Docker事始め - ネットワークについて1

Dockerのネットワークについて軽く調べてみました。

# 環境
- OS : CentOS release 6.5 (Final)
- Kernel : 2.6.32-431.17.1.el6.x86_64
- Docker : docker-io-0.11.1-4.el6.x86_64  

# ホストOS側のネットワーク

```bash
# ifconfig 
docker0   Link encap:Ethernet  HWaddr FE:9B:89:E6:05:BD  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::c0ad:6ff:fece:6bb0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          <snip>

eth0      Link encap:Ethernet  HWaddr 00:0C:29:EA:83:FF  
          inet addr:192.168.1.174  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:feea:83ff/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          <snip>

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          <snip>

# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.0     *               255.255.255.0   U         0 0          0 eth0
link-local      *               255.255.0.0     U         0 0          0 eth0
172.17.0.0      *               255.255.0.0     U         0 0          0 docker0
default         192.168.0.254   0.0.0.0         UG        0 0          0 eth0

# sysctl -a|grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1
```

docker0というインタフェースが作成されており、固定IPアドレスが付与されています。
ipv4のフォワード機能も自動で有効になっていました。

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

```bash
# docker run -i -t centos /bin/bash
bash-4.1#
bash-4.1# ifconfig 
eth0      Link encap:Ethernet  HWaddr 76:93:DD:6B:8C:0D  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::7493:ddff:fe6b:8c0d/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          <snip>

bash-4.1# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
172.17.0.0      *               255.255.0.0     U         0 0          0 eth0
default         172.17.42.1     0.0.0.0         UG        0 0          0 eth0
```

コンテナ上ではホストOS上のdocker0に割り振られたネットワークセグメント上のIPアドレスがeth0に付与されています。また、デフォルトゲートウェイはdocker0が指定されています。
ホストOSとコンテナはdocker0を経由してネットワークの疎通が行われているように見えます。
実際に試してみましょう。

# 疎通を試す
## コンテナ ⇒ ホスト
```bash
bash-4.1# traceroute 172.17.42.1
bash: traceroute: command not found
# コンテナ側に標準でtracerouteコマンドはないようです。。。CentOSイメージは最小構成なのかな？
bash-4.1# yum -y install traceroute
bash-4.1# traceroute 172.17.42.1
traceroute to 172.17.42.1 (172.17.42.1), 30 hops max, 60 byte packets
 1  172.17.42.1 (172.17.42.1)  0.047 ms !X  0.013 ms !X  0.012 ms !X
bash-4.1# 
bash-4.1# traceroute 192.168.1.174
traceroute to 192.168.1.174 (192.168.1.174), 30 hops max, 60 byte packets
 1  192.168.1.174 (192.168.1.174)  0.046 ms !X  0.015 ms !X  0.011 ms !X
# 2hopかと思ったら1hopでいけるっぽい。。。
bash-4.1# 
bash-4.1# traceroute 192.168.1.175
traceroute to 192.168.1.175 (192.168.1.175), 30 hops max, 60 byte packets
 1  172.17.42.1 (172.17.42.1)  0.048 ms  0.015 ms  0.011 ms
 2  192.168.1.175 (192.168.1.175)  1.184 ms  1.172 ms  1.158 ms
# ホストOS側eth0の別ホストに対してであれば2hop
bash-4.1# 
bash-4.1# traceroute www.opst.co.jp
traceroute to www.opst.co.jp (54.249.236.62), 30 hops max, 60 byte packets
 1  172.17.42.1 (172.17.42.1)  0.038 ms  0.014 ms  0.011 ms
 2  192.168.1.254 (192.168.1.254)  0.352 ms  0.321 ms  0.271 ms
 3  xx.xx.xx.xx
 4  <snip>

bash-4.1# 
# exitコマンドでログアウトするとコンテナが破棄されるため
# Ctrl+p,Ctrl+qでコンテナを起動したままコンテナから抜ける
# 
```

## ホスト ⇒ コンテナ

```bash
# traceroute 172.17.42.1
traceroute to 172.17.42.1 (172.17.42.1), 30 hops max, 60 byte packets
 1  172.17.42.1 (172.17.42.1)  0.034 ms  0.010 ms  0.008 ms
# 
# traceroute 172.17.0.2
traceroute to 172.17.0.2 (172.17.0.2), 30 hops max, 60 byte packets
 1  172.17.0.2 (172.17.0.2)  0.499 ms  0.496 ms  0.491 ms
# こちらも1hop。。。
```

# 再度ホストOS側のネットワーク

```bash
# ifconfig
docker0   Link encap:Ethernet  HWaddr FE:DB:A2:47:0C:29  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::c0ad:6ff:fece:6bb0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          <snip>

eth0      Link encap:Ethernet  HWaddr 00:0C:29:EA:83:FF  
          inet addr:192.168.3.174  Bcast:192.168.3.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:feea:83ff/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          <snip>

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          <snip>

vethglbLjn Link encap:Ethernet  HWaddr FE:DB:A2:47:0C:29  
          inet6 addr: fe80::fcdb:a2ff:fe47:c29/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          <snip>

```

コンテナを起動した際にvethインタフェースが作成されるようです。
このインタフェースがナニモノなのかを調べていたら公式サイトの[Advanced networking](http://docs.docker.com/articles/networking/)に記載がありました。
記載内容によるとvethインタフェースはdocker0インタフェースのブリッジインタフェースのようです。

```bash
# ブリッジインタフェースは以下コマンドから確認可能
# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.fedba2470c29       no              vethglbLjn
```

#雑感
- ホストOSとコンテナのネットワークについてはブリッジで対応している
- 但しAdvanced networkingを確認していたら、ブリッジ以外のネットワークも可能っぽい
- 普通に疎通できたのでiptablesは未確認
- 特殊なことはやっていない

今回はDockerのホストOSとコンテナの疎通について確認しました。
次回はコンテナ上にWebサーバのようなサービスを起動したときの疎通について追ってみたいと思います。