Dockerのブリッジ・ネットワークでのコンテナ間名前解決がどうなっているのか見てみた

※こちらの記事は[個人ブログ](https://tech.tsukapah.com/docker-bridge-network/)に移行しました

# 動作確認環境の定義
まずは同じブリッジ・ネットワークにコンテナを立ち上げるためのdocker-compose.ymlを定義します。
特になにかのサービスを動かす必要はないので雑な感じになってます。

```bash
$ cat docker-compose.yml
version: '2'
services:
  centos1:
    image: centos
    container_name: centos1
    command: tail -f /dev/null
    networks:
      - centos

  centos2:
    image: centos
    container_name: centos2
    command: tail -f /dev/null
    networks:
      - centos

networks:
  centos:
    driver: bridge
```

# コンテナネットワーク作成/コンテナの起動
上記のdocker-compose.ymlを元にブリッジ・ネットワークの作成およびコンテナの起動を行います。

```bash
$ docker-compose up -d
Creating network "test_centos" with driver "bridge"
Creating centos2
Creating centos1
```

# コンテナネットワークの確認

```bash
$ docker network ls
NETWORK ID          NAME                         DRIVER              SCOPE
42165a96d808        bridge                       bridge              local
3762bcd6bffb        host                         host                local
f21c4ff0a40e        none                         null                local
888673525ef8        test_centos                  bridge              local
```

`test_centos`というブリッジ・ネットワークができています。
docker-composeを使うと名前のプレフィックスにdocker-compose.ymlを置いてあるディレクトリ名がつくようです。

# コンテナの確認

```bash
$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                                NAMES
ee82b4459dd3        centos                        "tail -f /dev/null"      28 minutes ago      Up 28 minutes                                            centos1
33be8d105125        centos                        "tail -f /dev/null"      28 minutes ago      Up 28 minutes                                            centos2
```

docker-compose.yml内の`container_name`で指定したとおりのコンテナが実行中になっていると思います。

# ブリッジ・ネットワークの詳細を確認してみる

```bash
$ docker network inspect test_centos
[
    {
        "Name": "test_centos",
        "Id": "888673525ef867e345d725fc931cd101d47a2175349bcd6af18615bc0c54b99d",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1/16"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "33be8d105125bc2eddb314e947cc8a6f43941d98959766320dd6e8f39457c450": {
                "Name": "centos2",
                "EndpointID": "1be71737dcc84729d0200f895ee1ec350efa66cdf46f41577294e01eaa658775",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            },
            "ee82b4459dd3d7034ecd0ef3f0c1d41e3288ae7045b38ebaabb9f519f1de6eef": {
                "Name": "centos1",
                "EndpointID": "7f912cb4bb22c11739ab88ada9c71d2ecbd32c9e0e0b0aeafb08368ed04d38e0",
                "MacAddress": "02:42:ac:13:00:03",
                "IPv4Address": "172.19.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
```

centos1は172.19.0.3/16、centos2は172.19.0.2/16がアサインされました。

# コンテナにログイン

コンテナ間の名前解決を見たいので片側のコンテナに入ります。

```bash
$ docker exec -it centos1 bash
```

# 疎通確認

ログインしていない方のコンテナと通信できるか確認してみます。

```bash
[root@ee82b4459dd3 /]# ping centos2 -c 4
PING centos2 (172.19.0.2) 56(84) bytes of data.
64 bytes from centos2.test_centos (172.19.0.2): icmp_seq=1 ttl=64 time=0.597 ms
64 bytes from centos2.test_centos (172.19.0.2): icmp_seq=2 ttl=64 time=0.141 ms
64 bytes from centos2.test_centos (172.19.0.2): icmp_seq=3 ttl=64 time=0.150 ms
64 bytes from centos2.test_centos (172.19.0.2): icmp_seq=4 ttl=64 time=0.099 ms

--- centos2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3017ms
rtt min/avg/max/mdev = 0.099/0.246/0.597/0.204 ms
```

pingが通ります。
宛先アドレスも先に確認したものと同じになっています。

# 名前解決の確認

## hostsの確認
まずはhostsを確認してみます。

```bash
[root@ee82b4459dd3 /]# cat /etc/hosts
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.19.0.3	ee82b4459dd3
```

ここにはいないようです。

## DNSに問い合わせてみる

DNSへの問い合わせにdigコマンドを使いたいのでbind-utilsをインストールします。

```bash
[root@ee82b4459dd3 /]# yum install -y bind-utils
省略...
```

名前解決してみます。

```bash
[root@ee82b4459dd3 /]# dig centos2

; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3 <<>> centos2
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51306
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;centos2.			IN	A

;; ANSWER SECTION:
centos2.		600	IN	A	172.19.0.2

;; Query time: 5 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Dec 12 11:14:23 UTC 2016
;; MSG SIZE  rcvd: 48
```

DNSサーバは`;; SERVER: 127.0.0.11#53(127.0.0.11)`となっています。

```bash
[root@ee82b4459dd3 /]# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
```

確認して見るとresolv.confで定義されてます。

---

Dockerエンジンはコンテナ内部向けにDNSサーバを動かすこと、またそのIPアドレスは`127.0.0.11`であることが確認できました。
この内容は[こちら](https://docs.docker.com/engine/userguide/networking/#/docker-embedded-dns-server)に記載してあるとおりでした。

---

# 後片付け

```bash
$ docker-compose stop
Stopping centos1 ... done
Stopping centos2 ... done
$ docker-compose rm
Going to remove centos1, centos2
Are you sure? [yN] y
Removing centos1 ... done
Removing centos2 ... done
$ docker network rm test_centos
test_centos
```