参考訳：マルチホスト・ネットワーキングを始めよう

Get started with multi-host networking
http://docs.docker.com/engine/userguide/networking/get-started-overlay/

----
# マルチホスト・ネットワーキングを始めよう

このページでは、マルチホスト・ネットワーキングの基本的な例について説明します。独創的な `overlay` ネットワーク・ドライバによって、Docker エンジンはマルチホスト・ネットワーキングをサポートしました。`bridge` ネットワークとは違い、オーバレイ・ネットワークは作成前にいくつかの事前準備が必要です。準備とは次のようなものです：

* kernel バージョン 3.16 以上のホスト
* キーバリュー・ストアに対するアクセス。エンジンがサポートするキーバリュー・ストアは、Consul、Etcd、Zookeeper（分散ストア）です。
* ホストのクラスタが、キーバリュー・ストアに接続する。
* Swarm の各ホスト上で動作するエンジン `daemon` に、適切な設定を行う。

Docker マルチホスト・ネットワーキング機能を使うのに、Docker Machine と Docker Swarm の使用は強制ではありません。しかし、この例では Machine と Swarm を使用して説明します。Machine を使ってキーバリュー・ストア用のサーバと、ホストのクラスタを作成します。この例では Swarm クラスタを作成します。

## 事前準備

始める前に、自分のネットワーク上のシステムに、最新バージョンの Docker エンジン と Docker Machine がインストールされているか確認してください。この例では VirtualBox を扱います。Mac や Windows で Docker Toolbox を使ってインストールしているのであれば、いずれも最新バージョンがインストールされています。

もし準備ができていなければ、Docker エンジンと Docker Machine を最新バージョンに更新してください。

## ステップ１：キーバリュー・ストアのセットアップ

オーバレイ・ネットワークはキーバリュー・ストアが必要です。キーバリュー・ストアにネットワーク情報に関する情報を保管します。情報とは、ディスカバリ、ネットワーク、エンドポイント、IP アドレスなどです。Docker はキーバリュー・ストアとして Consul、Etcd、ZooKeeper（分散ストア）をサポートしています。今回の例では Consul を使います。

1. 必要になる Docker エンジン、Docker Machine、VirtualBox ソフトウェアを準備したシステムにログインします。
2. `mh-keysotre` という名前の VirtualBox マシンを作成します。

```
$ docker-machine create -d virtualbox mh-keystore
```

新しいマシンを作成すると、この手順で Docker エンジンがホスト上に追加されます。つまりこれは、Consul を手動でインストールするのではなく、[Docker Hub 上の consul イメージ](https://hub.docker.com/r/progrium/consul/)を使用するインスタンスの作成を意味します。インストールは次の手順で行います。
3. 実行中の `mh-keystore` マシン上で `progrium/consul` コンテナを起動します。

```
$  docker $(docker-machine config mh-keystore) run -d \
    -p "8500:8500" \
    -h "consul" \
    progrium/consul -server -bootstrap
```

`docker run` コマンドを実行するとき、bash 変数展開 `$(docker-machine config mh-keystore)` を使い、接続と設定を行います。実行中の `mh-keystore` マシン上で 、クライアントは `progrium/consul` イメージを開始します。このサーバは `consul` と呼ばれており、ポート `8500` を開きます。
4. ローカルに `mh-keystore` マシンの環境変数を設定します。

```
$ eval "$(docker-machine env mh-keystore)"
```

　5. `docker ps` コマンドを実行すると、`consul` コンテナが表示されます。

```
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                            NAMES
4d51392253b3        progrium/consul     "/bin/start -server -"   25 minutes ago      Up 25 minutes       53/tcp, 53/udp, 8300-8302/tcp, 0.0.0.0:8500->8500/tcp, 8400/tcp, 8301-8302/udp   admiring_panini
```

ターミナルを開いたまま、次のステップに映ります。

## ステップ２：Swarm クラスタの作成

このステップは、`docker-machine` を使ってネットワーク上にホストを準備します。この時点では実際にネットワークを作成する必用はありません。VirtualBox 内に複数のマシンを作成します。マシンの１つを Swarm マスタとして動かします（これは一番始めに作成するマシンです）。各々のホストを作成した後、マシン上のエンジンで `overlay` ネットワーク・ドライバに対応するために必要なオプション設定を追加します。

1. Swarm マスタの作成

```
$ docker-machine create \
-d virtualbox \
--swarm --swarm-image="swarm" --swarm-master \
--swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \
--engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \
--engine-opt="cluster-advertise=eth1:2376" \
mhs-demo0
```

作成時、エンジンの `daemon` に対して `--cluster-store` オプションを与えます。このオプションは、エンジンに対して `overlay` ネットワークのキーバリュー・ストアを伝えます。bash 変数展開 `$(docker-machine ip mh-keystore)` は、「STEP 1」で作成した Consul サーバの IP アドレスを割り当てます。`--cluster-advertise` オプションは、ネットワーク上のマシンに対して公表（advertise）するものです。

　2. Swarm クラスタに追加する他のホストを作成します。

```
$ docker-machine create -d virtualbox \
    --swarm --swarm-image="swarm:1.0.0-rc2" \
    --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \
    --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \
    --engine-opt="cluster-advertise=eth1:2376" \
  mhs-demo1
```

　3. マシン一覧から、全てが起動・実行中であることを確認します。

```
$ docker-machine ls
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM
default               virtualbox   Running   tcp://192.168.99.100:2376
mh-keystore           virtualbox   Running   tcp://192.168.99.103:2376
mhs-demo0             virtualbox   Running   tcp://192.168.99.104:2376   mhs-demo0 (master)
mhs-demo1             virtualbox   Running   tcp://192.168.99.105:2376   mhs-demo0
```

この時点で、ネットワーク上に複数のホストが起動します。これらのホストを使って、マルチホスト・ネットワークを作成する準備が整いました。

## ステップ３：オーバレイ・ネットワークの作成

オーバレイ・ネットワークを作成します。

　1. docker 環境変数を Swarm マスタのものにします。

```
$ eval $(docker-machine env --swarm mhs-demo0)
```

`docker-machine` に `--swarm` フラグを使うと、`docker` コマンドは Swarm 情報のみ表示します。

　2. `docker info` コマンドで Swarm を表示します。

```
$ docker info
Containers: 3
Images: 2
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 2
mhs-demo0: 192.168.99.104:2376
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.1.10-boot2docker, operatingsystem=Boot2Docker 1.9.0-rc1 (TCL 6.4); master : 4187d2c - Wed Oct 14 14:00:28 UTC 2015, provider=virtualbox, storagedriver=aufs
mhs-demo1: 192.168.99.105:2376
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: executiondriver=native-0.2, kernelversion=4.1.10-boot2docker, operatingsystem=Boot2Docker 1.9.0-rc1 (TCL 6.4); master : 4187d2c - Wed Oct 14 14:00:28 UTC 2015, provider=virtualbox, storagedriver=aufs
CPUs: 2
Total Memory: 2.043 GiB
Name: 30438ece0915
```

この情報から、３つのコンテナが動作中で、マスタ上には２つのイメージがあることがわかります。

　3. `overlay` ネットワークを作成します。

```
docker network create --driver overlay my-net
```

クラスタ上のどこかのホストで、ネットワークを作成する必用があります。この例では、Swarm マスタを使いますが、クラスタ上のホストであれば、どこでも簡単にできます。

　4. ネットワークの状態を確認します。
```
$ docker network ls
NETWORK ID          NAME                DRIVER
412c2496d0eb        mhs-demo1/host      host
dd51763e6dd2        mhs-demo0/bridge    bridge
6b07d0be843f        my-net              overlay
b4234109bd9b        mhs-demo0/none      null
1aeead6dd890        mhs-demo0/host      host
d0bb78cbe7bd        mhs-demo1/bridge    bridge
1c0eb8f69ebb        mhs-demo1/none      null
```

Swarm マスタ環境にいるため、このように Swarm エージェントが動作している全てのネットワークが表示されます。各 `NETWORK ID` はユニークなことに注意します。各エンジンのデフォルト・ネットワークとオーバレイ・ネットワークが１つ表示されます。

　5. 各 Swarm エージェントに切り替えて、ネットワークの一覧を見てみます。

```
$ eval $(docker-machine env mhs-demo0)
$ docker network ls
NETWORK ID          NAME                DRIVER
6b07d0be843f        my-net              overlay
dd51763e6dd2        bridge              bridge
b4234109bd9b        none                null
1aeead6dd890        host                host
$ eval $(docker-machine env mhs-demo1)
$ docker network ls
NETWORK ID          NAME                DRIVER
d0bb78cbe7bd        bridge              bridge
1c0eb8f69ebb        none                null
412c2496d0eb        host                host
6b07d0be843f        my-net              overlay
```

どちらのエージェントも、ID が `6b07d0be843f ` の `my-net` ネットワークを持っていると表示しています。これでマルチホスト・コンテナ・ネットワークが動作しました！

## ステップ４：ネットワークでアプリケーションの実行

ネットワークを作成したあとは、あらゆるホスト上で、自動的にこのネットワークの一部としてコンテナを開始できます。

　1. `mhs-demo0` インスタンス環境を指定します。

```
$ eval $(docker-machine env mhs-demo0)
```

　2. `mhs-demo0` 上に Nginx サーバを開始します。

```
$ docker run -itd --name=web --net=my-net --env="constraint:node==mhs-demo0" nginx
```

このコマンドは Swarm マスタ上でウェブサーバを開始するコマンドです。

　3. `mhs-demo1` のマシン環境を指定します。

```
$ eval $(docker-machine env mhs-demo1)
```

　4. Busybox インスタンスを実行し、Nginx サーバのホームページのコンテンツを取得します。

```
    $ docker run -it --rm --net=my-net --env="constraint:node==mhs-demo1" busybox wget -O- http://web
    Unable to find image 'busybox:latest' locally
    latest: Pulling from library/busybox
    ab2b8a86ca6c: Pull complete
    2c5ac3f849df: Pull complete
    Digest: sha256:5551dbdfc48d66734d0f01cafee0952cb6e8eeecd1e2492240bf2fd9640c2279
    Status: Downloaded newer image for busybox:latest
    Connecting to web (10.0.0.2:80)
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
    }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>


    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>


    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    -                    100% |*******************************|   612   0:00:00 ETA

```

## ステップ５：外部への接続性を確認

これまで見て来たように、Docker 内蔵のオーバレイ・ネットワーク・ドライバによって、複数のホスト上（同じネットワークでなくとも）に存在するコンテナ間で、革新的な接続性をもたらします。さらに、マルチホスト・ネットワークに接続するコンテナは、自動的に `docker_gwbridge` ネットワークに接続します。このネットワークはコンテナがクラスタの外部に対する接続性をもたらします。

　1. Swarm エージェントの環境を変更します。

```
$ eval $(docker-machine env mhs-demo1)
```

　2. ネットワーク一覧に `docker_gwbridge` ネットワークがあることを確認します。

```
$ docker network ls
NETWORK ID          NAME                DRIVER
6b07d0be843f        my-net              overlay
dd51763e6dd2        bridge              bridge
b4234109bd9b        none                null
1aeead6dd890        host                host
e1dbd5dff8be        docker_gwbridge     bridge
```

　3. Swarm マスタでステップ１と２を繰り返します。

```
$ eval $(docker-machine env mhs-demo0)
$ docker network ls
NETWORK ID          NAME                DRIVER
6b07d0be843f        my-net              overlay
d0bb78cbe7bd        bridge              bridge
1c0eb8f69ebb        none                null
412c2496d0eb        host                host
97102a22e8d2        docker_gwbridge     bridge
```

　4. Nginx コンテナのネットワーク・インターフェースを確認します。

```
$ docker exec web ip addr
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
22: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link/ether 02:42:0a:00:09:03 brd ff:ff:ff:ff:ff:ff
inet 10.0.9.3/24 scope global eth0
    valid_lft forever preferred_lft forever
inet6 fe80::42:aff:fe00:903/64 scope link
    valid_lft forever preferred_lft forever
24: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
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
```

`eth0` インターフェースは、コンテナが `my-net` オーバレイ・ネットワークに接続するインターフェースを表しています。`eth1` インターフェースは、コンテナが`docker_gwbridge` ネットワークが接続するインターフェースを表します。

## ステップ６：Docker Compose との追加機能

既存の Swarm クラスタ上に、Docker Compose を使って２つめのネットワークを起動できます。

　1. Swarm マスタにログインします。

　2. Docker Compose をインストールします。

　3. `docker-compose.yml` ファイルを作成します。

　4. ファイル内容に以下の項目を追加します。

```
web:
    image: bfirsh/compose-mongodb-demo
    environment:
        - "MONGO_HOST=counter_mongo_1"
        - "constraint:node==swl-demo0"
    ports:
        - "80:5000"
mongo:
    image: mongo
```

　5. ファイルを保存して閉じます。

　6. Compose を使ってアプリケーションを起動します。

```
$ docker-compose --x-networking up -d
```