こんにちは。@jedipunkz です。

今回は Weave というコンテナ間のネットワークを提供してくれる Docker のネットワークプラ グインを使ってみました。下記のような沢山の機能があるようです。

  • Fast Data Path
  • Docker Network Plugin
  • Security
  • Dynamic Netwrok Attachment
  • Service Binding
  • Fault Tolerance
  • etc …

この記事では上から幾つか抜粋して、Weave ってどのように動かせるのか?を解説します。 そこから Weave が一体ナニモノなのか理解できればなぁと思います。

Vagrant を使った構成

この記事では下記の構成を作って色々と試していきます。使う技術は

  • Vagrant
  • Docker
  • Weave

です。

+---------------------+ +---------------------+ +---------------------+
| docker container a1 | | docker container a2 | | docker container a3 |
+---------------------+ +---------------------+ +---------------------+
|    vagrant host 1   | |    vagrant host 2   | |    vagrant host 3   |
+---------------------+-+---------------------+-+---------------------+
|                          Mac or Windows                             |
+---------------------------------------------------------------------+

特徴としては

  • 作業端末(Mac or Windows or Linux)上で Vagrant を動作させる
  • 各 Vagrant VM 同士はホスト OS のネットワークインターフェース上で疎通が取れる

です。

Vagrantfile の作成と host1,2,3 の起動

上記の3台の構成を下記の Vagrantfile で構築します。

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/vivid64"

  config.vm.define "host1" do |server|
    server.vm.network "private_network", ip: "192.168.33.11"
  end

  config.vm.define "host2" do |server|
    server.vm.network "private_network", ip: "192.168.33.12"
  end

  config.vm.define "host3" do |server|
    server.vm.network "private_network", ip: "192.168.33.13"
  end

  config.vm.provision :shell, inline: <<-SHELL
apt-get update
apt-get install -y libsqlite3-dev docker.io
curl -L git.io/weave -o /usr/local/bin/weave
chmod a+x /usr/local/bin/weave
  SHELL
end

vagrant コマンドを使って host1, host2, host3 を起動します。

$ vagrant up
$ vagrant ssh host1 # <--- host1 に SSH する場合
$ vagrant ssh host2 # <--- host2 に SSH する場合
$ vagrant ssh host3 # <--- host3 に SSH する場合

物理ノードまたがったコンテナ間で通信をする

weave でまず物理ノードをまたがったコンテナ間で通信をさせてみましょう。ここでは 上図の host1, host2 を使います。通常、物理ノードまたがっていると各々のホストで 稼働する Docker コンテナは通信し合えませんが weave を使うと通信しあうことが出 来ます。

まず weave が用いる Docker コンテナを稼働します。下記のように /16 でレンジを切って 更にそこからデフォルトのレンジを指定することが出来ます。

host1# weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.1.0/24
host1# eval $(weave env)
host2# weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.1.0/24 192.168.33.11
host2# eval $(weave env)

この状態で下記のようなコンテナが稼働します。

host1# docker ps
CONTAINER ID        IMAGE                        COMMAND                CREATED             STATUS              PORTS               NAMES
c55e96b4bdf9        weaveworks/weaveexec:1.4.0   "/home/weave/weavepr   4 seconds ago       Up 3 seconds                            weaveproxy
394382c9c5d9        weaveworks/weave:1.4.0       "/home/weave/weaver    5 seconds ago       Up 4 seconds                            weave

host1, host2 でそれぞれテスト用コンテナを稼働させます。名前を –name オプションで付けるのを 忘れないようにしてください。

host1# docker run --name a1 -ti ubuntu
host2# docker run --name a2 -ti ubuntu

どちらか一方から ping をもう一方に打ってみましょう。下記では a2 -> a1 の流れで ping を実行しています。

root@a2:/# ping 10.2.1.1 -c 3
PING 10.2.1.1 (10.2.1.1) 56(84) bytes of data.
64 bytes from 10.2.1.1: icmp_seq=1 ttl=64 time=0.316 ms
64 bytes from 10.2.1.1: icmp_seq=2 ttl=64 time=0.501 ms
64 bytes from 10.2.1.1: icmp_seq=3 ttl=64 time=0.619 ms

--- 10.2.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.316/0.478/0.619/0.127 ms

また docker コンテナを起動する時に指定した –name a1, –name a2 の名前で ping を実行してみましょう。これも weave の機能の1つで dns lookup が行えます。

root@b2:/# ping a1 -c 3
PING b1.weave.local (10.2.1.1) 56(84) bytes of data.
64 bytes from a1.weave.local (10.2.1.1): icmp_seq=1 ttl=64 time=1.14 ms
64 bytes from a1.weave.local (10.2.1.1): icmp_seq=2 ttl=64 time=0.446 ms
64 bytes from a1.weave.local (10.2.1.1): icmp_seq=3 ttl=64 time=0.364 ms

--- b1.weave.local ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.364/0.653/1.149/0.352 ms

結果から、異なる物理ノード(今回は VM)上で動作させた Docker コンテナ同士が通信し合えた ことがわかります。またコンテナ名の DNS 的は名前解決も可能になりました。

ダイナミックにネットワークをアタッチ・デタッチする

次に weave のネットワークを動的(コンテナがオンラインのまま)にアタッチ・デタッ チすることが出来るので試してみます。

最初に weave のネットワークに属さない a1-1 という名前のコンテナを作ります。 docker exec で IP アドレスを確認すると eth0, lo のインターフェースしか持っていない ことが判ります。

host1# C=$(docker run --name a1-1 -e WEAVE_CIDR=none -dti ubuntu)
host1# docker exec -it a1-1 ip a # <--- docker コンテナ内でコマンド実行
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
25: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:5/64 scope link
       valid_lft forever preferred_lft forever

では weave のネットワークを a1-1 コンテナにアタッチしてみましょう。

host1# weave attach $C
10.2.1.1
host1# docker exec -it a1-1 ip a
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
25: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:5/64 scope link
       valid_lft forever preferred_lft forever
27: ethwe: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast state UP group default qlen 1000
    link/ether aa:15:06:51:6a:3b brd ff:ff:ff:ff:ff:ff
    inet 10.2.1.1/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet6 fe80::a815:6ff:fe51:6a3b/64 scope link
       valid_lft forever preferred_lft forever

上記のようにインターフェース ethwe が付与され最初に指定したデフォルトのサブネッ ト上の IP アドレスが付きました。

次に weave ネットワークを複数アタッチしてみましょう。default, 10.2.2.0/24, 10.2.3.0/24 のネットワーク(サブネット)をアタッチします。

host1# weave attach net:default net:10.2.2.0/24 net:10.2.3.0/24 $C
10.2.1.1 10.2.2.1 10.2.3.1
root@vagrant-ubuntu-vivid-64:~# docker exec -it b3 ip a
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
25: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:5/64 scope link
       valid_lft forever preferred_lft forever
33: ethwe: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 9a:74:73:1b:24:a9 brd ff:ff:ff:ff:ff:ff
    inet 10.2.1.1/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet 10.2.2.1/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet 10.2.3.1/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet6 fe80::9874:73ff:fe1b:24a9/64 scope link
       valid_lft forever preferred_lft forever

結果、ethwe インターフェースに3つの IP アドレスが付与されました。 この様にダイナミックにコンテナに対して weave ネットワークをアタッチすることが出来ます。

コンテナ外部から情報を取得する

下記のようにコンテナを起動しているホスト上 (Vagrant VM) からコンテナの情報を取 得する事もできます。シンプルですがオーケストレーション・自動化を行う上で重要な機能に なりそうな予感がします。

host1# weave expose
10.2.1.1
host1# weave dns-lookup a2
10.2.1.128

ダイナミックに物理ノードを追加し weave ネットワークへ

物理ノード(今回の場合 vagrant vm)を追加し上記で作成した weave ネットワークへ参 加させることも可能です。なお、今回は上記の vagrant up の時点で追加分の vm (host3) を既に稼働させています。

host1 で新しい物理ノードを接続します。

host1# weave connect 192.168.33.12
host1# weave status targets
192.168.33.13
192.168.33.12

host3 で weave コンテナ・テストコンテナを起動します。 下記で指定している 192.168.33.11 は host1 の IP アドレスです。

host3# weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.1.0/24 192.168.33.11
host3# docker run --name a3 -ti ubuntu

host2 の a2 コンテナに ping を打ってみます。

roota3:/# ping a2 -c 3
PING a2.weave.local (10.2.1.128) 56(84) bytes of data.
64 bytes from a2.weave.local (10.2.1.128): icmp_seq=1 ttl=64 time=0.366 ms
64 bytes from a2.weave.local (10.2.1.128): icmp_seq=2 ttl=64 time=0.709 ms
64 bytes from a2.weave.local (10.2.1.128): icmp_seq=3 ttl=64 time=0.569 ms

host3 上の a3 コンテナが既存の weave ネットワークに参加し通信出来たことが確認 できました。

まとめと考察

コンフィギュレーションらしきモノを記述することなく Docker コンテナ間の通信 が出来ました。これは自動化する際に優位になるでしょう。また今回紹介したのは ‘weave net’ と呼ばれるモノですが他にも ‘weave scope’, ‘weave run’ といったモノ があります。

また Docker Swarm, Compose と組み合わせる構成も組めるようです。試してみたい方 がいましたら是非。

ですが結果、まだ weave をどう自分たちのサービスに組み込めるかは検討が付いてい ません。‘出来る’ と ‘運用できる’ が別物であることと、コンテナまわりのネットワー ク機能全般に理解して選定する必要がありそうです。