複数のDockerサーバで独自ネットワークを構築する「Weave」を試す!

Dockerはコンテナ型の仮想化ソフトウェアで、一台のサーバの中にコンテナを複数立ち上げることができます。そのためDockerサーバ1台で何でもこなせそうに思いますが、やはり大きなシステムになると複数のサーバ内で動作するDockerコンテナ同士を連携させたいと思うのではないでしょうか。

そうなると問題になりそうなのがネットワークです。リンクを使う方法もありますが、より大きなネットワーク構造を作り上げるのにはWeaveが使えそうです。WeaveはDockerコンテナ向けの仮想化ネットワークソフトウェアになります。

用意するもの

Dockerが動けば良いのですが、他にも幾つか必要なのでCoreOSは向かなそうです。今回は Ubuntu Server 14.04 LTS 64bit を使っています。さくらのクラウドでサーバを立ち上げる際に、アーカイブとして Ubuntu Server 14.04 LTS 64bit を選択します。今回はそのサーバを2台用意しました。

Ubuntu 14.04 LTSを2台用意しています

サーバに接続、Dockerのインストール

まずはサーバに接続します。

$ ssh ubuntu@server_ip_address

server_ip_address は立ち上がったサーバのものに読み替えてください。接続したらDockerをインストールします。

$ sudo apt-get update
$ apt-get install docker.io

これで準備は完了です。

Weaveのインストール

weaveのインストールはとても簡単で、次のコマンドを打つだけです。

$ sudo wget -O /usr/local/bin/weave \
  https://raw.githubusercontent.com/zettio/weave/master/weaver/weave
$ sudo chmod a+x /usr/local/bin/weave

これで完了です。

1台目のサーバで実行

まず1台目のサーバ(サーバ1とします)でWeaveを立ち上げます。root権限で行ってください。

# weave launch 10.0.0.1/16

完了したら、DockerでUbuntuを立ち上げます。

# C=$(weave run 10.0.1.1/24 -t -i ubuntu)

これで $C の中にコンテナIDが入ります。

2台目のサーバで実行

次に2台目のサーバ(サーバ2とします)です。こちらはサーバ1のWeaveに接続する指定を行います。

# weave launch 10.0.0.2/16 server1_ip_address

server1_ip_address はサーバ1のIPアドレスになります。終わったらサーバ1と同じようにDockerコンテナを立ち上げます。

# C=$(weave run 10.0.1.2/24 -t -i ubuntu)

サーバ1からサーバ2へpingを打つ

ではサーバ1のDockerコンテナからサーバ2のDockerコンテナへの疎通確認を行います。

# docker attach $C

root@97a26833e25f:/# ping -c 1 -q 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.

--- 10.0.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 16.272/16.272/16.272/0.000 ms

ちゃんとpingが飛んで、疎通確認ができています。コンテナを抜ける場合は Ctrl + P / Ctrl + Q で行ってください。この逆にサーバ2からサーバ1への疎通も可能です。

# docker attach $C
root@fc91dc9c2cab:/# 
root@fc91dc9c2cab:/# ping -c 1 -q 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.

--- 10.0.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 14.521/14.521/14.521/0.000 ms

仮想ネットワークが構築されて、サーバ1とサーバ2のコンテナ同士がつながっているのが分かります。

アプリケーションの隔離

では次にアドレスを分けてみます。

# D=$(weave run 10.0.2.1/24 -t -i ubuntu) # サーバ1
# D=$(weave run 10.0.2.2/24 -t -i ubuntu) # サーバ2

このように10.0.1.xと10.0.2.xで分離します。この場合はもちろんパケットは通りません。

# docker attach $D
root@1b001316fcf8:/# 
root@1b001316fcf8:/# ping -c 1 -q 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.

--- 10.0.2.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.244/1.244/1.244/0.000 ms
root@1b001316fcf8:/# ping -c 1 -q 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.

--- 10.0.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

サーバ1から実行した場合、10.0.2.2へのpingは通っていますが、10.0.1.1へのpingは100%ロスしています。当たり前ですが仮想ネットワークでもきちんと動いています。

ホストネットワークからのアクセス

デフォルトのままですと、ホストであってもコンテナのネットワークとはつながることはできません。

# ping 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.

--- 10.0.1.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms

ですが、exposeオプションによって解放ができます。

# weave expose 10.0.1.102/24
# ping 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=0.050 ms

これはもちろんサーバ内だけでなく、同じ仮想ネットワークにつながっている他のコンテナでも接続できます。

# ping 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=2.05 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.798 ms

これまではコンテナのポート単位で解放する方法しかなかったのですが、Weaveを使うとほぼサーバと同じように見えてしまいます。複数台サーバの中で多数のコンテナを立ち上げて、それらを必要に応じて仮想ネットワークで組み上げる、そんな大型なDocker活用が考えられそうな面白いソフトウェアですね。

zettio/weave

おしらせ