マルチホストDockerネットワーキング(native overlay)

  • 69
    Like
  • 0
    Comment
More than 1 year has passed since last update.

2015/11/13追記

docker 1.9 正式版での検証した記事を、マルチホストDockerネットワーキング(正式版 native overlay)で公開した。

正式版のoverlay networkは、サブネットアドレスが指定できるようになるなどかなり進化しているため、今後はコチラを参照してほしい。


ずいぶん間が空いてしまったが、マルチホストで動作するDockerネットワーキングツールについてのまとめ第四弾。

(第一弾:pipework+GRE
(第二弾:etcd+flannel
(第三弾:weaveworks/weave
今回はDockerのnative overlay networkを取り上げる。

Dockerのnative networkについて

Docker libnetworkのWiki pageにあるように、Dockerは1.7.0からネットワーク機能を「libnetwork」として切り離し、networkをfirst class objectとして扱うように実装を修正している。ただし2015/10/07時点の最新リリース(1.8.2)ではまだCLIが封印されており、libnetworkの機能を直接操作することはできない。

libnetworkのコンセプト

libnetworkのコンセプトは「The Container Network Model(CNM)」と呼ばれており、以下3つの概念から構成されている。

The Container Network Model (CNM)
出展:Docker Blog - Docker Networking takes a step in the right direction

  1. Sandbox
    • コンテナのネットワークスタックの設定(インタフェースやルーティングテーブル、DNS設定等)を隠蔽するもの。
    • LinuxであればNetwork Namespace、FreeBSDであればJail等を用いて実装される。
    • 一つのSandboxが複数のEndpointを持っていても良い。
  2. Endpoint
    • SandboxをNetworkに参加させるもの。
    • Endpointはveth pairやOpen vSwitch internal port等を用いて実装される。
    • Endpointは一つのNetwork、一つのSandboxに所属する。
  3. Network
    • お互い直接通信できるEndpointの集合を表すもの。
    • NetworkはLinux bridgeやVLAN等を用いて実装される。
    • Networkは複数のEndpointを持つ。

詳細はlibnetworkのdesignドキュメントを参照

現時点で実装されているlibnetwork driver

https://github.com/docker/libnetwork/tree/master/drivers を見る限り、現時点では以下のlibnetwork driverが実装されているようだ。

ドライバ 備考
Null driverが備えるべきAPIの空実装。ネットワークが不要なコンテナの場合に利用する。(従来の --net=none に相当)
Bridge Linux Bridgeとiptablesを用いたネットワークを実現。 docker0 を作り、Endpointとbridge間を veth pair で接続する。(デフォルトで用いられるdockerネットワーク --net=bridge に相当)
Host ホストOSのネットワークをそのまま利用する。(従来の --net=host に相当)
Overlay VXLANでカプセリングしたオーバーレイネットワークを複数ホスト間に延伸する。
Remote 動的に登録されるDriverの接続ポイントとなる。Remoteパッケージ自体はDriverの実装を持たず、libnetworkのpluginとして動作するdriverプロセスへのプロキシを提供する。

上記以外にもdrivers以下にはwindows.goなるコードもあるが、"TODO Windows. This is a placeholder for now" とコメントされているだけで中身はnull driverとほぼ同じでしかない。

またWeaveworksのweaveは、libnetworkのRemote Driver pluginを実装しているようである。が、未検証。

overlay network driverの前提条件

libnetworkのoverlay driverを動作させるためには、以下の環境が必要となる。

  • 3.16以上のLinux kernel
    • Ubuntu 14.04 LTSのカーネルは3.13のため、カーネルアップデートが必要
  • Experimental Docker Client
    • 正式リリースされている1.8.2のDocker Clientにはlibnetworkを操作するCLIが搭載されていないため、experimental releaseのDockerが必要
  • 分散KVS
    • libnetworkのoverlay driverは、NetworkやEndpoint等のメタデータを保持するためにlibkvを用いる
    • libkvは現時点で次の分散KVSをサポートしている
    • consul >= 0.5.1 or etcd >= 2.0 or zookeeper >= 3.4.5

Docker native overlay networkの検証環境の準備

ではここから、SoftLayerのVMを用いてlibnetworkのoverlay driverを検証するための環境を準備する。今回は以下のバージョンで検証を行った。

DC hostname private IP address (eth0) private network address
ホスト1 Dallas9 overlay01 10.121.212.207 10.121.212.192/26
ホスト2 Dallas9 overlay02 10.121.212.217 10.121.212.192/26
ホスト3 Dallas6 overlay03 10.107.33.254 10.107.33.192/26
version
distribution Ubuntu 14.04.3 LTS
kernel 3.19.0-30-generic
consul v0.5.2
docker 1.9.0-dev, build 93bd57b, experimental

カーネルアップデート

SoftLayerではUbuntu 15.04のOSイメージが提供されていないため、14.04 LTSで立ち上げた仮想マシンのカーネルを15.04のカーネルにアップデートする。

全てのホストで最新版(15.04)カーネルにアップデート
root@overlay01:~# apt-get install linux-generic-lts-vivid -y
root@overlay01:~# reboot
カーネルのバージョン確認
root@overlay01:~# uname -r
3.19.0-30-generic
root@overlay01:~# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"

パッケージインストール

全てのホストで必要なパッケージをインストールする。

全てのホストでパッケージをインストール
root@overlay01:~# apt-get update
root@overlay01:~# apt-get upgrade -y
root@overlay01:~# apt-get install curl unzip git build-essential bridge-utils -y

(bridge-utilsはネットワークの状態確認のためにインストールするので、overlay networkを動作させるだけならば不要)。

consulのインストール

今回は分散KVSとしてconsulを利用する。全てのホストに最新版のconsulをインストールする。

全てのホストにconsulのインストール
root@overlay01:~# curl -OL https://dl.bintray.com/mitchellh/consul/0.5.2_linux_amd64.zip
root@overlay01:~# unzip 0.5.2_linux_amd64.zip
root@overlay01:~# mv consul /usr/local/bin/
consulのバージョン確認
root@overlay01:~# consul version
Consul v0.5.2
Consul Protocol: 2 (Understands back to: 1)

experimental Dockerのインストール

全てのホストにDockerをソースコードからビルドしてインストールする。

公式リリースのDockerをインストール

DockerのソースコードをビルドするためにはDockerが必要なので、まずは公式リリースのDocker(1.8.2)をインストールする。

リリースバージョンのDockerをインストール
root@overlay01:~# curl -sSL https://get.docker.com/ | sh

Dockerのソースコード取得

Dockerのソースコードをgithubからcloneする。

Dockerのソースコードをclone
root@overlay01:~# git clone https://github.com/docker/docker.git

Dockerのビルド

重要:2015/09/26に、大きな改修が入ったlibnetworkとlibkvがDocker本体に取り込まれ、Dockerデーモンに指定するoverlay networkの設定オプションも変更された。
(これまで --kv-store=consul:localhost:8500 と指定していた分散KVSオプションが、 --cluster-store=consul://localhost:8500 と指定するようになった等)

実装が不安定なのかオプションが足りないのか不明だが、2015/10/07の本記事の執筆時点のmasterの最新Commit(0137e3eda2bae42a83cecd967249e4da54f2fa52)では、ホスト間の通信が届かない。

そのため2015/09/26の大規模改修以前のコードで検証を行うことにする。全てのホストで以下の作業を実施する。

大規模改修直前のcommitでDockerをビルド
root@overlay01:~# cd docker/
root@overlay01:~/docker# git checkout -b overlay_test 93bd57b0b21e1a802b80388c8fc034780e3200fc
root@overlay01:~/docker# make DOCKER_EXPERIMENTAL=1 binary

Docker 1.8.2 の無効化

Dockerのビルドが成功すれば最初にインストールした正式リリースのDockerは不要となるため、Dockerデーモンを停止して自動起動しないように設定する。

root@overlay01:~/docker# service docker stop
root@overlay01:~/docker# mv /etc/init/docker.conf /etc/init/docker.conf.disable
root@overlay01:~/docker# cd

Experimental DockerへPATHを設定

正式リリースのDockerではなくビルドしたDockerを使うようにPATHを差し替える。

PATHの変更
root@overlay01:~# echo 'PATH=$HOME/docker/bundles/latest/binary:$PATH' >> .bashrc
root@overlay01:~# source .bashrc
root@overlay01:~# which docker
/root/docker/bundles/latest/binary/docker
Dockerのバージョン確認
root@overlay01:~# docker --version
Docker version 1.9.0-dev, build 93bd57b, experimental

Docker native overlay networkの検証

構築した検証環境で、Docker native overlay networkの検証を行う。

consulクラスタの起動

まずはホスト1を起点としてconsulクラスタを構成する(起点はどのホストでも良い)。

ホスト1

consul起動
root@overlay01:~# rm -rf /tmp/consul
root@overlay01:~# nohup consul agent -server -bootstrap-expect 3 -data-dir=/tmp/consul -node=overlay01 -bind=10.121.212.207 &

ホスト2

consul起動とホスト1へのjoin
root@overlay02:~# rm -rf /tmp/consul
root@overlay02:~# nohup consul agent -server -data-dir=/tmp/consul -node=overlay02 -bind=10.121.212.217 &
root@overlay02:~# consul join 10.121.212.207

ホスト3

consul起動とホスト1へのjoin
root@overlay03:~# rm -rf /tmp/consul
root@overlay03:~# nohup consul agent -server -data-dir=/tmp/consul -node=overlay03 -bind=10.107.33.254 &
root@overlay03:~# consul join 10.121.212.207
consulクラスタの確認
root@overlay03:~# consul members
Node       Address              Status  Type    Build  Protocol  DC
overlay03  10.107.33.254:8301   alive   server  0.5.2  2         dc1
overlay01  10.121.212.207:8301  alive   server  0.5.2  2         dc1
overlay02  10.121.212.217:8301  alive   server  0.5.2  2         dc1

dockerデーモンの再起動

重要:overlay networkの正式リリース時には、本記事とはオプションが異なっている可能性があることに注意

overlay networkを利用するために、ホスト1を起点とするオプションを指定してDocker デーモンを起動する。

ホスト1

Dockerデーモン起動
root@overlay01:~# nohup docker daemon --kv-store=consul:localhost:8500 --label=com.docker.network.driver.overlay.bind_interface=eth0 &

ホスト2

dockerデーモン再起動
root@overlay02:~# nohup docker daemon --kv-store=consul:localhost:8500 --label=com.docker.network.driver.overlay.bind_interface=eth0 --label=com.docker.network.driver.overlay.neighbor_ip=10.121.212.207 &

ホスト3

dockerデーモン再起動
root@overlay03:~# nohup docker daemon --kv-store=consul:localhost:8500 --label=com.docker.network.driver.overlay.bind_interface=eth0 --label=com.docker.network.driver.overlay.neighbor_ip=10.121.212.207 &

Docker native overlay networkの動作確認

ここまででDocker native overlay networkを利用する準備が整ったので、実際に動作させてみる。

overlay networkの構成

どのホストでもかまわないので、Networkを構成する。今回はホスト1から vn01 という名前のoverlay networkを構成した。-d overlay と明示的にドライバを指定しないとbridge driverが使われてしまうので注意。

overlay_networkの構成
root@overlay01:~# docker network create -d overlay vn01

構成されたNetworkは、全てのホストで共有されている(bridge、host、noneドライバは最初から構成されているもの)。

ホスト1でnetworkを確認
root@overlay01:~# docker network ls
NETWORK ID          NAME                TYPE
cdba3727e0eb        none                null                
4341bf67e59a        host                host                
e7620c692cb2        bridge              bridge              
1dd2898c340f        vn01                overlay                      
ホスト2でnetworkを確認
root@overlay02:~# docker network ls
NETWORK ID          NAME                TYPE
c162794dbd38        bridge              bridge              
1dd2898c340f        vn01                overlay             
59ff56da5d84        none                null                
b0611c74ed57        host                host                              
ホスト3でnetworkを確認
root@overlay03:~# docker network ls
NETWORK ID          NAME                TYPE
2a77c13efd4a        none                null                
b89fc8197c12        host                host                
d25d4b617992        bridge              bridge              
1dd2898c340f        vn01                overlay             

Serviceの構成

Networkに対応付けられたEndpointを生成する。

serviceの構成
root@overlay01:~# docker service publish ep01.vn01

EndpointとNetworkの組み合わせを意味するServiceも、全てのホストで共有される。

ホスト1でserviceを確認
root@overlay01:~# docker service ls
SERVICE ID          NAME                NETWORK             CONTAINER
343a63c0f2c9        ep01                vn01                               
ホスト2でserviceを確認
root@overlay02:~# docker service ls
SERVICE ID          NAME                NETWORK             CONTAINER
343a63c0f2c9        ep01                vn01                
ホスト3でserviceを確認
root@overlay03:~# docker service ls
SERVICE ID          NAME                NETWORK             CONTAINER
343a63c0f2c9        ep01                vn01                

ホスト1でコンテナを起動してoverlay networkに接続

ホスト1でコンテナを起動し、作成したEndpointをattachする。

起動したコンテナにEndpointをattach
root@overlay01:~# CID=$(docker run -itd --name=c01 --hostname=c01 ubuntu:14.04)
root@overlay01:~# docker service attach $CID ep01.vn01

この段階で、立ち上げたコンテナには「コンテナ起動時に差し込まれた、docker0のbridge networkに接続されたeth0(172.17.0.1/16)」と「serviceをattachした際に差し込まれた、overlay networkに接続されたeth1(172.21.0.1/16)」が存在する。

コンテナのインタフェース
root@overlay01:~# docker exec $CID ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
13: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
16: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
    link/ether 02:42:ac:15:00:01 brd ff:ff:ff:ff:ff:ff
    inet 172.21.0.1/16 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe15:1/64 scope link 
       valid_lft forever preferred_lft forever

ホスト2でコンテナを立ち上げ

上記の手順は煩雑なため、接続するNetworkやEndpointを指定してコンテナを直接起動することもできる。指定したNetworkが無ければ自動で作成し、存在すればそのNetworkにEndpointを参加させる。
この場合docker0には接続されず、overlay networkにのみ接続する。

EndpointやNetworkを直接指定してコンテナを起動
root@overlay02:~# CID=$(docker run -itd --name=c02 --hostname=c02 --publish-service=ep02.vn01.overlay ubuntu:14.04)
コンテナのインタフェース
root@overlay02:~# docker exec $CID ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
60: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
    link/ether 02:42:ac:15:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.21.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe15:2/64 scope link 
       valid_lft forever preferred_lft forever

ホスト3でコンテナを立ち上げ

ホスト3ではコンテナを2つ起動してみる。

Endpointを直接指定してコンテナを起動
root@overlay03:~# CID1=$(docker run -itd --name=c03 --hostname=c03 --publish-service=ep03.vn01.overlay ubuntu:14.04)
root@overlay03:~# docker exec $CID1 ip addr show eth0 | grep 172.
    inet 172.21.0.3/16 scope global eth0

root@overlay03:~# CID2=$(docker run -itd --name=c04 --hostname=c04 --publish-service=ep04.vn01.overlay ubuntu:14.04)
root@overlay03:~# docker exec $CID2 ip addr show eth0 | grep 172.
    inet 172.21.0.4/16 scope global eth0

serviceの状態確認

今回作成したEndpoint(ep01、ep02、ep03、ep04)が全て同じoverlay network(vn01)に所属していることがわかる。

ホスト1でのserviceの状態
root@overlay01:~# docker service ls
SERVICE ID          NAME                NETWORK             CONTAINER
48f088dc0a5e        c01                 bridge              d076a471f6d9
343a63c0f2c9        ep01                vn01                d076a471f6d9
811431a85a34        ep02                vn01                
30cca8a15a6e        ep03                vn01                
de7cffcff55e        ep04                vn01                
ホスト2でのserviceの状態
root@overlay02:~# docker service ls
SERVICE ID          NAME                NETWORK             CONTAINER
811431a85a34        ep02                vn01                0a8b69b789b3
30cca8a15a6e        ep03                vn01                
de7cffcff55e        ep04                vn01                
343a63c0f2c9        ep01                vn01                
ホスト3でのserviceの状態
root@overlay03:~# docker service ls
SERVICE ID          NAME                NETWORK             CONTAINER
343a63c0f2c9        ep01                vn01                
811431a85a34        ep02                vn01                
30cca8a15a6e        ep03                vn01                240323344a8e
de7cffcff55e        ep04                vn01                1820e31ec320

コンテナ間で疎通確認

ホスト1とホスト2は同一Subnet、ホスト3は異なるSubnetに所属している。しかしoverlay networkはホストのネットワーク状況に関わらず、全てのコンテナをL2で接続する。

疎通確認
root@overlay01:~# docker attach $CID

root@c01:/# ip neigh
root@c01:/# ping 172.21.0.1 -c2
PING 172.21.0.1 (172.21.0.1) 56(84) bytes of data.
64 bytes from 172.21.0.1: icmp_seq=1 ttl=64 time=0.035 ms
64 bytes from 172.21.0.1: icmp_seq=2 ttl=64 time=0.036 ms

--- 172.21.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.035/0.035/0.036/0.006 ms
root@c01:/# ping 172.21.0.2 -c2
PING 172.21.0.2 (172.21.0.2) 56(84) bytes of data.
64 bytes from 172.21.0.2: icmp_seq=1 ttl=64 time=0.657 ms
64 bytes from 172.21.0.2: icmp_seq=2 ttl=64 time=0.271 ms

--- 172.21.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.271/0.464/0.657/0.193 ms
root@c01:/# ping 172.21.0.3 -c2
PING 172.21.0.3 (172.21.0.3) 56(84) bytes of data.
64 bytes from 172.21.0.3: icmp_seq=1 ttl=64 time=1.65 ms
64 bytes from 172.21.0.3: icmp_seq=2 ttl=64 time=1.66 ms

--- 172.21.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.651/1.657/1.663/0.006 ms
root@c01:/# ping 172.21.0.4 -c2
PING 172.21.0.4 (172.21.0.4) 56(84) bytes of data.
64 bytes from 172.21.0.4: icmp_seq=1 ttl=64 time=1.47 ms
64 bytes from 172.21.0.4: icmp_seq=2 ttl=64 time=1.24 ms

--- 172.21.0.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.244/1.359/1.474/0.115 ms
root@c01:/# ip neigh
172.21.0.4 dev eth1 lladdr 02:42:ac:15:00:04 REACHABLE
172.21.0.3 dev eth1 lladdr 02:42:ac:15:00:03 REACHABLE
172.21.0.2 dev eth1 lladdr 02:42:ac:15:00:02 REACHABLE

Docker native overlay networkの状態

最後にホストからみたNetwork Namespaceの状態を確認する。
重要:overlay networkの正式リリース時には、本記事とはネットワークアーキテクチャが異なっている可能性があることに注意

ホスト1のネットワーク

ホスト1の docker0 には、コンテナ起動時に差し込まれたveth pair(コンテナにとってのeth0)の片割れ( veth6392365 )が接続されている。
docker0veth6392365 も、ホストのネットワークから普通に確認できる(従来のdocker0と同様)。

ホストのdocker0の状態
root@overlay01:~# ip link show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:a2:1e:01:c1 brd ff:ff:ff:ff:ff:ff
root@overlay01:~# brctl show docker0
bridge name bridge id       STP enabled interfaces
docker0     8000.0242a21e01c1   no      veth6392365
root@overlay01:~# ip link show veth6392365
14: veth6392365: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 62:bd:22:eb:aa:42 brd ff:ff:ff:ff:ff:ff
root@overlay01:~# ethtool -S veth6392365
NIC statistics:
     peer_ifindex: 13
コンテナのeth0の状態
root@overlay01:~# docker exec $CID ip link show eth0
13: eth0: <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

一方overlay networkの情報はSandboxとして隔離されているため、ホストのネットワークには出現しない。libnetworkが作成したNetwork Namespaceを ip netns で確認してみると、以下のような状態になっている。

Sandboxの確認
root@overlay01:~# mkdir -p /var/run/netns
root@overlay01:~# ln -s /var/run/docker/netns/2-1dd2898c34 /var/run/netns/overlay
root@overlay01:~# ip netns exec overlay ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
    link/ether 3a:37:9d:10:64:38 brd ff:ff:ff:ff:ff:ff
    inet 172.21.255.254/16 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::4c2a:32ff:fecc:4fe4/64 scope link 
       valid_lft forever preferred_lft forever
15: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN group default 
    link/ether 7e:f2:3c:87:de:b2 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::7cf2:3cff:fe87:deb2/64 scope link 
       valid_lft forever preferred_lft forever
17: veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UP group default 
    link/ether 3a:37:9d:10:64:38 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::3837:9dff:fe10:6438/64 scope link 
       valid_lft forever preferred_lft forever
root@overlay01:~# ip netns exec overlay brctl show br0 
bridge name bridge id       STP enabled interfaces
br0     8000.3a379d106438   no      veth2
                            vxlan1
root@overlay01:~# ip netns exec overlay ethtool -S veth2
NIC statistics:
     peer_ifindex: 16
コンテナのeth1の状態
root@overlay01:~# docker exec $CID ip link show eth1
16: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:ac:15:00:01 brd ff:ff:ff:ff:ff:ff

Network Namespaceで隔離された br0 には vxlan1veth2 が接続されており、この veth2 はコンテナの eth1 につながっている。
コンテナ間は、この vxlan1 を経由してL2で接続される。

ホスト2とホスト3のネットワーク

同様にホスト2とホスト3のSandbox内を確認すると、vxlanとコンテナに接続されるvethが確認できる。

ホスト2のSandbox内のbridge
root@overlay02:~# ip netns exec overlay brctl show br0
bridge name bridge id       STP enabled interfaces
br0     8000.523a7d15ed52   no      veth2
                            vxlan1
ホスト3のSandbox内のbridge
root@overlay03:~# ip netns exec overlay brctl show br0
bridge name bridge id       STP enabled interfaces
br0     8000.1e9a6a141297   no      veth2
                            veth3
                            vxlan1

注意点

本記事で確認したoverlay driverの実装では、仮想ネットワークのネットワークアドレス( 172.21.0.0/16 )を任意に指定することはできない(と思われる)。またコンテナに与えられるIPアドレスも 172.21.0.1/16 からの昇順で、任意に指定する仕組みは準備されていない(と思われる)。

docker_networking_5_01.png

まとめ

docker nativeのoverlay networkを動作させることができた。3rd partyのツールを利用せずともホストを跨ったコンテナ間で通信できるようになることは、今後のDockerの活用シーンをより広げることだろう。

ただし正式にリリースされた際には、指定するオプションやネットワークアーキテクチャが異なる可能性があることに注意が必要である。