Docker network tutorial (bridge編)
Docker公式ドキュメントのbridge network tutorialをやってみた.
docs.docker.com
環境
Docker 18.09.1 on Ubuntu 18.04 (Oracle VirtualBox VM on macOS)
インストール方法はこちら↓
koimedenshi.hatenablog.com
- default bridge network
デフォルトブリッジはその名の通りデフォルトで用意されているネットワーク.
ネットワークを指定せずにコンテナを立ち上げると, ここに接続される.
ここでは2台のalpineコンテナをデフォルトブリッジに接続する.
初期状態の確認
$ docker network ls NETWORK ID NAME DRIVER SCOPE f0e09069add5 bridge bridge local 6dc567989d6f host host local dd596238709d none null local
2台のalpineコンテナの立ち上げ
$ docker run -dit --name alpine1 alpine ash $ docker run -dit --name alpine2 alpine ash
起動したコンテナの確認
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4081fada5d19 alpine "ash" 2 minutes ago Up 2 minutes alpine2 f9926cee8b76 alpine "ash" 2 minutes ago Up 2 minutes alpine1
ブリッジネットワークの接続状況をinspectで確認
$ docker network inspect bridge [ { "Name": "bridge", "Id": "f0e09069add5f694454f4b91aa92b249834c51f990436233d3d1302cd14f1bcc", "Created": "2019-01-22T09:55:52.056584987+09:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "4081fada5d19e08d10b7a903261c12f66d42d962b639851256525babc933c7f7": { "Name": "alpine2", "EndpointID": "f94f5c25a244f5f921e066f00950cc9926675d131c84cfdbfec86319e398ce78", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "f9926cee8b761f44da6f8646132c6e6d2a1b4ece6c7d46e49b8f6e98d577efee": { "Name": "alpine1", "EndpointID": "784c9240218a496ce26d6301354ec0051fbd5f9ef657ded18736e079bf89ed6f", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
alpine1コンテナ, alpine2コンテナはbridgeネットワークに接続され, デフォルトゲートウェイ172.17.0.1/16を介してDocker hostと通信する.
実際にコンテナの中から確認する.
attachコマンドでalpine1に接続する.
$ docker attach alpine1 / #
ipコマンドでインターフェースの確認
/ # ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
loopbackとeth0(172.17.0.2/16)が立ち上がっている.
外向けにpingを打ってみる
/ # ping -c 2 google.com PING google.com (216.58.197.142): 56 data bytes 64 bytes from 216.58.197.142: seq=0 ttl=61 time=9.415 ms 64 bytes from 216.58.197.142: seq=1 ttl=61 time=10.116 ms --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.415/9.765/10.116 ms
/ # ping -c 2 172.17.0.3 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.117 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.099 ms --- 172.17.0.3 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.099/0.108/0.117 ms
'alpine2'にpingを打つと失敗する
/ # ping -c 2 'alpine2' ping: bad address 'alpine2'
デフォルトブリッジではコンテナ名指定で疎通しないことがわかる.
alpine1のシェルを抜けてから(CTRL+p + qの順に押す),使用したコンテナを削除する
$ docker container stop alpine1 alpine2 $ docker container rm alpine1 alpine2
デフォルトブリッジのチュートリアル終わり.
- user-defined bridge networks
次にユーザ定義ネットワークのチュートリアルを行う.
まずalpine-netという名前のネットワークを作成
$ docker network create --driver bridge alpine-net 3fe4ed300746ac93ff0eb283f239d3482aeedc88a9aa0e2eb1354a6ca79527ac
ネットワークが追加されたことを確認
$ docker network ls NETWORK ID NAME DRIVER SCOPE 3fe4ed300746 alpine-net bridge local b005254ef24e bridge bridge local 6dc567989d6f host host local dd596238709d none null local
inspectコマンドでalpine-netの接続状況を確認. この段階では何もつながっていない
$ docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "3fe4ed300746ac93ff0eb283f239d3482aeedc88a9aa0e2eb1354a6ca79527ac", "Created": "2019-01-24T11:04:19.021413436+09:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
ネットワークアドレスは172.19.0.0/16となっている.
自動生成されるアドレス帯は環境によって異なる.
以下のコマンドで4台のコンテナを起動する.
$ docker run -dit --name alpine1 --network alpine-net alpine ash 26673686e6ff88c401c6e5b9dd007d1519ac603f86d1251195392a846f398ac5 $ docker run -dit --name alpine2 --network alpine-net alpine ash 6d36c4792f2b5c16b4a381a930d51b7456ab216efcc7af4363f9204c3a27a16a $ docker run -dit --name alpine3 alpine ash 7747f25eb4e7729b83741be135f9fdc13c84695519abd77544f1f01fbe400d17 $ docker run -dit --name alpine4 --network alpine-net alpine ash f39f29ac4f23bd0bb41bf39e80961d542a23f3cb79f91b93bbc00bee690a2e1b
$ docker network connect bridge alpine4 $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f39f29ac4f23 alpine "ash" 31 seconds ago Up 29 seconds alpine4 7747f25eb4e7 alpine "ash" 49 seconds ago Up 48 seconds alpine3 6d36c4792f2b alpine "ash" About a minute ago Up About a minute alpine2 26673686e6ff alpine "ash" About a minute ago Up About a minute alpine1
ざっくり言うと以下のようなネットワーク構成になっている
inspectコマンドでalpine-netを確認すると,コンテナが3台追加されている
$ docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "3fe4ed300746ac93ff0eb283f239d3482aeedc88a9aa0e2eb1354a6ca79527ac", "Created": "2019-01-24T11:04:19.021413436+09:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "26673686e6ff88c401c6e5b9dd007d1519ac603f86d1251195392a846f398ac5": { "Name": "alpine1", "EndpointID": "10d86d5b8ac9a132fa018c1ef2af71fa605ebcc48db24c1176628f36fc8cee08", "MacAddress": "02:42:ac:13:00:02", "IPv4Address": "172.19.0.2/16", "IPv6Address": "" }, "6d36c4792f2b5c16b4a381a930d51b7456ab216efcc7af4363f9204c3a27a16a": { "Name": "alpine2", "EndpointID": "ceb49779dff5690117bc9ab18995bf443a8f77d2c956a2152179561676ca0a3c", "MacAddress": "02:42:ac:13:00:03", "IPv4Address": "172.19.0.3/16", "IPv6Address": "" }, "f39f29ac4f23bd0bb41bf39e80961d542a23f3cb79f91b93bbc00bee690a2e1b": { "Name": "alpine4", "EndpointID": "49f46643172030e0de68dd093aca27a45d6c8ddf606cdc8a7c1eee8228b8f360", "MacAddress": "02:42:ac:13:00:04", "IPv4Address": "172.19.0.4/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
alpine1の中からpingを打ってみると,今度はコンテナ名でも通じることがわかる.
$ docker container attach alpine1 / # ping -c 2 alpine2 --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.095/0.097/0.099 ms / # ping -c 2 alpine4 PING alpine4 (172.19.0.4): 56 data bytes 64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.255 ms 64 bytes from 172.19.0.4: seq=1 ttl=64 time=0.156 ms --- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.156/0.205/0.255 ms / # ping -c 2 alpine1 PING alpine1 (172.19.0.2): 56 data bytes 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.073 ms 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.122 ms --- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.073/0.097/0.122 ms
この機能はautomatic service discoveryという.
一方alpine3はネットワークが異なるため,名前解決できないし,IPアドレスでも到達できない.
/ # ping -c 2 alpine3 ping: bad address 'alpine3' / # ping -c 2 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes --- 172.17.0.2 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss
CTRL+p+qでalpine1を抜けて,今度はalpine4からpingを打ってみる.
$ docker container attach alpine4 / # ping -c 2 alpine1 PING alpine1 (172.19.0.2): 56 data bytes 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.067 ms 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.086 ms --- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.067/0.076/0.086 ms / # ping -c 2 alpine2 PING alpine2 (172.19.0.3): 56 data bytes 64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.090 ms 64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.097 ms --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.090/0.093/0.097 ms / # ping -c 2 alpine3 ping: bad address 'alpine3' / # ping -c 2 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.115 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.155 ms --- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.115/0.135/0.155 ms / # ping -c 2 alpine4 PING alpine4 (172.19.0.4): 56 data bytes 64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.035 ms 64 bytes from 172.19.0.4: seq=1 ttl=64 time=0.105 ms --- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.035/0.070/0.105 ms
デフォルトブリッジとユーザ定義ブリッジの両方に接続しているので,すべてのコンテナに到達できる.
ただしalpine3はデフォルトブリッジのため,名前解決はできない.
ブリッジネットワークに接続しているので,全てのコンテナがグローバルアドレスへ到達可能.
/ # ping -c 2 google.com PING google.com (172.217.25.238): 56 data bytes 64 bytes from 172.217.25.238: seq=0 ttl=61 time=10.855 ms 64 bytes from 172.217.25.238: seq=1 ttl=61 time=9.578 ms --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.578/10.216/10.855 ms
終わったら作成したコンテナとネットワークを削除
$ docker container stop alpine1 alpine2 alpine3 alpine4 $ docker container rm alpine1 alpine2 alpine3 alpine4 $ docker network rm alpine-net
まとめ
ブリッジネットワークのチュートリアルを実施した.
商用環境ではdefault bridge networkは非推奨とのこと.
逆に開発環境でコンテナ1台お手軽に試すとかならdefaultでも十分そう.
以上