概要
他に沢山記事はあるが、コンテナ間の通信を試してみた記録。通信の方法が確認できれば良いのでnetcatを使う。
書いてある内容としてはほぼ公式リファレンス(日本語訳)と同じ。
コンテナ同士での通信(独自ネットワークの生成による場合)
コンテナ同士の通信は、レガシーなやり方としてlink
を使うやり方があったようだが、今は非推奨となり、ネットワークを独自に作り、そこにコンテナを参加させることでネットワークに参加させたコンテナ間だけがお互いに通信し合える状態になるようだ。
なお、link
を使ったコンテナ同士の通信については、もう非推奨のようなので今回は試してない。
0.デフォルトネットワークの確認(はじめに)
DockerはDocker独自のネットワークを生成する。デフォルトで生成されるネットワークがbridge
ドライバを使った bridge ネットワーク。
で、新規ネットワークでの通信を試す前にこの bridge ネットワークをまずは確認してみる。
ネットワーク廻りにはnetwork
コマンドを利用する。ネットワークの一覧を表示するのはnetwork ls
で確認できる。
host$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
1df7cecfc3a4 bridge bridge local
65f55a9eacca host host local
2f1081153878 none null local
なにも触っていなければ上記の3つが設定される。デフォルトネットワークの bridge とホストが所属するネットワークの host とネットワーク所属なしを意味する none だ。特にオプションとして指定が無ければdocker run
で生成されるコンテナは bridge に所属する。
それぞれのネットワークの詳細を確認するには network inspect <NAME>
を使う。
host$ sudo docker network inspect bridge
[
{
"Name": "bridge",
"Id": "1337cecfc3a449722924b8d64f61ae3f6628950c45477f4a16d9b69fb4f871e9",
"Created": "2018-10-17T20:42:33.695849376+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"
}
<省略>
ゲートウェイアドレスなどを確認できる。
1.ネットワークの生成
新しいネットワークを作ってみる。
host$ sudo docker network create -d bridge test-network
確認してみる。
host$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
1337cecfc3a4 bridge bridge local
65f46a9eacca host host local
2f1080053878 none null local
55c4c69ba479 test-network bridge local
一番下に新しいネットワークが追加されたことが確認できた。
2.コンテナの生成
コンテナを普通に作ると bridge に所属してしまうので、新しく作ったネットワークに所属するよう指示を加えて生成する。これには--net=<NAME>
オプションを使う。
host$ sudo docker run -it --rm --net=test-network --name test_server 452a96d81c30 /bin/bash
サーバー側を生成したのでクライアント側も同様に生成する。
host$ sudo docker run -i -t --rm --net=test-network --name test_client 452a96d81c30 /bin/bash
サーバー、クライアント用のコンテナが test-network に所属したことを確認する。
host$ sudo docker network inspect test-network
[
{
"Name": "test-network",
"Id": "55c4c69ba47999934332697e7a68b341e8d810b6d913cc7f9d8d031b02257267",
"Created": "2018-10-23T08:19:33.836108811+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": {
"2b0de248f59159714911f298553782c4c698bd3a1bcaece425f9400e50dca519": {
"Name": "test_server",
"EndpointID": "551ffecd7fdddfb9dd855473c59a68d708621bf8c2ca3da59546578894d70212",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
},
"9f3f9026f3a14a061463a7fd700e171c24d33fc27b686df18464d4b0f6a25bfe": {
"Name": "test_client",
"EndpointID": "617cb38b6ed98faa6ecb8fef7bffe72edd8659c25120daf31c9999c15fdfc537",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
"Containers"を見れば生成した2つのコンテナの所属を確認できる。割り当てられたIPアドレスもここで確認しておく。
3.通信する
netcatで通信してみる。
サーバー側は待ち受ける
test-server$ nc -lp 8080
クライアント側から送る
test-client$ nc 172.19.0.2 8080
hello
サーバー側で確認
test-server$ nc -lp 8080
hello
通信できた。ネットワークを作ってコンテナをそこに参加させればよいだけなので直感的でわかりやすい。公式リファレンスにもあるがbridge
ネットワークは単一ホスト内で小さなネットワークを生成するのにはとても便利。