記録:Dockerコンテナ間通信(bridge) 

## 概要

他に沢山記事はあるが、コンテナ間の通信を試してみた記録。通信の方法が確認できれば良いのでnetcatを使う。

書いてある内容としてはほぼ[公式リファレンス(日本語訳)](http://docs.docker.jp/engine/tutorials/networkingcontainers.html)と同じ。

## コンテナ同士での通信（独自ネットワークの生成による場合）

コンテナ同士の通信は、レガシーなやり方として`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"を見れば生成した２つのコンテナの所属を確認できる。割り当てられたIPアドレスもここで確認しておく。

#### 3.通信する

netcatで通信してみる。

サーバー側は待ち受ける

```:コンテナ内での操作
test-server$ nc -lp 8080
```

クライアント側から送る

```:コンテナ内での操作
test-client$ nc 172.19.0.2 8080
hello
```

サーバー側で確認

```:コンテナ内での操作
test-server$ nc -lp 8080
hello
```

通信できた。ネットワークを作ってコンテナをそこに参加させればよいだけなので直感的でわかりやすい。公式リファレンスにもあるが`bridge`ネットワークは単一ホスト内で小さなネットワークを生成するのにはとても便利。