Work with network commandsの翻訳です。
(disconnect / remove はさほどではなかったので省略しています)
Work with network commands
本稿は Docker とやり取りをして network や container を操作する network サブコマンドの例を示します。
コマンドは Docker Engine CLI で利用可能です。
docker network create
docker network connect
docker network ls
docker network rm
docker network disconnect
docker network inspect
やりたいことが明確で無いのであれば、本セクションの例を試す前に Understanding Docker network を読むのがおすすめです。
bridge
ネットワークに関しての例で、すぐに試すことができます。
overlay
ネットワークの実験をしてみたいのであれば、 Getting started with multi-host networks を読んでみてください。
Create networks
Docker Engine は Engine がインストールされた時に自動的に1つ bridge
ネットワークを作成します。
このネットワークは 過去 docker0
として利用してきたネットワークに対応します。
このネットワークに加えて、あなた自身の bridge
または overlay
ネットワークを作成位することができます。
bridge
ネットワークは、稼働している Docker Engine のインスタンスの1つに1つ存在しています。
overlay
ネットワークは複数のホストに渡り、それぞれの Engine で稼働します。
もし、 docker network create
を実行し、ネットワーク名を与えれば、あなたのための bridge network を作成することができます。
$ docker network create simple-network
de792b8258895cf5dc3b43835e9d61a9803500b991654dacb1f4f0546b1c88f8
$ docker network inspect simple-network
[
{
"Name": "simple-network",
"Id": "de792b8258895cf5dc3b43835e9d61a9803500b991654dacb1f4f0546b1c88f8",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{}
]
},
"Containers": {},
"Options": {}
}
]
bridge
ネットワークではなく、 overlay
ネットワークは作成前にいくつかの事前条件が必要になります。
- key-value ストアにアクセスできること. Engine は Consul 、 Etcd および ZooKeeper (Distributed store) をサポートしています
- ホストのクラスタが key-value ストアに接続されていること
- 適切に設定された
daemon
Engine が swarm のホストに存在していること
docker daemon
のオプションは overlay
ネットワークをサポートしています。
--cluster-store
--cluster-store-opt
--cluster-advertise
特に要件がなければ、 Docker Swarm をインストールして、クラスタを管理するのがおすすめです。
Swarm は洗練されたディスカバリとサーバ管理を提供しています。
ネットワークを作成するときに、 Engine はオーバラップされていない subnetwork をデフォルトでネットワークに対して作成します。
このデフォルトを上書きし、--subnet
を利用することで直接にサブネットワー指定することができます。
bridge
ネットワークの場合は、たった一つのサブネットだけが作成可能です。
overlay
ネットワークは複数の subnet をサポートしています。
--subnetwork
オプションに加え、 --gateway
、 --ip-range
、 --aux-address
オプションを指定することができます。
$ docker network create -d overlay
--subnet=192.168.0.0/16 --subnet=192.170.0.0/16
--gateway=192.168.0.100 --gateway=192.170.0.100
--ip-range=192.168.1.0/24
--aux-address a=192.168.1.5 --aux-address b=192.168.1.6
--aux-address a=192.170.1.5 --aux-address b=192.170.1.6
my-multihost-network
サブネットワークがオーバラップされないことを確認してください。その場合は、ネットワークは作成に失敗し、 Engine はエラーを返します。
Connect containers
コンテナを動的に1つまたはそれ以上のネットワークに属させることができます。これらのネットワークは同一でも異なっているネットワークドライバでも構いません。
一旦属させてしまえば、コンテナはその他のコンテナ IP アドレスまたは名前を利用してコミュニケーションすることができるようになります。
overlay
ネットワークまたはマルチホストをサポートするカスタムプラグインであったとしても、同一のマルチホストネットワークに属しているコンテナはたとえ異なるホストで立ち上げられたとしても、コミュニケーションすることができます。
2つのコンテナを作ってみます。
$ docker run -itd --name=container1 busybox
18c062ef45ac0c026ee48a83afa39d25635ee5f02b58de4abc8f467bcaa28731
$ docker run -itd --name=container2 busybox
498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152
それから、独立した bridge
ネットワークをテスト用に作ってみます
$ docker network create -d bridge isolated_nw
f836c8deb6282ee614eade9d2f42d590e603d0b1efa0d99bd88b88c503e6ba7a
container2
をこのネットワークに所属させ、その後 inspect
でこのネットワークのコネクションを確認します。
$ docker network connect isolated_nw container2
$ docker network inspect isolated_nw
[[
{
"Name": "isolated_nw",
"Id": "f836c8deb6282ee614eade9d2f42d590e603d0b1efa0d99bd88b88c503e6ba7a",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{}
]
},
"Containers": {
"498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152": {
"EndpointID": "0e24479cfaafb029104999b4e120858a07b19b1b6d956ae56811033e45d68ad9",
"MacAddress": "02:42:ac:15:00:02",
"IPv4Address": "172.21.0.2/16",
"IPv6Address": ""
}
},
"Options": {}
}
]
Engine が自動的に IP アドレスが container2
に振っていることが確認できるはずです。
もし、ネットワーク作成時に --subnetwork
を指定しているならば、ネットワークがそのアドレスを使っているはずです。
さて、3つ目のコンテナを立ち上げ、ネットワークに属させてみましょう。 docker run
の時に --net
コマンドを使って、起動時に。
$ docker run --net=isolated_nw -itd --name=container3 busybox
c282ca437ee7e926a7303a64fc04109740208d2c20e442366139322211a6481c
container3
のネットワークリソースを(inspect
で)見てみましょう
$ docker inspect --format='{{json .NetworkSettings.Networks}}' container3
{"isolated_nw":{"EndpointID":"e5d077f9712a69c6929fdd890df5e7c1c649771a50df5b422f7e68f0ae61e847","Gateway":"172.21.0.1","IPAddress":"172.21.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:15:00:03"}}
このコマンドを container2
に対して繰り返してみてください。 Python がインストールされているのであれば、整形してみることができます(※訳注: jq使えばいいです)
$ docker inspect --format='{{json .NetworkSettings.Networks}}' container2 | python -m json.tool
{
"bridge": {
"EndpointID": "281b5ead415cf48a6a84fd1a6504342c76e9091fe09b4fdbcc4a01c30b0d3c5b",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03"
},
"isolated_nw": {
"EndpointID": "0e24479cfaafb029104999b4e120858a07b19b1b6d956ae56811033e45d68ad9",
"Gateway": "172.21.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.21.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:15:00:02"
}
}
container2
が2つのネットワークに属していることが見て取れるはずです。起動した時にデフォルトで所属していた bridge
ネットワークとその後、結びつけた isolated_nw
です。
container3
の場合には、docker run
を通して結びつけた isolated_nw
だけで、 bridge
には結び付けられていません。
docker attach
コマンドを利用して、稼働中の container2
に接続し、ネットワークスタックを調べてみましょう。
$ docker attach container2
コンテナのネットワークスタックを見てみると、 Ethernet interface が2つあるはずです。1つはデフォルトのbridgeネッワーク、もう一つは isolated_nw
ネットワークです。
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02
inet addr:172.21.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe15:2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/etc/hosts
も表示してみます。
/ # cat /etc/hosts
172.17.0.3 498eaaaf328e
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.21.0.3 container3
172.21.0.3 container3.isolated_nw
ユーザが定義した isolated_nw
上で、 Docker network の機能により /etc/hosts
が適切に名前解決ができるように更新されています。
container2
の中から、 ping container3
を名前で実行することが可能です。
/ # ping -w 4 container3
PING container3 (172.21.0.3): 56 data bytes
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.070 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.080 ms
64 bytes from 172.21.0.3: seq=2 ttl=64 time=0.080 ms
64 bytes from 172.21.0.3: seq=3 ttl=64 time=0.097 ms
--- container3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.070/0.081/0.097 ms
デフォルトの bridge ネットワークの場合はこうではありません。 container2
と container1
はデフォルトの bridge ネットワークに属しています。 Docker は自動的にサービスディスカバリをこのネットワークに対しては行えません。
このため、 container1
への ping は /etc/hosts
ファイルをベースにしてくれると期待して名前で行うと失敗します。
/ # ping -w 4 container1
ping: bad address 'container1'
A ping using the container1 IP address does succeed though:
/ # ping -w 4 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.095 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.072 ms
64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.101 ms
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.072/0.085/0.101 ms
もし、 container1
を container2
に結びつけたければ、 docker run --link
コマンドで行い、2つのコンテナが IP と同じように名前で疎通できるようにする必要があります。
CTRL-p CTRL-q
を利用して、稼働させたまま container2
から切り離します。
この例では、 container2
が両方のネットワークに結び付けられており、 container1
および container3
とコミュニケートしていました。
しかし、 container3
と container1
は同じネットワークには属しておらず、それゆえコミュニケーションができません。
では、 container3
にアタッチし、 container1
に IP アドレスで ping してみましょう。
$ docker attach container3
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
^C
--- 172.17.0.2 ping statistics ---
10 packets transmitted, 0 packets received, 100% packet loss
コンテナをネットワークに所属させるために、コンテナは稼働していなければなりません。
コンテナを止め、コンテナが所属しているネットワークを調べると、コンテナを発見できないでしょう。
docker network inspect
コマンドは起動しているコンテナだけを表示するからです。