Docker学習中につき！(ユーザ定義ネットワークでコンテナ間の通信)

#◎はじめに
・ECSを使うためにDockerの学習をしております。

1. [AWS ECSを使用する前にDockerを理解しなきゃ](http://qiita.com/mitzi2funk/items/14fa88d85498db28144a)
2. [Docker学習中につき！(コマンドの整理とイメージ構築など)](http://qiita.com/mitzi2funk/items/f5a2a5a69be495fdcd3c)


・今回は<b>Docker コンテナ・ネットワーク</b>について調べてみました。

##◯参考ドキュメント
1. [Docker コンテナ・ネットワークの理解](http://docs.docker.jp/engine/userguide/networking/dockernetworks.html)
2. [例で学ぶ >> コンテナのネットワーク](http://docs.docker.jp/engine/tutorials/networkingcontainers.html)

#■01. Docker コンテナ・ネットワーク

まずコンテナのイメージ図
![Container@2x.png](https://qiita-image-store.s3.amazonaws.com/0/50310/389ef7b4-d625-6a06-0b69-a6db3c4108b0.png)
※　[公式](https://docs.docker.com/)より拝借してきました。


そして、今回確認したことはコチラ↓
![Dockerユーザ定義ブリッジ・ネットワーク.png](https://qiita-image-store.s3.amazonaws.com/0/50310/67145074-069d-489f-d1ac-edb7b9288b01.png)

##01-1. デフォルト・ネットワークについて
■ ネットワーク・ドライバ
・Docker は ネットワーク・ドライバ を使うことで、コンテナの通信をサポートしている
・Docker Engine は、自動的に下記3つのデフォルト・ネットワークをインストールしている

```bash
[ec2-user@mitzi_dev02 ~]$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1916875b8e0e        bridge              bridge              local
9d80476b295c        host                host                local
f1b79f29f8a4        none                null                local
```

・コンテナ起動時指定しなければデフォルトで「bridge」ネットワークが選択される

##01-2. デフォルトネットワークでコンテナを起動

・この時コンテナ名に「webapp」という名称を付与しています。

```bash
[ec2-user@mitzi_dev02 ~]$ docker run -d -P --name webapp training/webapp python app.py
4687219e75dba87b1c297953c027a20d5a710fc759388b5ce31f054a717e9c46
```

###◯コンテナ名に関して
・作成時指定しないとコンテナ名が自動で振られる。
そこで上述のようにフラグを指定することでコンテナに任意の名前をつけることが出来る。

・コンテナ名を付けるメリット
　役割が分かる名前を付けることで、覚えやすくなる。また同一ネットワーク上の他コンテナから参照する際に名前解決のような挙動で通信が出来る。

・注意
　コンテナ名はユニークである必要がある。
同名が使いたい場合は下記のように古いコンテナを削除する必要あり。

```bash
$ docker stop webapp
$ docker rm webapp
```

###◯先ほど作成したコンテナの状態を確認

・デフォルトネットワーク(bridge)内に該当コンテナが起動していることを確認

```bash
[ec2-user@mitzi_dev02 ~]$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "1916875b8e0e5ab85d5e360a1ab32601f0744224bd76638ff527e890bdcc8013",
        "Created": "2017-06-18T23:12:52.761037899Z",
        "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,
        "Containers": {
            "4687219e75dba87b1c297953c027a20d5a710fc759388b5ce31f054a717e9c46": {
                "Name": "webapp",
                "EndpointID": "1def167abf8c1cc5e6a494528502809314649114ea0f0ca7153264c211008307",
                "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": {}
    }
]
```

##01-3. 任意のブリッジ・ネットワークを作成

・ `-d`フラグでドライバーを指定しない場合も「bridge」になるとのこと

```bash
[ec2-user@mitzi_dev02 ~]$ docker network create -d bridge my-bridge-network
daa4195aab0bd7da4f20371d15660529a016457aee8eaef936f028f62c18229f
```

・増えました

```bash
[ec2-user@mitzi_dev02 ~]$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1916875b8e0e        bridge              bridge              local
9d80476b295c        host                host                local
daa4195aab0b        my-bridge-network   bridge              local
f1b79f29f8a4        none                null                local
```

##01-4. 新しいネットワークにコンテナを起動

・データベース用として「db」という名称のコンテナを新ネットワークに起動

```bash
[ec2-user@mitzi_dev02 ~]$ docker run -d --net=my-bridge-network --name db training/postgres
Unable to find image 'training/postgres:latest' locally
latest: Pulling from training/postgres
a3ed95caeb02: Pull complete
6e71c809542e: Pull complete
2978d9af87ba: Pull complete
e1bca35b062f: Pull complete
500b6decf741: Pull complete
74b14ef2151f: Pull complete
7afd5ed3826e: Pull complete
3c69bb244f5e: Pull complete
d86f9ec5aedf: Pull complete
010fabf20157: Pull complete
Digest: sha256:a945dc6dcfbc8d009c3d972931608344b76c2870ce796da00a827bd50791907e
Status: Downloaded newer image for training/postgres:latest
e5c184b284eb4741760504cce473494b0e63757d9a305e1fd8fbd70a0031d616

→ 「training/postgres」というimageがなかったため、リポジトリから自動で　Pullしてくれました。
```

・起動したコンテナが指定のネットワークに接続していることを確認

```bash
[ec2-user@mitzi_dev02 ~]$ docker inspect --format='{{json .NetworkSettings.Networks}}'  db
{"my-bridge-network":{"IPAMConfig":null,"Links":null,"Aliases":["e5c184b284eb"],"NetworkID":"daa4195aab0bd7da4f20371d15660529a016457aee8eaef936f028f62c18229f","EndpointID":"22e20f5f4ef82da7781288b495c79b3d270d366b3fb95dd7176cb638c5d2d3fc","Gateway":"172.18.0.1","IPAddress":"172.18.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:12:00:02"}}
```

###◯現在の状態
・ネットワーク<b>「bridge」</b>に<b>「webapp」</b>というコンテナ
・ネットワーク<b>「my-bridge-network」</b>に<b>「db」</b>というコンテナ

##01-5. 同一ネットワークにコンテナを接続
・このままだとコンテナ間で通信が出来ないため、「webapp」も「my-bridge-network」に接続させます。
下記のようにコマンドを実行することで実行中のコンテナをネットワークに接続することが出来ます。
(ドキュメントによると複数のネットワークに接続することが出来るとのこと)

```bash
[ec2-user@mitzi_dev02 ~]$ docker network connect my-bridge-network webapp
```

・確認

```bash
[ec2-user@mitzi_dev02 ~]$ docker inspect --format='{{json .NetworkSettings.Networks}}'  webapp
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"1916875b8e0e5ab85d5e360a1ab32601f0744224bd76638ff527e890bdcc8013","EndpointID":"1def167abf8c1cc5e6a494528502809314649114ea0f0ca7153264c211008307","Gateway":"172.17.0.1","IPAddress":"172.17.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"},"my-bridge-network":{"IPAMConfig":{},"Links":null,"Aliases":["4687219e75db"],"NetworkID":"daa4195aab0bd7da4f20371d15660529a016457aee8eaef936f028f62c18229f","EndpointID":"19c5ea9bfe3559efbc13bcce68ce5daf5e120bf2fb9002d75c3b1749e8d3d3e5","Gateway":"172.18.0.1","IPAddress":"172.18.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:12:00:03"}}
```
→ 「bridge」と「my-bridge-network」に接続していることが確認出来た。
→ 分かりづらいがそれぞれのNW上でサブネットに所属しIPアドレスが割り振られている「172.17.0.2」と「172.18.0.3」


##01-6. 疎通確認

・dbコンテナ中でシェルを起動

```bash
[ec2-user@mitzi_dev02 ~]$ docker exec -it db bash
root@e5c184b284eb:/#
```

・web コンテナに向けてping実行 (この時、IPではなく宛先にコンテナ名を指定)

```bash
root@e5c184b284eb:/# ping -c 3 webapp
PING webapp (172.18.0.3) 56(84) bytes of data.
64 bytes from webapp.my-bridge-network (172.18.0.3): icmp_seq=1 ttl=255 time=0.044 ms
64 bytes from webapp.my-bridge-network (172.18.0.3): icmp_seq=2 ttl=255 time=0.077 ms
64 bytes from webapp.my-bridge-network (172.18.0.3): icmp_seq=3 ttl=255 time=0.059 ms

--- webapp ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2044ms
rtt min/avg/max/mdev = 0.044/0.060/0.077/0.013 ms
```
→ 新ネットワーク上のコンテナ間で通信出来ることが確認出来ました。


以上になります。
引き続き学習の方、進めてゆきます。