Dockerでweaveをつかったマルチホストネットワーキング

Dockerを使ったマルチホストのネットワークは、いくつかあるなか、weaveを検証したので、記事にしました。

執筆時の２０１６年５月時点で、docker+consul+swarm(+vxlan)による検証を行いましたが、vxlanが作成されないなど現象がでてきて、内部ネットワーク（１０．０．０．ｘ/16）通信ができませんでした。

（時間があれば別途記事化しようと思います）

今回参照させてもらった記事
[マルチホストDockerネットワーキング（weave）](http://qiita.com/nmatsui/items/a7caa5a3840b8c920124)
の異なるバリエーションとして位置づけています。
若干コマンドの仕様変更などもあり、見た目がかわりますが、わかりにくいところは若干補足の意味で追記しています。

#1.検証環境
某有名なサイトのクラウドサービスを利用して、検証用に以下のVirutalMachineを起動を立ち上げた。

##1.1　ホスト一覧

|  | hostname | private IP(eth0) |public IP(eth0:0)|
|:--:|:--|:--|:--|
|ホスト１|test01|172.31.13.144|x.x.x.x|
|ホスト2|test02|172.31.27.114|y.y.y.y|

ホスト1とホスト2は別VLAN上で接続されている。

##1.2 ホストの各種バージョン
ホスト１とホスト２の各種バージョンは以下の通り。

|  | バージョン | 
|:--:|:--|
|distribution| CentOS 7 Linux |
|kernel|3.10.0-327.el7.x86_64|
|docker|Docker version 1.11.1, build 5604cbe|
|weave|weave script 1.5.1|
|GO|go1.4.2 linux/amd64|

Dockerのインストール方法は
[Installation on CentOS（英文）](https://docs.docker.com/engine/installation/linux/centos/)
に詳しい内容があります

##1.3 ホストが使用するポート番号
使用するポート番号は以下の通り。

|  |種類|ポート番号| 
|:--:|:--|--:|
|No.1| udp/tcp|6783|

イメージ図はこちら
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/96347/0d284aff-cec1-9168-5e0a-d7e7903e4c3b.png)


#2.準備

すべてのホストで以下の作業を実施する。

##2.1 必要パッケージのインストール

```text:必要パッケージのインストール
root@test01:~# yum update
root@test01:~# yum -y install iptables2 bridge-utils curl
```

##2.2 GOのインストール

```text:golangのインストール
root@test01:~# yum -y install golang
root@test01:~# go version
go version go1.4.2 linux/amd64
```

詳細はこちら
[Go言語をyumで入れる](http://qiita.com/okataitai/items/4beaf74d284f5bdfae4b)

##2.3 Dockerのインストール

```text:dockerのインストール
root@test01:~# yum -y install docker-engine
root@test01:~# docker version
Client:
 Version:      1.11.1
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   5604cbe
 Built:        Wed Apr 27 00:34:42 2016
 OS/Arch:      linux/amd64
```

```text:dockerの起動
root@test01:~# systemctl start docker.service
```

```text:ネットワークの確認
root@test01:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 06:59:6e:00:15:e4 brd ff:ff:ff:ff:ff:ff
    inet 172.31.13.144/21 brd 172.31.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 153.122.99.4/21 brd 153.122.103.255 scope global eth0:0
       valid_lft forever preferred_lft forever
    inet6 fe80::459:6eff:fe00:15e4/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:9a:ec:5f:e5 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
```


#2.4 weaveのインストール

```text:weaveのインストール
root@test01:~# wget -O /usr/local/bin/weave https://github.com/zettio/weave/releases/download/latest_release/weave
root@test01:~# chmod a+x /usr/local/bin/weave
```

#3.weaveクラスタの起動
weaveクラスタに参加するある一つのノード（今回はホスト１）でweaveを起動する。
サーバーの役割になるのが１つ、他はエージェント的役割になる。

##3.1 ホスト１

```text:weave起動
root@test01:~# weave launch
Unable to find image 'weaveworks/weaveexec:1.5.1' locally
1.5.1: Pulling from weaveworks/weaveexec
c52e3ed763ff: Pull complete 
e3ee3ebaaa7a: Pull complete 
9d94a316b7bf: Pull complete 
6e4a78881788: Pull complete 
3bd2811e2c9a: Pull complete 
886cab1ed359: Pull complete 
1ccbb1f1a1e7: Pull complete 
e7efc9eedb90: Pull complete 
b8e5c537a426: Pull complete 
Digest: sha256:91ff928a6e4c76869ce71053db900fa142d0cfa965f1502df8554530a65ca188
Status: Downloaded newer image for weaveworks/weaveexec:1.5.1
WARNING: existing iptables rule

    '-A FORWARD -j REJECT --reject-with icmp-host-prohibited'

will block name resolution via weaveDNS - please reconfigure your firewall.
Unable to find image 'weaveworks/weavedb:latest' locally
latest: Pulling from weaveworks/weavedb
c1d3010baf39: Pulling fs layer
c1d3010baf39: Verifying Checksum
c1d3010baf39: Download complete
c1d3010baf39: Pull complete
Digest: sha256:0790ab1a704d50eeae38468a9c95a710e044d7666d7dba5e0331f96ebc34aab8
Status: Downloaded newer image for weaveworks/weavedb:latest
Unable to find image 'weaveworks/weave:1.5.1' locally
1.5.1: Pulling from weaveworks/weave
91aaa506766f: Pulling fs layer
c7e848dbefae: Pulling fs layer
67966b7f321c: Pulling fs layer
908e601e8e38: Pulling fs layer
908e601e8e38: Waiting
91aaa506766f: Verifying Checksum
91aaa506766f: Download complete
67966b7f321c: Verifying Checksum
67966b7f321c: Download complete
c7e848dbefae: Verifying Checksum
c7e848dbefae: Download complete
908e601e8e38: Verifying Checksum
908e601e8e38: Download complete
91aaa506766f: Pull complete
c7e848dbefae: Pull complete
67966b7f321c: Pull complete
908e601e8e38: Pull complete
Digest: sha256:30fb6aa8c11e599683d5d21d0d069120ff1c222c1f97982c46e79b8bdbe17241
Status: Downloaded newer image for weaveworks/weave:1.5.1
Unable to find image 'weaveworks/plugin:1.5.1' locally
1.5.1: Pulling from weaveworks/plugin
c52e3ed763ff: Already exists
e3ee3ebaaa7a: Already exists
9d94a316b7bf: Already exists
6e4a78881788: Already exists
3bd2811e2c9a: Already exists
886cab1ed359: Already exists
1ccbb1f1a1e7: Already exists
e7efc9eedb90: Already exists
b8e5c537a426: Already exists
d7b5bdab083d: Pulling fs layer
d7b5bdab083d: Verifying Checksum
d7b5bdab083d: Download complete
d7b5bdab083d: Pull complete
Digest: sha256:a378027cf4730b63f0c68b556ab8216f7c90a256bfce53bce8bbe9d309daeb5f
Status: Downloaded newer image for weaveworks/plugin:1.5.1
root@test01:~# 
```
この段階でweaveというブリッジが作成される。
またweave用dockerコンテナが自動で立ち上がり、docker0とweaveにvethペアが差し込まれる。weave用dockerコンテナでは、weaverプロセスが起動している。

このときに、
>WARNING: existing iptables rule
    '-A FORWARD -j REJECT --reject-with icmp-host-prohibited'
will block name resolution via weaveDNS - please reconfigure your firewall.

のエラーが出たら、iptablesより削除しておかないとPINGが通らない。
`iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited`
と入力して削除する。

```text:ホスト１のネットワークの状態（起動後）
root@test01:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 06:59:6e:00:15:e4 brd ff:ff:ff:ff:ff:ff
    inet 172.31.13.144/21 brd 172.31.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 153.122.99.4/21 brd 153.122.103.255 scope global eth0:0
       valid_lft forever preferred_lft forever
    inet6 fe80::459:6eff:fe00:15e4/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:9a:ec:5f:e5 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
4: datapath: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UNKNOWN 
    link/ether fe:84:77:e8:eb:5d brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc84:77ff:fee8:eb5d/64 scope link 
       valid_lft forever preferred_lft forever
5: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UP 
    link/ether 72:1f:cd:e9:07:33 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::701f:cdff:fee9:733/64 scope link 
       valid_lft forever preferred_lft forever
6: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN 
    link/ether 06:1c:d0:09:93:7d brd ff:ff:ff:ff:ff:ff
8: vethwe-datapath@vethwe-bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast master datapath state UP qlen 1000
    link/ether 1a:51:b3:21:b6:f1 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::1851:b3ff:fe21:b6f1/64 scope link 
       valid_lft forever preferred_lft forever
9: vethwe-bridge@vethwe-datapath: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast master weave state UP qlen 1000
    link/ether 3a:66:a8:29:94:52 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::3866:a8ff:fe29:9452/64 scope link 
       valid_lft forever preferred_lft forever
root@test01:~# brctl show docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02429aec5fe5	no		
root@test01:~#  brctl show weave
bridge name	bridge id		STP enabled	interfaces
weave		8000.721fcde90733	no		vethwe-bridge
```

```text:ホスト１で立ち上がったweave用コンテナ
root@test01:~# docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
5fdfa5d771a1        weaveworks/plugin:1.5.1      "/home/weave/plugin"     2 minutes ago       Up 2 minutes                            weaveplugin
9800407af969        weaveworks/weaveexec:1.5.1   "/home/weave/weavepro"   3 minutes ago       Up 2 minutes                            weaveproxy
83e19416b6a4        weaveworks/weaveexec:1.5.1   "/bin/false"             3 minutes ago       Created                                 weavevolumes-1.5.1
4340cecb92e1        weaveworks/weave:1.5.1       "/home/weave/weaver -"   3 minutes ago       Up 3 minutes                            weave
4c5cb99ad7a5        weaveworks/weavedb           "data-only"              3 minutes ago       Created                                 weavedb
```

##3.2 ホスト２

次にホスト２でweaveを起動する。この際、最初にweaveを立ち上げたホストのIPアドレスを指定することで、weaveクラスタに参加することができる。

```text:クラスタメンバーのIPアドレスを指定してweave起動
root@test01:~# weave launch 172.31.13.144
Unable to find image 'weaveworks/weaveexec:1.5.1' locally
1.5.1: Pulling from weaveworks/weaveexec
...
```

ホスト１と同様にweaveブリッジが作成され、weaveコンテナが立ち上がる。
ホスト１と同様iptableのエラーメッセージの対応を行う。

```text:ホスト２のネットワークの状態（起動後）
root@test02:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 06:9c:20:00:20:53 brd ff:ff:ff:ff:ff:ff
    inet 172.31.27.114/21 brd 172.31.31.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 153.122.99.4/21 brd 153.122.103.255 scope global eth0:0
       valid_lft forever preferred_lft forever
    inet6 fe80::49c:20ff:fe00:2053/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:cc:c1:48:93 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
4: datapath: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UNKNOWN 
    link/ether d2:84:50:d5:5e:ab brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d084:50ff:fed5:5eab/64 scope link 
       valid_lft forever preferred_lft forever
5: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UP 
    link/ether de:54:76:ab:4f:e9 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dc54:76ff:feab:4fe9/64 scope link 
       valid_lft forever preferred_lft forever
6: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN 
    link/ether 22:bf:fe:a5:26:a0 brd ff:ff:ff:ff:ff:ff
8: vethwe-datapath@vethwe-bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast master datapath state UP qlen 1000
    link/ether 0a:3c:9f:ac:47:bd brd ff:ff:ff:ff:ff:ff
    inet6 fe80::83c:9fff:feac:47bd/64 scope link 
       valid_lft forever preferred_lft forever
9: vethwe-bridge@vethwe-datapath: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast master weave state UP qlen 1000
    link/ether 82:4a:41:ff:a2:59 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::804a:41ff:feff:a259/64 scope link 
       valid_lft forever preferred_lft forever
root@test02:~# brctl show docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.0242ccc14893	no		
root@test02:~#  brctl show weave
bridge name	bridge id		STP enabled	interfaces
weave		8000.de5476ab4fe9	no		vethwe-bridge
```

```text:ホスト2で立ち上がったweave用コンテナ
root@test02:~# docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
52f5367ccd91        weaveworks/plugin:1.5.1      "/home/weave/plugin"     5 minutes ago       Up 5 minutes                            weaveplugin
694d4665f366        weaveworks/weaveexec:1.5.1   "/home/weave/weavepro"   5 minutes ago       Up 5 minutes                            weaveproxy
6c9e84329487        weaveworks/weaveexec:1.5.1   "/bin/false"             5 minutes ago       Created                                 weavevolumes-1.5.1
918e14fc1142        weaveworks/weave:1.5.1       "/home/weave/weaver -"   5 minutes ago       Up 5 minutes                            weave
2f0cf5db8704        weaveworks/weavedb           "data-only"              6 minutes ago       Created                                 weavedb
```

#4.weaveクラスタの状態

`weave status`と`weave report` でweaveクラスタの状態が確認できる。


```text:weaveクラスタの状態
root@test01:~#  weave status

        Version: 1.5.1 (up to date; next check at 2016/05/24 17:27:23)

        Service: router
       Protocol: weave 1..2
           Name: 72:1f:cd:e9:07:33(test01)
     Encryption: disabled
  PeerDiscovery: enabled
        Targets: 0
    Connections: 1 (1 established)
          Peers: 2 (with 2 established connections)
 TrustedSubnets: none

        Service: ipam
         Status: idle
          Range: 10.32.0.0-10.47.255.255
  DefaultSubnet: 10.32.0.0/12

        Service: dns
         Domain: weave.local.
       Upstream: 172.31.10.160, 180.222.191.16, 180.222.191.15
            TTL: 1
        Entries: 0

        Service: proxy
        Address: unix:///var/run/weave/weave.sock

        Service: plugin
     DriverName: weave

root@test01:~# weave status connections
<- 172.31.27.114:51531   established fastdp de:54:76:ab:4f:e9(test02)
root@test01:~# weave status peers
72:1f:cd:e9:07:33(test01)
   <- 172.31.27.114:51531   de:54:76:ab:4f:e9(test02) established
de:54:76:ab:4f:e9(test02)
   -> 172.31.13.144:6783    72:1f:cd:e9:07:33(test01) established
root@test01:~# weave report
{
    "Version": "1.5.1",
    "VersionCheck": {
        "Enabled": true,
        "NewVersion": "",
        "NextCheckAt": "2016-05-24T17:27:23.32623158Z"
    },
    "Router": {
        "Protocol": "weave",
        "ProtocolMinVersion": 1,
        "ProtocolMaxVersion": 2,
        "Encryption": false,
        "PeerDiscovery": true,
        "Name": "72:1f:cd:e9:07:33",
        "NickName": "test01",
        "Port": 6783,
        "Peers": [
            {
                "Name": "72:1f:cd:e9:07:33",
                "NickName": "test01",
                "UID": 1232692811381818389,
                "ShortID": 1212,
                "Version": 2,
                "Connections": [
                    {
                        "Name": "de:54:76:ab:4f:e9",
                        "NickName": "test02",
                        "Address": "172.31.27.114:51531",
                        "Outbound": false,
                        "Established": true
                    }
                ]
            },
            {
                "Name": "de:54:76:ab:4f:e9",
                "NickName": "test02",
                "UID": 4984887491259103282,
                "ShortID": 2957,
                "Version": 2,
                "Connections": [
                    {
                        "Name": "72:1f:cd:e9:07:33",
                        "NickName": "test01",
                        "Address": "172.31.13.144:6783",
                        "Outbound": true,
                        "Established": true
                    }
                ]
            }
        ],
        "UnicastRoutes": [
            {
                "Dest": "72:1f:cd:e9:07:33",
                "Via": "00:00:00:00:00:00"
            },
            {
                "Dest": "de:54:76:ab:4f:e9",
                "Via": "de:54:76:ab:4f:e9"
            }
        ],
        "BroadcastRoutes": [
            {
                "Source": "72:1f:cd:e9:07:33",
                "Via": [
                    "de:54:76:ab:4f:e9"
                ]
            }
        ],
        "Connections": [
            {
                "Address": "172.31.27.114:51531",
                "Outbound": false,
                "State": "established",
                "Info": "fastdp de:54:76:ab:4f:e9(test02)"
            }
        ],
        "Targets": null,
        "OverlayDiagnostics": {
            "fastdp": {
                "Vports": [
                    {
                        "ID": 0,
                        "Name": "datapath",
                        "TypeName": "internal"
                    },
                    {
                        "ID": 1,
                        "Name": "vethwe-datapath",
                        "TypeName": "netdev"
                    },
                    {
                        "ID": 2,
                        "Name": "vxlan-6784",
                        "TypeName": "vxlan"
                    }
                ],
                "Flows": []
            },
            "sleeve": null
        },
        "TrustedSubnets": [],
        "Interface": "datapath (via ODP)",
        "CaptureStats": {
            "FlowMisses": 52
        },
        "MACs": null
    },
    "IPAM": {
        "Paxos": null,
        "Range": "10.32.0.0-10.47.255.255",
        "RangeNumIPs": 1048576,
        "DefaultSubnet": "10.32.0.0/12",
        "Entries": null,
        "PendingClaims": null,
        "PendingAllocates": null
    },
    "DNS": {
        "Domain": "weave.local.",
        "Upstream": [
            "172.31.10.160",
            "180.222.191.16",
            "180.222.191.15"
        ],
        "Address": "172.17.0.1:53",
        "TTL": 1,
        "Entries": null
    }
}
```

weave reportの詳しい内容はこちら
[weave/site/troubleshooting.md](https://github.com/weaveworks/weave/blob/master/site/troubleshooting.md)


#5.Dockerコンテナ起動

weaveコマンドを用い、以下のようなコンテナを立ち上げる。

|ホスト|コンテナ名|IPアドレス|備考| 
|:--:|:--|:--:|:--:|
|ホスト１| httpd |192.168.99.10/24|apache2を起動|
|ホスト１| client1 |192.168.99.11/24||
|ホスト2| client2 |192.168.99.21/24||

##5.1 ホスト１

`weave run`した後に`weave expose`することで、静的routeとNATルールが追加される。
ただし外部からコンテナ上のサービスにアクセスする場合、**-pオプション**でポートフォワードしなければならないが、docker0に紐付けられたIPアドレスに関する設定がiptablesに書かれているとパケットが届かないため、iptablesから当該ルールを削除する。

> これは非常に煩雑な手順なので、本来もっと良い方法があるのかもしれない。。。

```text:httpdコンテナ起動
root@test01:~# HTTPD=$(weave run 192.168.99.10/24 -d -i -p 80:80 -t ubuntu:latest /bin/bash)
root@test01:~# ping 192.168.99.10
PING 192.168.99.10 (192.168.99.10) 56(84) bytes of data.
^C
--- 192.168.99.10 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms

root@test01:~# weave expose 192.168.99.10/24
192.168.99.10
root@test01:~# ping 192.168.99.10
PING 192.168.99.10 (192.168.99.10) 56(84) bytes of data.
64 bytes from 192.168.99.10: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 192.168.99.10: icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from 192.168.99.10: icmp_seq=3 ttl=64 time=0.047 ms
^C
--- 192.168.99.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.047/0.056/0.074/0.013 ms
```

```text:client1コンテナ起動
root@test01:~# CLIENT1=$(weave run 192.168.99.11/24 -d -i -t ubuntu:latest /bin/bash)
root@test01:~# weave expose 192.168.99.11/24
192.168.99.11
```

```text:iptablesのルール削除
root@test01:~# iptables-save | grep `docker inspect --format="{{.NetworkSettings.IPAddress}}" $HTTPD`
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT


root@test01:~# iptables-save | grep `docker inspect --format="{{.NetworkSettings.IPAddress}}" $HTTPD`
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT

root@test01:~# iptables -t nat -D POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
root@test01:~# iptables -t nat -D DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
root@test01:~# iptables -D DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
```

iptableの詳細を知りたいかたはこちら
[コピペから脱出！iptablesの仕組みを理解して環境に合わせた設定をしよう](http://oxynotes.com/?p=6361)


```text:ホスト１のネットワーク状態
root@test01:~# brctl show docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02429aec5fe5	no		veth483c8f2
							vethd470fff
[root@test01:~# brctl show weave
bridge name	bridge id		STP enabled	interfaces
weave		8000.721fcde90733	no		vethwe-bridge
							vethwepl3947
							vethwepl4633
root@test01:~#  ip route show
default via 172.31.15.254 dev eth0 
153.122.96.0/21 dev eth0  proto kernel  scope link  src 153.122.99.4 
169.254.0.0/16 dev eth0  scope link  metric 1002 
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1 
172.31.8.0/21 dev eth0  proto kernel  scope link  src 172.31.13.144 
192.168.99.0/24 dev weave  proto kernel  scope link  src 192.168.99.10 

root@test01:~# iptables-save
# Generated by iptables-save v1.4.21 on Tue May 24 20:45:39 2016
*nat
:PREROUTING ACCEPT [2:656]
:INPUT ACCEPT [2:656]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DOCKER - [0:0]
:WEAVE - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -j WEAVE
-A DOCKER -i docker0 -j RETURN
-A WEAVE -s 192.168.99.0/24 -d 224.0.0.0/4 -j RETURN
-A WEAVE ! -s 192.168.99.0/24 -d 192.168.99.0/24 -j MASQUERADE
-A WEAVE -s 192.168.99.0/24 ! -d 192.168.99.0/24 -j MASQUERADE
COMMIT
# Completed on Tue May 24 20:45:39 2016
# Generated by iptables-save v1.4.21 on Tue May 24 20:45:39 2016
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [93:90389]
:DOCKER - [0:0]
:DOCKER-ISOLATION - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -j ACCEPT
-A INPUT -p udp -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -d 172.17.0.1/32 -i docker0 -p tcp -m tcp --dport 6783 -j DROP
-A INPUT -d 172.17.0.1/32 -i docker0 -p udp -m udp --dport 6783 -j DROP
-A INPUT -d 172.17.0.1/32 -i docker0 -p udp -m udp --dport 6784 -j DROP
-A INPUT -i docker0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i docker0 -p tcp -m tcp --dport 53 -j ACCEPT
-A FORWARD -i docker0 -o weave -j DROP
-A FORWARD -j DOCKER-ISOLATION
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -i weave -o weave -j ACCEPT
-A DOCKER-ISOLATION -j RETURN
COMMIT
# Completed on Tue May 24 20:45:39 2016
```

```text:Dockerコンテナの起動状況
root@test01:~# docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                NAMES
963a338fe903        ubuntu:latest                "/bin/bash"              6 minutes ago       Up 6 minutes                             awesome_noyce
8d6a495ea1e0        ubuntu:latest                "/bin/bash"              8 minutes ago       Up 8 minutes        0.0.0.0:80->80/tcp   insane_keller
5fdfa5d771a1        weaveworks/plugin:1.5.1      "/home/weave/plugin"     27 minutes ago      Up 27 minutes                            weaveplugin
9800407af969        weaveworks/weaveexec:1.5.1   "/home/weave/weavepro"   28 minutes ago      Up 28 minutes                            weaveproxy
83e19416b6a4        weaveworks/weaveexec:1.5.1   "/bin/false"             28 minutes ago      Created                                  weavevolumes-1.5.1
4340cecb92e1        weaveworks/weave:1.5.1       "/home/weave/weaver -"   28 minutes ago      Up 28 minutes                            weave
4c5cb99ad7a5        weaveworks/weavedb           "data-only"              28 minutes ago      Created                                  weavedb
root@test01:~# weave ps
weave:expose 72:1f:cd:e9:07:33 192.168.99.10/24
963a338fe903 c2:0e:89:6a:b9:bf 192.168.99.11/24
8d6a495ea1e0 b6:55:46:0e:16:43 192.168.99.10/24
```

###5.1.1 httpdコンテナ

各コンテナには、docker0ブリッジにつながっているeth0インタフェースとweaveブリッジにつながっているethweインタフェースが差し込まれている。
また192.168.99.0/24のパケットとマルチキャストパケットがethwe経由で送信されるように静的routeが設定されている。

```text:httpdコンテナのネットワーク
root@test01:~# docker attach $HTTPD
root@8d6a495ea1e0:/# 
root@8d6a495ea1e0:/# 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
10: eth0@if11: <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 link-netnsid 0
    inet 172.17.0.2/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
12: ethwe@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b6:55:46:0e:16:43 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.99.10/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet6 fe80::b455:46ff:fe0e:1643/64 scope link 
       valid_lft forever preferred_lft forever
root@8d6a495ea1e0:/# ip route show
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  proto kernel  scope link  src 172.17.0.2 
192.168.99.0/24 dev ethwe  proto kernel  scope link  src 192.168.99.10 
224.0.0.0/4 dev ethwe  scope link  mtu lock 1410
```

`ip addr show`コマンドで`bash: ip: command not found`と表示されたら、`apt-get update`をして必要なパッケージやモジュールをインストールしてください。
ipコマンドのパッケージは、`apt-get -y install iproute`です。


```text:apache2のインストール
root@8d6a495ea1e0:/# apt-get install apache2 -y
root@8d6a495ea1e0:/# apachectl start
```

###5.1.2 client1コンテナ

```text:client1コンテナのネットワーク
root@test01:~# docker attach $CLIENT1
root@963a338fe903:/# 
root@963a338fe903:/# ip addr show
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
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever
16: ethwe@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast state UP group default qlen 1000
    link/ether c2:0e:89:6a:b9:bf brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.99.11/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet6 fe80::c00e:89ff:fe6a:b9bf/64 scope link 
       valid_lft forever preferred_lft forever
```

```text:curlのインストール
root@963a338fe903:/# apt-get install curl -y
```

#5.2 ホスト２

```text:client2コンテナ起動
root@test02:~# CLIENT2=$(weave run 192.168.99.21/24 -d -i -t ubuntu:latest /bin/bash)
root@test02:~# weave expose 192.168.99.21/24
```

```text:ホスト２のネットワーク状態

root@test02:~# brctl show docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.0242ccc14893	no		veth24d5d04
root@test02:~# brctl show weave
bridge name	bridge id		STP enabled	interfaces
bridge name	bridge id		STP enabled	interfaces
weave		8000.de5476ab4fe9	no		vethwe-bridge
							vethwepl4363
root@test02:~# ip route show
default via 172.31.31.254 dev eth0 
153.122.96.0/21 dev eth0  proto kernel  scope link  src 153.122.99.4 
169.254.0.0/16 dev eth0  scope link  metric 1002 
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1 
172.31.24.0/21 dev eth0  proto kernel  scope link  src 172.31.27.114 
192.168.99.0/24 dev weave  proto kernel  scope link  src 192.168.99.21 
```

```text:Dockerコンテナの起動状況
root@test02:~# docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
00bf6e9f66f1        ubuntu:latest                "/bin/bash"              3 minutes ago       Up 3 minutes                            tiny_panini
52f5367ccd91        weaveworks/plugin:1.5.1      "/home/weave/plugin"     About an hour ago   Up About an hour                        weaveplugin
694d4665f366        weaveworks/weaveexec:1.5.1   "/home/weave/weavepro"   About an hour ago   Up About an hour                        weaveproxy
6c9e84329487        weaveworks/weaveexec:1.5.1   "/bin/false"             About an hour ago   Created                                 weavevolumes-1.5.1
918e14fc1142        weaveworks/weave:1.5.1       "/home/weave/weaver -"   About an hour ago   Up About an hour                        weave
2f0cf5db8704        weaveworks/weavedb           "data-only"              About an hour ago   Created                                 weavedb
root@test02:~# weave ps
weave:expose de:54:76:ab:4f:e9 192.168.99.21/24
00bf6e9f66f1 0a:03:33:71:a1:81 192.168.99.21/24
```

###5.2.1 client2コンテナ

```text:clent2コンテナのネットワーク
root@test02:~# docker attach $CLIENT2
root@00bf6e9f66f1:/# 
root@00bf6e9f66f1:/# 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
10: eth0@if11: <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 link-netnsid 0
    inet 172.17.0.2/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
12: ethwe@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:03:33:71:a1:81 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.99.21/24 scope global ethwe
       valid_lft forever preferred_lft forever
    inet6 fe80::803:33ff:fe71:a181/64 scope link 
       valid_lft forever preferred_lft forever
```

```text:curlのインストール
root@00bf6e9f66f1:/# apt-get install curl -y
```

#6.疎通確認

ここまでで、複数ホストをまたがって敷設された192.168.99.0/24という仮想ネットワーク上に3つのコンテナが起動した。コンテナやホストから疎通確認を行う。

##6.1 ホスト1 → httpdコンテナ
httpdコンテナはホスト1上の仮想ブリッジdocker0, weaveに直接つながっているため、eth0を経由せずに通信が行われる。

```text:ping(ホスト1→httpdコンテナ)
root@test01:~# ping -c 3 192.168.99.10
PING 192.168.99.10 (192.168.99.10) 56(84) bytes of data.
64 bytes from 192.168.99.10: icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from 192.168.99.10: icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from 192.168.99.10: icmp_seq=3 ttl=64 time=0.071 ms

--- 192.168.99.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.057/0.065/0.071/0.005 ms
```

```text:HTTP(ホスト1→httpdコンテナ)
root@test01:~# curl 192.168.99.10

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <!--
    Modified from the Debian original for Ubuntu
    Last updated: 2014-03-19
    See: https://launchpad.net/bugs/1288690
...
```

##6.2 client1コンテナ → httpdコンテナ

client1コンテナとhttpdコンテナは同じ仮想ブリッジdocker0, weaveにつながっているため、eth0を経由せずに通信が行われる。

```text:ping(client1コンテナ→httpdコンテナ)
root@963a338fe903:/# ping -c 3 192.168.99.10
PING 192.168.99.10 (192.168.99.10) 56(84) bytes of data.
64 bytes from 192.168.99.10: icmp_seq=1 ttl=64 time=0.152 ms
64 bytes from 192.168.99.10: icmp_seq=2 ttl=64 time=0.085 ms
64 bytes from 192.168.99.10: icmp_seq=3 ttl=64 time=0.093 ms

--- 192.168.99.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.085/0.110/0.152/0.029 ms
```

`ping`コマンドで`bash: ping: command not found`と表示されたら、`apt-get update`をして必要なパッケージやモジュールをインストールしてください。
ipコマンドのパッケージは、`apt-get install iputils-ping`です。

```text:HTTP(client1コンテナ→httpdコンテナ)
root@963a338fe903:/# curl 192.168.99.10

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <!--
...
```

##6.3 ホスト2 → httpdコンテナ

同一VLAN上にあるホスト2からのパケットをweaverプロセスがラップしてホスト1のeth0に到達し、ホスト1のweaverプロセスを経由してhttpdコンテナと通信されている。

```text:ping(ホスト2→httpdコンテナ)
root@test02:~# ping -c 3 192.168.99.10
PING 192.168.99.10 (192.168.99.10) 56(84) bytes of data.
64 bytes from 192.168.99.10: icmp_seq=1 ttl=64 time=101 ms
64 bytes from 192.168.99.10: icmp_seq=2 ttl=64 time=1.32 ms
64 bytes from 192.168.99.10: icmp_seq=3 ttl=64 time=1.31 ms

--- 192.168.99.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 1.311/34.579/101.098/47.036 ms
```

```text:HTTP(ホスト2→httpdコンテナ)
root@test02:~# curl 192.168.99.10

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <!--
    Modified from the Debian original for Ubuntu
    Last updated: 2014-03-19
...
```

##6.4 client2コンテナ → httpdコンテナ

ホスト2上にあるclient2コンテナからのパケットをweaverプロセスがラップしてホスト1のeth0に到達し、ホスト1のweaverプロセスを経由してhttpdコンテナと通信されている。

```text:ping(client2コンテナ→httpdコンテナ)
root@test02:~# docker attach $CLIENT2
root@00bf6e9f66f1:/# 
root@00bf6e9f66f1:/# ping -c 3 192.168.99.10
PING 192.168.99.10 (192.168.99.10) 56(84) bytes of data.
64 bytes from 192.168.99.10: icmp_seq=1 ttl=64 time=2.01 ms
64 bytes from 192.168.99.10: icmp_seq=2 ttl=64 time=0.666 ms
64 bytes from 192.168.99.10: icmp_seq=3 ttl=64 time=0.670 ms

--- 192.168.99.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.666/1.117/2.017/0.637 ms
```

`ping`コマンドで`bash: ping: command not found`と表示されたら、`apt-get update`をして必要なパッケージやモジュールをインストールしてください。
ipコマンドのパッケージは、`apt-get install iputils-ping`です。

#7.まとめ
Dockerでのマルチホストネットワークとして、基本的な基盤の確認ができました。
docker+consul+swarm(+vxlan）は、Dockerの本体に組み込まれているところを中心な技術でqiitaでの執筆量は、結構ありますが、Docker+Weaveではあまりないようです。
weaveの記事を参考にさせて頂いた[nmatsui](http://qiita.com/nmatsui)さんには感謝です。

#8.参考資料

[マルチホストDockerネットワーキング（weave）](http://qiita.com/nmatsui/items/a7caa5a3840b8c920124)

[複数のDockerサーバで独自ネットワークを構築する「Weave」を試す！](http://knowledge.sakura.ad.jp/tech/2522/)

[Weaveでマルチホストのコンテナ間ネットワークを作ってみる](http://tanksuzuki.com/post/docker-weave-test/)

[Dockerコンテナ接続パターン (2014年冬)](http://deeeet.com/writing/2014/12/01/docker-link-pattern/)

[（本家の資料）WEAVE NET 1.5.1 DOCUMENTATION](https://www.weave.works/docs/net/latest/introducing-weave/)

#最後に
この検証環境は、某有名なクラウドサービス（ALTUS Basic）のサーバーを、２サーバー（１サーバー１ヶ月５００円）借りて検証しました。
次は、weaveを使って、nginx＋Weｂサーバーのスタイルを作ろうと思います。

ありがとうございます。