Work with network commands
http://docs.docker.com/engine/userguide/networking/work-with-networks/
network コマンドの動作
このページでは、network サブコマンドの例を紹介します。コマンドは Docker ネットワークと、ネットワーク内のコンテナを相互に使えるようにします。コマンドは Docker エンジン CLI を使って利用できます。コマンドは次のようなものです。
docker network createdocker network connectdocker network lsdocker network rmdocker network disconnectdocker network inspect
必須ではありませんが、このセクションで例に取り組む前に Docker ネットワークの理解についてを読んでおくことは良い考えです。例では bridge ネットワークを扱いますので、すぐに試すことができます。それよりも overlay ネットワークについて知りたい場合は、こちらよりマルチ・ホスト・ネットワーク導入ガイドをお読みください。
ネットワークの作成
Docker エンジンをインストールすると、Docker エンジンは自動的に bridge ネットワークを作成します。このネットワークは docker0 ブリッジに対応するものであり、エンジンが伝統的に頼っているものです。このネットワークについて説明を付け加えるとすると、自分自身で bridge や overlay ネットワークを作成できます。
$ 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 ネットワークを使うこともできます。調整とは次のようなものです:
- キーバリュー・ストアに対するアクセス。エンジンがサポートするキーバリュー・ストアは、Consul、Etcd、Zookeeper(分散ストア)です。
- ホストのクラスタが、キーバリュー・ストアに接続する。
- Swarm の各ホスト上で動作するエンジン
daemonに、適切な設定を行う。
docker デーモン が overlaye ネットワークをサポートするオプションは、次の通りです:
--cluster-store--cluster-store-opt--cluster-advertise
これらを使う代わりに、Docker Swarm をインストールしてクラスタを管理するのも良い考えです。実装にあたって、Swarm は高度なディスカバリとサーバ管理を提供します。
ネットワークを作成するとき、デフォルトではエンジンはサブネットが重複しないネットワークを作成します。このデフォルト設定は --subnet オプションを直接指定することにより上書き可能です。bridge ネットワーク上では、単一のサブネットのみ作成可能です。overlay ネットワークは複数のサブネットをサポートします。
--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
サブネットが重複しないように気をつけてください。もし重複する場合、ネットワークの作成に失敗し、エンジンはエラーを返します。
コンテナへの接続 (attach)
コンテナに対して、動的に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": {}
}
]
エンジンが自動的に container2 に IP アドレスを割り当てていることがわかります。ネットワーク作成時に --subnetwork を指定すると、ネットワークは割り当てられたアドレスを使います。次は3つめのコンテナを起動します。docker run コマンドで --net オプションを使うことにより、どのネットワークに接続するか指定して起動します:
$ docker run --net=isolated_nw -itd --name=container3 busybox
c282ca437ee7e926a7303a64fc04109740208d2c20e442366139322211a6481c
それから、container3 が使用しているネットワーク・リソースを調べます。
$ 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 をインストールしていれば、次のように表示されます。
$ 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つのネットワークに属しているのが分かります。1つはコンテナを起動する時の、デフォルトで参加した bridge ネットワーク。もう1つは後から接続した isolated_nw です。
図:
container3 の場合は、docker run 実行時に isolated_nw に接続するように指定したので、コンテナは bridge に繋がりません。
docker attach コマンドを使って実行中の container2 に接続詞、ネットワーク・スタックを確認します:
$ docker attach container2
コンテナのネットワーク・スタックに2つのイーサネット・インターフェースが見えるでしょう。1つはデフォルトの bridge ネットワークで、もう1つは 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
isotated_nw はユーザによって定義されたものです。Docker ネットワーク機能は適切な名前解決ができるよう /etc/hosts を更新します。container2 の内部では、container3 に対して名前で ping できるでしょう。
/ # 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
デフォルトのブリッジ・ネットワークの場合は、このようになりません。container2 と container1 は、どちらもデフォルトのブリッジ・ネットワークに接続しています。Docker はこのブリッジ・ネットワークに対してディスカバリ・サービス(訳者注:ホスト名に応じて、自動で名前解決する機能)を提供しません。そのため、/etc/hosts ファイルに記述しない限り、container1 という名前で ping しても失敗します。
/ # ping -w 4 container1
ping: bad address 'container1'
container1 の IP アドレスを使う場合は、ping は成功します:
/ # 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 アドレス同様、名前でもやりとり可能になります。
container2 をデタッチして離れるには、CtRL-p CTRL-q を実行します。
この例 における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 コマンドは、コンテナ実行中のみ表示するものです。
コンテナの切断 (disconnect)
コンテナをネットワークから切断するのに docker network disconnect コマンドを使います。
$ docker network disconnect isolated_nw container2
docker inspect --format='{{json .NetworkSettings.Networks}}' container2 | python -m json.tool
{
"bridge": {
"EndpointID": "9e4575f7f61c0f9d69317b7a4b92eefc133347836dd83ef65deffa16b9985dc0",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03"
}
}
$ docker network inspect isolated_nw
[[
{
"Name": "isolated_nw",
"Id": "f836c8deb6282ee614eade9d2f42d590e603d0b1efa0d99bd88b88c503e6ba7a",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{}
]
},
"Containers": {
"c282ca437ee7e926a7303a64fc04109740208d2c20e442366139322211a6481c": {
"EndpointID": "e5d077f9712a69c6929fdd890df5e7c1c649771a50df5b422f7e68f0ae61e847",
"MacAddress": "02:42:ac:15:00:03",
"IPv4Address": "172.21.0.3/16",
"IPv6Address": ""
}
},
"Options": {}
}
]
コンテナをネットワークから切断すると、接続していたネットワーク上の他のコンテナとは通信できません。この例の container2 は、isolated_nw 上の container3 と通信できなくなっています。
$ docker attach container2
/ # 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)
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)
/ # ping container3
PING container3 (172.20.0.1): 56 data bytes
^C
--- container3 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
container2 は、まだブリッジ・ネットワークに対する完全な接続性を持っています。
/ # ping container1
PING container1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.119 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.174 ms
^C
--- container1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.119/0.146/0.174 ms
/ #
ネットワークの削除 (remove)
ネットワーク上のすべてのコンテナが停止または切断すると、ネットワークを削除(remove)できます。
$ docker network disconnect isolated_nw container3
docker network inspect isolated_nw
[
{
"Name": "isolated_nw",
"Id": "f836c8deb6282ee614eade9d2f42d590e603d0b1efa0d99bd88b88c503e6ba7a",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{}
]
},
"Containers": {},
"Options": {}
}
]
$ docker network rm isolated_nw
全てのネットワーク一覧から isolated_nw が削除されたのを確認します。
$ docker network ls
NETWORK ID NAME DRIVER
72314fa53006 host host
f7ab26d71dbd bridge bridge
0f32e83e61ac none null