当サイトは、アフィリエイト広告を利用しています

【Docker】Docker-Composeの内部ネットワークでコンテナに固定IPを割り振る

作成日:2023月10月04日
更新日:2023年11月02日

Docker Composeはdocker-compose.yamlファイルに記述した
同じプロジェクト内に存在するコンテナ間(サービス)で通信可能な内部ネットワーク
を作成する

DockerのDocker-Composeを使って内部ネットワークを作成し
コンテナに固定IPを割り振る方法をまとめる。

Docker-Composeを使って内部ネットワークを作成した場合
特にIPを設定しなければ
Dockerは自動的にIPアドレスを割り当てるようになっているため
コンテナごとに固定IPを設定する場合は、Docker-Compose.ymlの中で
IPを設定をする必要がある。

Dockerについては下記の書籍がかなり参考になります。

コンテナに固定IPを割り当てる

コンテナに固定IPを割り当てるには、Docker-Compose.ymlで
networksの設定をする

下記のような構成で試してみる

tree
.
|-- authtest
| `-- docker-compose.yml

networksの設定方法

DockerComposeを使って2つのコンテナ(test1とtest2)を作成し、
それらを同じネットワーク(test_network)に接続する設定を書いてみる

Docker-Compose.yml
version: "3"
# コンテナ
services:
# コンテナ1
test1:
container_name: authtest1
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# 固定IPを割り振る
networks:
test_network:
ipv4_address: 172.25.1.2
# コンテナ2
test2:
container_name: authtest2
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# 固定IPを割り振る
networks:
test_network:
ipv4_address: 172.25.1.3
# ネットワーク設定
networks:
# ネットワーク名(ファイル内での使う名称)
test_network:
# ネットワークドライバーを指定
driver: bridge
#ネットワークの名前を指定(dockerネットワークとしての名称)
name: test_network_name
# IPアドレス管理(IPAM)の設定
ipam:
# IPAMドライバーを指定
driver: default
# ネットワークのサブネット設定
config:
- subnet: 172.25.1.0/24

test1とtest2のnetworks部分

コンテナが接続するネットワークを指定する
test1とtest2の固有のIPアドレスを割り振る。

この時、最下部のnetworksで設定している ネットワークのサブネット(172.25.1.0/24)の中から割り振る
ようにする。

最下部のtest_network:

このDocker-composeファイル内でのこのnetworkの名称。
コンテナのnetwork設定などで使用する

driver: bridge

ネットワークドライバの種類を指定する
bridgeはDockerのデフォルトのネットワークドライバで
コンテナ間の通信を可能にする。

省略した場合はデフォルトで「driver: bridge」
になる
※「driver: bridge」にしたいなら書かなくてもいい

name: test_network_name

ネットワークの名前を指定する。
ここで指定してものが「docker network ls」で表示される

GitBash
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
1cde57aff652 bridge bridge local
2b2180493fa6 host host local
9acc6567cd86 none null local
a0fb193095eb test_network_name bridge local

ちなみにこれも省略ができ、
省略して書かなかった場合は

GitBash
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ea3419911196 authtest_test_network bridge local
1cde57aff652 bridge bridge local
2b2180493fa6 host host local
9acc6567cd86 none null local

「プロジェクト名_ネットワーク名」となるようだ。

ipam:

配下にIPアドレス管理(IPAM)の設定をする

driver: default

IPアドレス管理(IPAM)ドライバの種類を指定する
defaultはDockerのデフォルトのIPAMドライバで、特に指定しない場合、
Dockerは自動的にこのドライバを使用する

config:

ネットワークのサブネット設定を記述する

docker composeを実行してIPアドレスを確認する

docker composeでコンテナを起動する

GitBash
$ docker compose up -d
[+] Running 3/3
✔ Network authtest_test_network Created 0.7s
✔ Container authtest2 Started 1.8s
✔ Container authtest1 Started 1.8s

起動確認をする

GitBash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fc85e2e0b66 rockylinux/rockylinux "/sbin/init" 24 minutes ago Up 24 minutes authtest1
3c1be86e6df4 rockylinux/rockylinux "/sbin/init" 24 minutes ago Up 24 minutes authtest2

起動できている

IPアドレスを確認する

GitBash
$ docker inspect authtest1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.2",
$ docker inspect authtest2 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.3",

想定通り、IPアドレスが設定されている。

DockerComposeでコンテナのIPアドレスを指定しない場合

指定しない場合はコンテナが所属するネットワークの利用可能な
IPアドレス範囲から自動せ設定されるので
「docker inspect コンテナ名」のコマンド調べればわかる

IPアドレスを固定にしないが同じネットワークに入れたい場合

IPアドレスは固定でなくていい場合はネットワークだけ指定すればいい

具体的には下記のように設定する

docker-compose.yml
version: "3"
# コンテナ
services:
# コンテナ1
test1:
container_name: authtest1
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# ネットワークのみ指定
networks:
- test_network
# ipv4_address: 172.25.1.2
# コンテナ2
test2:
container_name: authtest2
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# ネットワークのみ指定
networks:
- test_network
# ipv4_address: 172.25.1.3
# ネットワーク設定
networks:
# ネットワーク名(ファイル内での使う名称)
test_network:
# ネットワークドライバーを指定
driver: bridge
#ネットワークの名前を指定(dockerネットワークとしての名称)
# name: test_network_name
# IPアドレス管理(IPAM)の設定
ipam:
# IPAMドライバーを指定
driver: default
# ネットワークのサブネット設定
config:
- subnet: 172.25.1.0/24

固定IP設定部分を削除し、ネットワークだけ設定するようにする

確認すると

GitBash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69a4ae51b9f4 rockylinux/rockylinux "/sbin/init" 2 minutes ago Up 2 minutes authtest1
c74c9731b2a6 rockylinux/rockylinux "/sbin/init" 2 minutes ago Up 2 minutes authtest2
$ docker inspect authtest1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.2",
$ docker inspect authtest2 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.3",

同じ172.25.1.0/24サブネットのネットワーク内のIPが設定されている

注意点

内部ネットワーク設定はDockerの自動IP割り振り機能との
兼ね合いでIP設定がうまくいなかい時がある。

注意するパターンとして下記がある

  • ネットワーク設定の有無を混在させた場合
  • ネットワーク設定のIP固定とIP固定なしを混在させた場合

どちらもあまりすることはないと思うが
一応、まとめておく。

ネットワーク設定の有無を混在させた場合

ネットワークを指定しているserviceとしていないserviceを
混在させた場合、ネットワークがわかれてしまう可能性がある

例えば

docker-compose.yml
version: "3"
# コンテナ
services:
# コンテナ1
test1:
container_name: authtest1
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# 固定IPを割り振る
networks:
test_network:
ipv4_address: 172.25.1.2
# コンテナ2
test2:
container_name: authtest2
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# # 固定IPを割り振る
# networks:
# test_network:
# ipv4_address: 172.25.1.3
# ネットワーク設定
networks:
# ネットワーク名(ファイル内での使う名称)
test_network:
# ネットワークドライバーを指定
driver: bridge
#ネットワークの名前を指定(dockerネットワークとしての名称)
# name: test_network_name
# IPアドレス管理(IPAM)の設定
ipam:
# IPAMドライバーを指定
driver: default
# ネットワークのサブネット設定
config:
- subnet: 172.25.1.0/24

のようにauthtest2のネットワーク設定を書かなかった場合
どうなるかというと

GitBash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f42f1dc83e8 rockylinux/rockylinux "/sbin/init" 11 seconds ago Up 8 seconds authtest2
acf6937052b5 rockylinux/rockylinux "/sbin/init" 11 seconds ago Up 8 seconds authtest1
$ docker inspect authtest1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.2",
$ docker inspect authtest2 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.19.0.2",

サブネット「172.25.1.0/24」で内部ネットワーク作っているので
IPアドレスが「172.19.0.2」となるauthtest2は別ネットワークと
となってしまっている

ネットワーク設定のIP固定とIP固定なしを混在させた場合

先に言っておくと、ネットワーク設定で固定IPにするなら
「全部設定する」しないなら、「全部設定しない」
のどちらかに寄せた方がいいと思う

IP固定とIP固定なしを混在

test1のIPは固定し、test2はネットワークのみ設定し
IPは固定しない

GitBash
version: "3"
# コンテナ
services:
# コンテナ1
test1:
container_name: authtest1
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# ネットワークのIP固定
networks:
test_network:
ipv4_address: 172.25.1.2
# コンテナ2
test2:
container_name: authtest2
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# ネットワークのみ指定
networks:
- test_network
# ipv4_address: 172.25.1.3
# ネットワーク設定
networks:
# ネットワーク名(ファイル内での使う名称)
test_network:
# ネットワークドライバーを指定
driver: bridge
#ネットワークの名前を指定(dockerネットワークとしての名称)
# name: test_network_name
# IPアドレス管理(IPAM)の設定
ipam:
# IPAMドライバーを指定
driver: default
# ネットワークのサブネット設定
config:
- subnet: 172.25.1.0/24

実行すると

GitBash
$ docker compose up -d
[+] Running 2/3
✔ Network authtest_test_network Created 0.7s
✔ Container authtest2 Started 1.0s
- Container authtest1 Starting 1.0s
Error response from daemon: Address already in use

エラーになり
実行順を見ると、authtest2の方が先に作れているのがわかる

割り当てを見てみると

GitBash
$ docker inspect authtest2 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.2",
$ docker inspect authtest1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "",

となっており、test2にtest1で固定にしている「172.25.1.2」
が割り当てられている

なぜかというと Dockerはまず最初にDockerが利用可能なIPアドレスを割り当てるので
「172.25.1.2」が空いていた場合、固定IPを指定していないtest2に「172.25.1.2」が
先に割り当てられる

その後、test1のIPアドレスに固定で指定している「172.25.1.2」を
割り当てようとしてエラーになる

対応方法

test1で固定で割り振るIPを後の方の番号にすれば一応は解決する

docker-compose.yml
version: "3"
# コンテナ
services:
# コンテナ1
test1:
container_name: authtest1
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# ネットワークのIP固定
networks:
test_network:
ipv4_address: 172.25.1.99
# コンテナ2
test2:
container_name: authtest2
image: rockylinux/rockylinux
restart: always
tty: true
command: /sbin/init
# ネットワークのみ指定
networks:
- test_network
# ipv4_address: 172.25.1.3
# ネットワーク設定
networks:
# ネットワーク名(ファイル内での使う名称)
test_network:
# ネットワークドライバーを指定
driver: bridge
#ネットワークの名前を指定(dockerネットワークとしての名称)
# name: test_network_name
# IPアドレス管理(IPAM)の設定
ipam:
# IPAMドライバーを指定
driver: default
# ネットワークのサブネット設定
config:
- subnet: 172.25.1.0/24

test2にDockerの自動IP割り当てで割り当てられるIPが
test1で固定で指定するIPとかぶらないように設定することで
解決はする

実行すると

GitBash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e64dd7fe364c rockylinux/rockylinux "/sbin/init" 9 seconds ago Up 7 seconds authtest2
a58ef1b607b3 rockylinux/rockylinux "/sbin/init" 9 seconds ago Up 7 seconds authtest1
$ docker inspect authtest1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.99",
$ docker inspect authtest2 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.25.1.2",

IP割り振りがちゃんとできている

まとめ

割とDockerコンテナのIPを確認することがあり
いちいちコマンド叩くのが面倒なので、固定で割り振るようにした

また内部ネットワーク設定のパターンも色々試してみて
Dockerのネットワーク設定に関する知識が増えた

DockerComposeはversionによってちょっと書き方が違ったり
するので注意したい。

参考

関連記事

新着記事

top