dockerブリッジについて

#1 目的
コンテナネットワークのデバッグに役立つ情報をまとめる。


#2 環境

- ホストはVMware Workstation
- master1はゲストマシン。OSはCentOS7.2
- docker0はDockerブリッジ

```

  +----------------- master1(CentOS7.2) -------------+
  |                                                  |
  |     +-------------------------------------+      |
  |     |        docker0 (172.17.0.1/16)      |      |
  |     +------------------+------------------+      |
  |                        |                         |
  |                        |                         |
  |      +========== routing table ============+     |
  |      |   # ip route show                   |     |
  |      |   default via 192.168.0.1 dev eth0  |     |
  |      |   172.17.0.0/16 dev docker0         |     |
  |      |   192.168.0.0/24 dev eth0           |     |
  |      +=====================================+     |
  |                        |                         |
  |                        |                         |
  +---------------------- eth0 ----------------------+
                           | 192.168.0.10
                           |
  +---------------------------------------------------+
  |                 VMware  Workstation               |
  +---------------------------------------------------+
                           |
                           | 192.168.0.1
                   +-------+--------+
                   |     router     |
                   +----------------+

```


#3 dokcerブリッジの各種情報確認方法
ipコマンドやbrctlコマンドを使って、dokcerブリッジのMAC学習テーブルやARPテーブルを確認する。


##3.1 名前やMACアドレス(ip link)

```
どのようなデバイスがあるか確認する。docker0という名前のブリッジがあることがわかる(★印)
[root@master1 ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:18:5c:90 brd ff:ff:ff:ff:ff:ff
3:★docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT
    link/ether 02:42:a5:85:91:b6 brd ff:ff:ff:ff:ff:ff
[root@master1 ~]#

```


##3.2 ポート(brctl show <ブリッジ名>)

```
dockerブリッジのポートを確認する。
Pod(コンテナ)を起動していないので、ポートはまだ割り当てられていないことがわかる。
[root@master1 ~]# brctl show docker0
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242a58591b6       no
[root@master1 ~]#

```



##3.3 MAC学習テーブル(brctl showmacs <ブリッジ名>)

```
dockerブリッジのMAC学習テーブルを表示する。まだ何も登録されていない。
[root@master1 ~]# brctl showmacs docker0
port no mac addr                is local?       ageing timer
[root@master1 ~]#

```



##3.4 ARPテーブル(ip neigh show dev <ブリッジ名>)

```
dockerブリッジのARPテーブルを表示する。まだ何も登録されていない。
[root@master1 ~]# ip neigh show dev docker0
[root@master1 ~]#

```


##3.5 統計情報(ip -s link show dev <ブリッジ名>)

```
dockerブリッジの統計情報を表示する。
[root@master1 ~]# ip -s link show dev docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT
    link/ether 02:42:a5:85:91:b6 brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast
    259111     3157     0       0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    666135     3035     0       0       0       0
[root@master1 ~]#

dockerブリッジの統計情報を表示する。-hを付けると、単位を付けて分かりやすくなる。
[root@master1 ~]# ip -s -h link show dev docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT
    link/ether 02:42:a5:85:91:b6 brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast
    259k       3.16k    0       0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    666k       3.04k    0       0       0       0
[root@master1 ~]#

```


#4 MAC学習テーブルの確認

Podを1つ起動したときのMAC学習テーブルを確認する。

```
-------------------------------------
1. Podを起動する。
-------------------------------------
Podを起動する。
[root@master1 ~]# kubectl run nginx --image=nginx
deployment "nginx" created

Podの状態を確認する。
[root@master1 ~]# kubectl get pod -o wide
NAME                     READY     STATUS    RESTARTS   AGE       NODE
nginx-2040093540-k0mv4   1/1       Running   0          40s       master1

-------------------------------------------
2. PodのMACアドレス,IPを確認する。
-------------------------------------------
Podでipコマンドを実行する。
[root@master1 ~]# kubectl exec -it nginx-2040093540-k0mv4 bash
root@nginx-2040093540-k0mv4:/# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
root@nginx-2040093540-k0mv4:/#

root@nginx-2040093540-k0mv4:/# ip addr show dev eth0|grep -w inet
    inet 172.17.0.2/16 scope global eth0

----------------------------------------
3. ブリッジのポートとMACアドレスを確認する。
----------------------------------------
dockerブリッジのポートを確認する。
Podを起動したことで、ポート(veth2482a36)がdockerブリッジに割り当てられたことがわかる。
[root@master1 ~]# brctl show docker0
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242fa6f2e95       no              veth2482a36

MAC学習テーブルを確認する。ブリッジのMACアドレスが登録されていることがわかる。
[root@master1 ~]# brctl showmacs docker0
port no mac addr                is local?       ageing timer
  1     9e:73:f4:f6:8c:8a       yes                0.00


図に書くと、以下のような状態になったことがわかる。
()内はMACアドレス、<>内はIPアドレスを表す。


  +----------------- master1(CentOS7.2) -------------+
  |                                                  |
  |     +-----------------------+                    |
  |     |       Pod(nginx)      |                    |
  |     |                       |                    |
  |     |   < 172.17.0.2 >      |                    |
  |     |  (02:42:ac:11:00:02)  |                    |
  |     +--------- eth0 --------+                    |
  |                 |                                |
  |                 |                                |
  |     +----- veth2482a36 -------------------+      |
  |     |  (9e:73:f4:f6:8c:8a)                |      |
  |     |                                     |      |
  |     |        docker0 <172.17.0.1/16>      |      |
  |     |                                     |      |
  |     +------------------+------------------+      |
  |                        |                         |
  |                        |                         |
  |      +========== routing table ============+     |
  |      |   # ip route show                   |     |
  |      |   default via 192.168.0.1 dev eth0  |     |
  |      |   172.17.0.0/16 dev docker0         |     |
  |      |   192.168.0.0/24 dev eth0           |     |
  |      +=====================================+     |
  |                        |                         |
  |                        |                         |
  +---------------------- eth0 ----------------------+
                           | <192.168.0.10>
                           |
  +---------------------------------------------------+
  |                 vmware  Workstation               |
  +---------------------------------------------------+
                           |
                           | <192.168.0.1>
                   +-------+--------+
                   |     router     |
                   +----------------+

```


#5 MAC学習テーブルの確認(Podを2つ起動したとき）

```
-------------------------------------
1. もう1つPodを起動する。
-------------------------------------
Podを起動する。
[root@master1 ~]# kubectl run nginx1 --image=nginx
deployment "nginx1" created

Podの状態を確認する。Podが2つ起動したことがわかる。
[root@master1 ~]# kubectl get pod -o wide
NAME                      READY     STATUS    RESTARTS   AGE       NODE
nginx-2040093540-k0mv4    1/1       Running   0          51m       master1
nginx1-2621397958-auuga   1/1       Running   0          22s       master1

---------------------------------------------
2. 新しく起動したPodのMACアドレス,IPを確認する。
---------------------------------------------
PodのIPアドレスを確認する。
[root@master1 ~]# kubectl exec -it nginx1-2621397958-auuga bash
root@nginx1-2621397958-auuga:/# ip addr show dev eth0 |grep -w inet
    inet 172.17.0.3/16 scope global eth0

PodのMACアドレスを確認する。
root@nginx1-2621397958-auuga:/# ip link show dev eth0
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
root@nginx1-2621397958-auuga:/#

--------------------------------
3. ポートとMACアドレスを確認する。
--------------------------------
dockerブリッジのポートを確認する。もう1つポートが割り当てられたことがわかる。
[root@master1 ~]#  brctl show docker0
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242fa6f2e95       no              veth1b74665
                                                        veth2482a36

MAC学習テーブルを確認する。ブリッジのMACアドレスしか登録されていないことがわかる。
[root@master1 ~]# brctl showmacs docker0
port no mac addr                is local?       ageing timer
  1     9e:73:f4:f6:8c:8a       yes                0.00
  2     e6:64:d9:b4:2e:8c       yes                0.00


図に書くと、以下のような状態になったことがわかる。
()内はMACアドレス、<>内はIPアドレスを表す。


  +----------------------- master1(CentOS7.2) -----------------------+
  |                                                                  |
  |     +-----------------------+      +-----------------------+     |
  |     |       Pod(nginx)      |      |       Pod(nginx1)     |     |
  |     |                       |      |                       |     |
  |     |   < 172.17.0.2 >      |      |   < 172.17.0.3 >      |     |
  |     |  (02:42:ac:11:00:02)  |      |  (02:42:ac:11:00:03)  |     |
  |     +--------- eth0 --------+      +--------- eth0 --------+     |
  |                 |                               |                |
  |                 |                               |                |
  |     +----- veth2482a36 ------------------- veth1b74665 ---+      |
  |     |  (9e:73:f4:f6:8c:8a)            (e6:64:d9:b4:2e:8c) |      |
  |     |                                                     |      |
  |     |        docker0 (172.17.0.1/16)                      |      |
  |     |                                                     |      |
  |     +------------------+----------------------------------+      |
  |                        |                                         |
  |                        |                                         |
  |      +========== routing table ============+                     |
  |      |   # ip route show                   |                     |
  |      |   default via 192.168.0.1 dev eth0  |                     |
  |      |   172.17.0.0/16 dev docker0         |                     |
  |      |   192.168.0.0/24 dev eth0           |                     |
  |      +=====================================+                     |
  |                        |                                         |
  |                        |                                         |
  +---------------------- eth0 --------------------------------------+
                           | 192.168.0.10
                           |
  +---------------------------------------------------+
  |                 vmware  Workstation               |
  +---------------------------------------------------+
                           |
                           | 192.168.0.1
                   +-------+--------+
                   |     router     |
                   +----------------+

```


#6 MAC学習テーブルにMACアドレスが登録されることを確認する。

Pod(nginx)からルータに対してpingを実行すると、
MAC学習テーブル(MAC address table)にMACアドレスが登録されることがわかった。

```
Pod(nginx)からルータに対してpingを実行する。
[root@master1 ~]# kubectl exec -it nginx-2040093540-k0mv4 bash
root@nginx-2040093540-k0mv4:/# ping -c 1 192.168.0.1
PING 192.168.0.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: icmp_seq=0 ttl=254 time=2.388 ms
--- 192.168.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.388/2.388/2.388/0.000 ms
root@nginx-2040093540-k0mv4:/#

MAC学習テーブルを確認する。PodのMACアドレスが,MAC学習テーブルに登録されたことがわかる(★印)
"yes"と表示されているポートはdockerブリッジのポート、"no"と表示されているのはポートはPodのポートを表す。
[root@master1 ~]# brctl showmacs docker0
port no mac addr                is local?       ageing timer
  1   ★02:42:ac:11:00:02       no                13.45
  1     9e:73:f4:f6:8c:8a       yes                0.00
  2     e6:64:d9:b4:2e:8c       yes                0.00
[root@master1 ~]#


MAC学習テーブル(MAC address table)は以下のようになる。
ポートは300秒(デフォルト）でMAC学習テーブルから消去される。


  +----------------------- master1(CentOS7.2) -----------------------+
  |                                                                  |
  |     +-----------------------+      +-----------------------+     |
  |     |       Pod(nginx)      |      |       Pod(nginx1)     |     |
  |     |                       |      |                       |     |
  |     |   < 172.17.0.2 >      |      |   < 172.17.0.3 >      |     |
  |     |  (02:42:ac:11:00:02)  |      |  (02:42:ac:11:00:03)  |     |
  |     +--------- eth0 --------+      +--------- eth0 --------+     |
  |                 |                               |                |
  |                 |                               |                |
  |     +----- veth2482a36 ------------------- veth1b74665 ---+      |
  |     |  (9e:73:f4:f6:8c:8a)            (e6:64:d9:b4:2e:8c) |      |
  |     |                                                     |      |
  |     |                                                     |      |
  |     |  ============== MAC address table ================= |      |
  |     |  port  mac addr           is local?  ageing timer   | <========= docker0
  |     |  ------------------------------------------------   |      |
  |     |    1   02:42:ac:11:00:02   no        13.45          |      |
  |     |    1   9e:73:f4:f6:8c:8a   yes        0.00          |      |
  |     |    2   e6:64:d9:b4:2e:8c   yes        0.00          |      |
  |     |                                                     |      |
  |     +------------------+----------------------------------+      |
  |                        |                                         |
  |                        |                                         |
  |      +========== routing table ============+                     |
  |      |   # ip route show                   |                     |
  |      |   default via 192.168.0.1 dev eth0  |                     |
  |      |   172.17.0.0/16 dev docker0         |                     |
  |      |   192.168.0.0/24 dev eth0           |                     |
  |      +=====================================+                     |
  |                        |                                         |
  |                        |                                         |
  +---------------------- eth0 --------------------------------------+
                           | 192.168.0.10
                           |
  +---------------------------------------------------+
  |                 vmware  Workstation               |
  +---------------------------------------------------+
                           |
                           | 192.168.0.1
                   +-------+--------+
                   |     router     |
                   +----------------+

```



#7 tcpdumpでパケット採取可能なデバイスを確認する

以下の場所で採取可能であることがわかった。
 - docker0ブリッジのポート(veth2482a36,veth1b74665)
 - dockerブリッジ(docker0)
 - ゲストマシンのeth0

```
---------------------------------------------------------------
1. dockerブリッジのポートでパケット採取可能かどうか確認する。
---------------------------------------------------------------
Podからルータにpingを実行する。
root@nginx-2040093540-k0mv4:/# ping -c 1 192.168.0.1

dockerブリッジのポート(veth2482a36)でパケット採取が可能であることがわかる。
[root@master1 ~]# tcpdump -i veth2482a36
tcpdump: WARNING: veth2482a36: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth2482a36, link-type EN10MB (Ethernet), capture size 65535 bytes
23:31:53.458972 IP 172.17.0.2 > 192.168.0.1: ICMP echo request, id 81, seq 0, length 64
23:31:53.462306 IP 192.168.0.1 > 172.17.0.2: ICMP echo reply, id 81, seq 0, length 64

------------------------------------------------------
2. dockerブリッジでパケット採取可能かどうか確認する。
------------------------------------------------------
Podからルータにpingを実行する。
root@nginx-2040093540-k0mv4:/# ping -c 1 192.168.0.1
-以下、略-

dockerブリッジ(docker0)でパケット採取が可能であることがわかる。
[root@master1 ~]# tcpdump -i docker0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 65535 bytes
23:29:22.639992 IP 172.17.0.2 > 192.168.0.1: ICMP echo request, id 80, seq 0, length 64
23:29:22.642634 IP 192.168.0.1 > 172.17.0.2: ICMP echo reply, id 80, seq 0, length 64

------------------------------------------------------
3. eth0でパケット採取可能かどうか確認する。
------------------------------------------------------
Podからルータにpingを実行する。
root@nginx-2040093540-k0mv4:/# ping -c 1 192.168.0.1
-以下、略-

eth0でパケット採取が可能であることがわかった。
送信元IPアドレスがeth0のアドレスに変換されていることがわかる。
[root@master1 ~]# tcpdump -i eth0 icmp -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
08:30:21.429823 IP 192.168.0.10 > 192.168.0.1: ICMP echo request, id 22, seq 0, length 64
08:30:21.431163 IP 192.168.0.1 > 192.168.0.10: ICMP echo reply, id 22, seq 0, length 64

```


#8 dockerコマンドでブリッジの状態を確認する(docker network inspect <ブリッジ名>)


```
Podの状態を確認する。Podが2つ起動していることがわかる。
[root@master1 ~]# kubectl get pod
NAME                      READY     STATUS    RESTARTS   AGE
nginx-2040093540-k0mv4    1/1       Running   1          13h
nginx1-2621397958-auuga   1/1       Running   0          12h


ブリッジの状態を確認する。ブリッジの他に、Podの名前やIPアドレスも確認できる。
[root@master1 ~]# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "f6f66c723b075033fcae6b58798a3296801dbf0840378a4996bfdf0a0c2026b6",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"
                }
            ]
        },
        "Containers": {　★Podの情報が2つ登録されていることがわかる。
            "2c46b426cde95e4eb898c44dfe05e01aabb6b390d3d80038acad13fd938ecd05": {
                "Name": "k8s_POD.ae8ee9ac_nginx1-2621397958-auuga_default_1f98b00b-da5a-11e6-ba88-000c29185c90_0687c1c7",
                "EndpointID": "e6e38b0d4a6ff361a8b45aaa894c0be25233b782efd1aca5327848c27c342f2f",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "ac566daf6351e32224cca20aca2b130ff57931f7f47a3f3149139acb9cb81104": {
                "Name": "k8s_POD.ae8ee9ac_nginx-2040093540-k0mv4_default_066f518b-da53-11e6-ba88-000c29185c90_9aa04ef2",
                "EndpointID": "b901efc052a34e76814bfca1828512470103ff38ebd36fe965315c04018e06ad",
                "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"
        }
    }
]

```