要約
-
/etc/docker/daemon.json で
bip
に IP アドレス範囲を指定しても、docker0 以外の追加ブリッジには作用しない。 -
docker-compose などでブリッジが追加されると
172.17.0.1/16
が割り当てられてしまい、実存するサブネットから通信不能になる。 -
bip
の代わりに、default-address-pools
に割り当て可能な IP アドレス範囲を指定する。
発生した問題
発生条件
- docker マシンが接続されている LAN 内に 172.17.0.0/16 などのクラスB(172.16.0.0/12)に含まれるサブネットが実存する場合
システム構成
項目 | 説明 |
---|---|
OS | Debian 9.9 |
Docker | docker-ce 18.09.6 |
docker-compose | docker-compose 1.22 |
dockerマシンの接続サブネット | 172.16.0.0/16 |
クライアントの接続サブネット | 172.17.0.0/16, 172.18.0.0/16, ... |
問題現象
- docker 既定のブリッジ
docker0
の IP アドレスが実存するサブネットと競合しないように、/etc/docker/deamon.json にbip
を指定して、標準の172.17.0.1/16
から192.168.0.1/24
に変更してある。 - 先日まで 172.17.0.0/16 に接続するクライアントからも docker 上のアプリを利用できていた。
- docker-compose でアプリ追加を試していたところ、172.17.0.0/16 に接続するクライアントから docker 上のアプリが利用できなくなった。
- 172.17.0.0/16 からの ping や traceroute もエラーとなり、docker マシンへ通信できない状態に陥ってしまった。
- 172.18.0.0/16 に接続するクライアントからは通信できているが、時折 docker マシンへの ssh 接続が切断されることがあった。
落とし穴
-
公式ドキュメントに記載されている次の方法は、Docker 標準の既定のブリッジ
docker0
の IPアドレス範囲にのみ作用する。- Configure the default bridge network - docker docs(latest)
- Customize the docker0 bridge - docker docs(v17.09)
/etc/docker/daemon.json { "bip":"192.168.0.1/24" }
-
docker-compose や docker network create コマンドにより
docker0
以外に新たなブリッジが追加されると、172.17.0.1/16 が割り当てられてしまう。docker-compose.yml networks: backend_bridge: driver: ... ...
-
そうなると、実存する 172.17.0.0/16 サブネットと競合するため、 172.17.0.0/16 に接続するクライアントからの通信が誤ってルーティングされてしまい、通信不能に陥る。
-
docker-compose.yml に
networks:
が記述されていなくても、複数コンテナが定義されていれば、コンテナ間の通信用に新たな default ブリッジが追加される。 -
networks:
に定義するブリッジごとに IP アドレス範囲を指定することはできるが、別の docker-compose 対象と競合しないように管理するのは面倒で、ミスも誘発しやすい。
対応策
-
参考になった記事
Changing default subnet for docker custom networks - stackoverflow.com
Configuring Docker to not use the 172.17.0.0 range - serverfault.com
-
/etc/docker/daemon.json の記述例
-
default-address-pools
に docker 内のブリッジに割り当て可能な IP アドレス範囲と各ブリッジのサブネットマスク相当の値を指定する。 -
bip
を省略した場合、このdefault-address-pools
の中から IP アドレスが割り振られる。
{ "default-address-pools":[ { "base":"192.168.0.0/16", "size":24 } ] }
-
動作確認
対策前
-
/etc/docker/daemon.json
{ "bip":"192.168.0.1/16" }
-
動作結果
user@host:~$ docker-compose up -d user@host:~$ ip -4 a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 inet 172.16.2.194/24 brd 172.16.2.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever 6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default inet 192.168.0.1/16 brd 192.168.255.255 scope global docker0 valid_lft forever preferred_lft forever 17: br-b7e055bbfd68: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default inet 172.17.0.1/16 brd 172.17.255.255 scope global br-b7e055bbfd68 valid_lft forever preferred_lft forever
既定のブリッジ:
docker0
には192.168.0.1/16
が割り当てられている。しかし、その下のブリッジ:br-b7e055bbfd68
には172.17.0.1/16
が割り当てられてしまっている。docker-compose up
やdocker network create
のコマンドで新たにブリッジが追加されるたびに、その次の IP アドレス範囲(172.18.0.1/16
)が割り当てられる。
もう一つの落とし穴
-
docker-compose down; docker-compose up -d
を繰り返していると、ブリッジに割り当てられる IP アドレス範囲が実存するサブネットと競合しなくなり、問題現象が発生しなくなるため、この問題が顕在化しない恐れがある。 -
その後 docker マシンを再起動しても、既存ブリッジでは IP アドレス範囲が維持されるため問題なく稼働する。だが、その後に
docker-compose down; docker-compose up -d
などを実行して新たにブリッジが追加されると、172.17.0.1/16
が再び割り当てられて問題が顕在化する。
対策後
-
/etc/docker/daemon.json
{ "default-address-pools":[ { "base":"192.168.0.0/16", "size":24 } ] }
-
動作結果
user@host:~$ sudo service docker restart user@host:~$ docker-compose down; docker-compose up -d user@host:~$ ip -4 a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 inet 172.16.2.194/24 brd 172.16.2.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever 102: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default inet 192.168.0.1/24 brd 192.168.0.255 scope global docker0 valid_lft forever preferred_lft forever 103: br-45f6e0728ffd: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default inet 192.168.1.1/24 brd 192.168.1.255 scope global br-45f6e0728ffd valid_lft forever preferred_lft forever
docker0
とその下のブリッジbr-45f6e0728ffd
に192.168.0.0/16
の IP アドレス範囲の中から2つのサブネットが割り当てられている。