概要
以前はWeaveというツールを使ってマルチホストをまたいだコンテナ間通信ができるように構築しました。
Docker 1.9.0からVXLANという仮想でL2ネットワークを構築する技術を用い、Docker自身がマルチホストネットワークに対応したので、今度はそちらで構築してみます。
overlay networkのkernel supportが3.16以下も対応したのでkernelのアップデートなども不要になっています。
環境
- Ubuntu 14.04
- Docker 1.11.1
- etcd 2.3.4
IP | 役割 |
---|---|
192.168.33.10 | Dockerホスト1 |
192.168.33.11 | Dockerホスト2 |
192.168.33.12 | etcd |
各マシンにDockerをインストールした状態から始めます。
事前準備
etcd
etcdを使えるようにします。Github Releasesにインストール方法が書いてあります。
$ curl -L https://github.com/coreos/etcd/releases/download/v2.3.4/etcd-v2.3.4-linux-amd64.tar.gz -o etcd-v2.3.4-linux-amd64.tar.gz $ tar xzvf etcd-v2.3.4-linux-amd64.tar.gz $ cd etcd-v2.3.4-linux-amd64
ポート
以下のポートを解放する必要があります。FWなどを設定している場合は解放しておいてください。
ポート | プロトコル | 役割 |
---|---|---|
2379 | TCP | etcdで使用。クライアントからのリクエスト用 |
2380 | TCP | etcdで使用。peerとのコミュニケーション用 |
4789 | UDP | overlayドライバ |
7946 | UDP・TCP | overlayドライバ |
2376 | TCP | Docker間通信 |
動作確認
etcd側のサーバを起動します。クライアントから疎通できるよう、オプションを設定します。
$ ./etcd -listen-client-urls "http://192.168.33.12:2379" -advertise-client-urls "http://192.168.33.12:2379"
クライアントから疎通できるか確認します。
$ curl -L http://192.168.33.12:2379/version {"etcdserver":"2.3.4","etcdcluster":"2.3.0"}
大丈夫ですね。
マルチホストネットワークの作成
overlayネットワークを作成します。
/etc/default/docker
各Dockerホストで以下を追記
DOCKER_OPTS="--cluster-store=etcd://192.168.33.12:2379 --cluster-advertise=eth1:2376"
パラメータの説明は以下。
項目 | 説明 | 例 |
---|---|---|
--cluster-store | backing datastoreの指定。etcdのホストを指定 | etcd://192.168.33.12:2379 |
--cluster-advertise | Docker間通信用に公開。自ホストのIP | eth1:2376 |
追記したら再起動
$ sudo service docker restart
作成
$ docker network create -d overlay overlay01 342e00d95e404003567a85a56dff6475cc5fdd2b48bc58bb2b64a5dc552d4c4f
作成されたネットワークは、すべてのDockerホスト内で共有されるため、1つのホストだけで実行すればOKです。
確認
$ docker network ls NETWORK ID NAME DRIVER 5139aed8a8ec bridge bridge 0422a42ed7a2 host host 35c2fe210767 none null 342e00d95e40 overlay01 overlay
別のDockerホストからみてます。
$ docker network ls NETWORK ID NAME DRIVER ae25358877fa bridge bridge 50ef65cf8246 host host 50ff46338a47 none null 342e00d95e40 overlay01 overlay
overlayネットワークのみ同じIDになっている事がわかります。
疎通確認
各Dockerホスト上にコンテナを立てます。
ホスト1
$ docker run -d --name nginx01 nginx
ホスト2
$ docker run -d --name nginx02 nginx
先ほどのネットワークに接続します。
ホスト1
$ docker network connect overlay01 nginx01
ホスト2
$ docker network connect overlay01 nginx02
docker network inspectで確認します。
$ docker network inspect overlay01 [ { "Name": "overlay01", "Id": "342e00d95e404003567a85a56dff6475cc5fdd2b48bc58bb2b64a5dc552d4c4f", "Scope": "global", "Driver": "overlay", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "10.0.0.0/24", "Gateway": "10.0.0.1/24" } ] }, "Internal": false, "Containers": { "a486799d5bac7863a5b16770a090ae12afc55e1070455b643be9cae896531f27": { "Name": "nginx02", "EndpointID": "f36f818f92b583eed4f856407cc98a18880cc6f6d3b864e5612b0555e9d33795", "MacAddress": "02:42:0a:00:00:03", "IPv4Address": "10.0.0.3/24", "IPv6Address": "" }, "ep-b8e39fc8b636b66e8efdab5ae28b679c6e7c19d2be0888c2863db36c8dff3ab5": { "Name": "nginx01", "EndpointID": "b8e39fc8b636b66e8efdab5ae28b679c6e7c19d2be0888c2863db36c8dff3ab5", "MacAddress": "02:42:0a:00:00:02", "IPv4Address": "10.0.0.2/24", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
2つとも接続されていますね。
コンテナの中に入って疎通できるか確認します。
$ docker exec -it nginx01 bash root@8711a2328e22:/# ping nginx02 PING nginx02 (10.0.0.3): 56 data bytes 64 bytes from 10.0.0.3: icmp_seq=0 ttl=64 time=0.426 ms 64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.614 ms
大丈夫でした。お疲れ様でした。
その他
failed to parse pool request for address space
Error response from daemon: failed to parse pool request for address space "GlobalDefault" pool "" subpool "": cannot find address space GlobalDefault (most likely the backing datastore is not configured)
というエラーが出る場合、kvsとの疎通がうまく行っていないです。
Destination Host Unreachable
pingした時に
92 bytes from b9eba6d2bba0 (10.0.0.3): Destination Host Unreachable 92 bytes from b9eba6d2bba0 (10.0.0.3): Destination Host Unreachable 92 bytes from b9eba6d2bba0 (10.0.0.3): Destination Host Unreachable
となってしまう場合、僕の場合はVagrantで構築していてマシンのホスト名が被っていたためこの問題が起きました。
/var/log/upstart/docker.log
に以下の様なログが出ています。
ime="2016-05-16T01:37:18.887050874Z" level=error msg="2016/05/16 01:37:18 [ERR] memberlist: Conflicting address for vagrant-ubuntu-trusty-64. Mine: 192.168.33.10:7946 Theirs: 192.168.33.11:7946\n" time="2016-05-16T01:37:18.887163246Z" level=error msg="2016/05/16 01:37:18 [ERR] serf: Node name conflicts with another node at 192.168.33.11:7946. Names must be unique! (Resolution enabled: true)\n"
Dockerでクラスタを構築する場合、ホスト名は必ずユニークにしましょう。