[実践編]docker + さくらのクラウドでマルチホストなoverlayネットワークしてみるよ(実施編)

[準備編](http://qiita.com/yamamoto-febc/items/861afa1ce363f4161113)では
マシンの作成を作成しリージョン間で管理系IP宛のPingが通るところまで確認しました。


## 前回のおさらい：手順と構成

![kobito.1449061175.615776.png](https://qiita-image-store.s3.amazonaws.com/0/20668/af32eafc-15e7-2cf0-5683-c549ef4e6721.png "kobito.1449061175.615776.png")


### 手順

  1. :white_check_mark: さくらのクラウド上でスイッチ/ブリッジを作成
  2. :white_check_mark: クラスタの構成情報を格納するKVS(consul)ノードを作成
  3. :white_check_mark: swarmマネージャノードを作成
  4. :white_check_mark: swarmエージェントノードを各リージョンに作成
  5. dockerオーバーレイネットワークの作成
  6. コンテナを作成して動作確認


今回は手順5からです。

## 概要

オーバーレイネットワークを作成し、確認のために各リージョンでコンテナを起動します。

|リージョン | コンテナ名   | オーバーレイネットワークへの参加 |
|---------|:-------------:|:----------------------------:|
|石狩第1   | container1   | :o: |
|石狩第2   | container2   | :o: |
|東京第1   | container3   | :x: |

以下のような結果を期待しています。

![kobito.1449064405.057453.png](https://qiita-image-store.s3.amazonaws.com/0/20668/b67be378-d65f-bc03-0ac5-acd5ee10ccd3.png "kobito.1449064405.057453.png")


## 手順5. dockerオーバーレイネットワークの作成

オーバーレイネットワークの作成は以下のコマンドで行います。
swarmクラスタに参加しているノードであればどこで行ってもOKです。

```bash
$ docker network create -d overlay [ネットワーク名] 
```

では早速作成していきます。
作成するオーバーレイネットワークの名前は`ishikari-network`とします。

```bash
# dockerコマンドでswarmマネージャへ接続するように設定
$ eval "$(docker-machine env --swarm sakura-is1a-manager)" 

# オーバーレイネットワーク作成
$ docker network create -d overlay ishikari-network

# ネットワークの確認
$ docker network ls

```

`docker network ls`で以下のような結果になっているはずです。
見やすくするため改行/並べ替えを行っています。

```bash
NETWORK ID          NAME                         DRIVER
b0decb567506        sakura-is1a-manager/bridge   bridge              
00cfbc40125e        sakura-is1a-manager/host     host                
4ba8ceef0a1a        sakura-is1a-manager/none     null                

735df4903fab        sakura-is1a-agent/bridge     bridge              
45303217fec0        sakura-is1a-agent/host       host                
82d3bb7aa67f        sakura-is1a-agent/none       null                

0723a7abc577        sakura-is1b-agent/bridge     bridge              
18752fd515f3        sakura-is1b-agent/host       host                
3c23e015b47a        sakura-is1b-agent/none       null                

d09b4b43c662        sakura-tk1a-agent/bridge     bridge              
c1bc94509cab        sakura-tk1a-agent/host       host 
bd64ec929e31        sakura-tk1a-agent/none       null                

452a2a1149fa        ishikari-network             overlay             
```

swarmクラスタに参加している各ノードそれぞれ3つ(bridge/host/null)に加え、
どのノードとも紐付いていないネットワーク`ishikari-network`が作成されました。

## 手順6. コンテナを作成して動作確認

それではdockerコンテナを起動していきましょう。
石狩第1と第2のコンテナは先ほどの`ishikari-network`に接続し、
東京第1のコンテナはネットワーク未指定で起動してみます。

指定しているオプションは以下の通りです。

  * `--name` : コンテナ名、後ほど名前解決に利用
  * `--net`  : 参加するネットワークを指定、デフォルトはbridgeに接続される
  * `--env`  : `constraint:node`を指定することでswarmにコンテナを起動するノードを指示する

```bash
# 石狩第1で起動,ネットワーク指定あり
docker run -itd --name=container1 --net=ishikari-network --env="constraint:node==sakura-is1a-agent" busybox
# 石狩第2で起動,ネットワーク指定あり
docker run -itd --name=container2 --net=ishikari-network --env="constraint:node==sakura-is1b-agent" busybox
# 東京第1で起動,ネットワーク指定なし
docker run -itd --name=container3 --env="constraint:node==sakura-tk1a-agent" busybox

```

起動したら各コンテナのIPを表示させてみましょう。
各コンテナで`ip addr`コマンドを実行します。

```bash
#各コンテナに対し以下を実施
$ docker exec -it [コンテナ名,先ほど--nameオプションで指定したやつ] /bin/sh
#コンテナ内でshが起動するため、ip addrコマンド実施
[container1]$ ip addr
```

#### 石狩第1上のコンテナ(container1)で`ip addr`
```bash
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    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
8: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue 
    link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe00:2/64 scope link 
       valid_lft forever preferred_lft forever
11: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:2/64 scope link 
       valid_lft forever preferred_lft forever
```

#### 石狩第2上のコンテナ(container2)で`ip addr`
```bash 
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    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
8: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue 
    link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.3/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe00:3/64 scope link 
       valid_lft forever preferred_lft forever
11: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:2/64 scope link 
       valid_lft forever preferred_lft forever
```

#### 東京第1上のコンテナ(container3)で`ip addr`
```bash
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    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
7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    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
```
       
以下の図のようなIPを持っています。
![kobito.1449071543.669620.png](https://qiita-image-store.s3.amazonaws.com/0/20668/479d28d2-026f-0e4e-ae72-daa682fc456f.png "kobito.1449071543.669620.png")

では動作確認してみましょう。

#### container1からcontainer2へping

```bash
$ docker exec -it container1 ping container2 -c4

PING container2 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.727 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.599 ms
64 bytes from 10.0.0.3: seq=2 ttl=64 time=0.563 ms
64 bytes from 10.0.0.3: seq=3 ttl=64 time=0.595 ms

--- container2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.563/0.621/0.727 ms
```
通りましたね:+1: 

#### container1からcontainer3へping
```bash
# container1からcontainer3へping
$ docker exec -it container1 ping container3 -c4

ping: bad address 'container3'
```

名前解決できないというエラーが出ました:-1:

#### container3からcontainer2へping
```bash
# container1からcontainer3へping
$ docker exec -it container3 ping container2 -c4

ping: bad address 'container2'
```

こちらも名前解決できないというエラーが出ました:-1:

## まとめ

期待していた結果通りとなりました。

オーバーレイネットワークでは、

* 参加したコンテナ間で名前解決できるようになる
* 参加したコンテナ間でネットワーク疎通できる

という結果になりましたね。

オーバーレイネットワークの裏側で何が行われているかは以下の記事が日本語で読めますので参考にされてください。

[参考訳：network コマンドの動作](http://qiita.com/zembutsu/items/a3f46a4e7f4eb582c3ea)
[参考訳：マルチホスト・ネットワーキングを始めよう](http://qiita.com/zembutsu/items/36032ee78e82278b3c6a)

## おまけ：container3をオーバーレイネットワークに参加させてみる。

せっかくなので先ほど繋がらなかったcontainer3をオーバーレイネットワークに参加させてみます。

以下のコマンドで参加させることができます。

```bash
$ docker network connect [ネットワーク名] [コンテナ名]
```

実行しましょう。

```bash
$ docker network connect ishikari-network container3
Error response from daemon: invalid container <nil> : nosuchcontainer: no such id: container3
```

あれれ、、？エラーになりますね、、

調べたらこんなswarmにIssueが。
[Network connect multihost env | invalid container <nil> : #1402](https://github.com/docker/swarm/issues/1402)

2015年12月3日現在Openとなっていますので静かに見守っておきましょう。


それでは本日は以上です。enjoy!:+1: