前回までに作成したOverlayネットワークのDocker SwarmクラスタへDocker Composeを使いRethinkDBをデプロイしてみます。 RethinkDBのブログは読んでいて楽しいので気に入っています。ES6 Generatorのサポートも早くモダンなデータベースです。
このシリーズ
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 1: Overlayネットワークの作成
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 2: Docker Swarmクラスタの作成
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 3: OverlayネットワークとDocker SwarmとDocker ComposeでRethinkDBをスケールさせる
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 4: Couchbase Serverをスケールしてみる
参考
以下のサイトを参考にしました。
- DockerでサクッとRethinkDBのクラスタを試す
- Simplify deployment with the new networking features in Docker 1.9
- Fun with Nuxeo Cloud and Docker Tools After DockerCon
仮想マシン
前回と同じ仮想マシンを使います。
| Dockerホストのhostname | Dockerホストのeth0 | Docker Swarm | 
|---|---|---|
| minion-1 | 10.3.0.101 | Swarm Manager/Agent | 
| minion-2 | 10.3.0.102 | Swarm Agent | 
| minion-3 | 10.3.0.103 | Swarm Agent | 
RethinkDB
RethinkDBはオフィシャルのイメージを使います。
プロジェクト
 rethinkの名前でディレクトリを作成してdocker-compose.ymlを配置します。このディレクトリ名はプロジェクト名としてコンテナの名前やOverlayネットワーク名として使われます。
$ tree .
.
└── rethink
    └── docker-compose.yml
docker-compose.yml
 DockerでサクッとRethinkDBのクラスタを試すを参考にしてdocker-compose.ymlを作成します。
seed:
  image: rethinkdb:2
  ports:
    - "8088:8080"
  command: rethinkdb -n seed --bind all
worker:
  image: rethinkdb:2
  environment:
    - "affinity:container!=rethink_worker_*"
  command: rethinkdb --bind all -j rethink_seed_1:29015
proxy:
  image: rethinkdb:2
  ports:
    - "8080:8080"
  environment:
    - constraint:node==minion-3
  command: rethinkdb proxy --bind all -j rethink_seed_1:29015
Docker ComposeはReleasesサイトから最新バージョンをワンライナーでインストールします。
$ curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
linksを使わない
 Networking in ComposeのLinksにあるようにlibnetworkが導入されlinksはdeprecatedとなりました。docker-compose.ymlから削除しています。
 これまでDocker Composeはlinksを指定するとコンテナの/etc/hostsに自動的にエントリーされ名前解決ができました。libnetworkに対応してDocker Composeでは--x-networkingフラグをつけてupするとプロジェクト名(ディレクトリ名)のネットワークが自動的にdocker network createされます。{ネットワーク名}_{サービス名}_Nのホスト名がコンテナの/etc/hostsに登録され名前解決ができるようになりました。
 ただしlibnetworkがまだエイリアスに対応していなかったり、/etc/hostsへの登録にはいくつか問題がありissuesが上がっています。
- About links at multi host x-networking
- simple names in /etc/hosts when using the experimental networking feature
 参考の例のlinksはサービス名で記述できましたが、{ネットワーク名}_{サービス名}_Nのように固定にする必要があります。
worker:
  image: rethinkdb:2
  links:
    - seed:seed
  command: rethinkdb --bind all -j seed:29015
proxy:
  image: rethinkdb:2
  ports:
    - 8080:8080
  links:
    - worker:worker
  command: rethinkdb proxy --bind all -j worker:29015
Affinity filter
 workerサービスはAffinity filterを使いanti-affinityフィルターを作ります。rethink_worker_*のコンテナが起動していない別のノードを選びます。
worker:
  image: rethinkdb:2
  environment:
    - "affinity:container!=rethink_worker_*"
  command: rethinkdb --bind all -j rethink_seed_1:29015
Constraint filter
 proxyサービスはConstraint Filterを指定してminion-3のノードを特定して起動します。IDCFクラウドの設定でパブリックIPアドレスとminion-3をスタティックNATしています。
proxy:
  image: rethinkdb:2
  ports:
    - "8080:8080"
  environment:
    - constraint:node==minion-3
  command: rethinkdb proxy --bind all -j rethink_seed_1:29015
Docker SwarmとOverlayネットワーク
DOCKER_HOST環境変数にSwarm Managerを設定してからupするとSwarmクラスタにデプロイします。
$ export DOCKER_HOST=tcp://10.3.0.101:3333
$ pwd
/root/rethink
$ docker-compose \
  --x-networking \
  --x-network-driver=overlay \
  up -d
Dockerイメージがないノードではdocker pullするので少し時間がかかります。docker-compose psで確認するとサービスのコンテナが1つずつ起動しました。
$ docker-compose ps
         Name                     Command                    State                     Ports
-----------------------------------------------------------------------------------------------------
rethink_proxy_1           rethinkdb proxy --bind    Up                        28015/tcp, 29015/tcp, 1
                          all ...                                             0.3.0.103:8080->8080/tc
                                                                              p
rethink_seed_1            rethinkdb -n seed         Up                        28015/tcp, 29015/tcp, 1
                          --bind all                                          0.3.0.101:8088->8080/tc
                                                                              p
rethink_worker_1          rethinkdb --bind all -j   Up                        28015/tcp, 29015/tcp,
                          re ...                                              8080/tcp
 --x-networkingフラグを指定するとプロジェクト名でDockerネットワークを作成します。rethinkネットワークが作成されました。
$ docker network ls
NETWORK ID          NAME                DRIVER
3f8bacd30250        rethink             overlay
f10c0f7978af        dn                  overlay
b68b118036d2        bridge              bridge
636664a4f746        docker_gwbridge     bridge
6e0cf0387184        none                null
bc09b464b0c5        host                host
Swarm Managerを指定してdocker psで確認するとNAMES列のコンテナ名は{Dockerホスト名}/{ネットワーク名}_{サービス名}_Nのように付けられています。
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                             NAMES
b9f13b49004a        rethinkdb:2         "rethinkdb proxy --bi"   4 seconds ago       Up 2 seconds        28015/tcp, 10.3.0.103:8080->8080/tcp, 29015/tcp   minion-3/rethink_proxy_1
581d02852c24        rethinkdb:2         "rethinkdb --bind all"   5 seconds ago       Up 4 seconds        8080/tcp, 28015/tcp, 29015/tcp                    minion-2/rethink_worker_1
4ae146ed7671        rethinkdb:2         "rethinkdb -n seed --"   6 seconds ago       Up 5 seconds        28015/tcp, 29015/tcp, 10.3.0.101:8088->8080/tcp   minion-1/rethink_seed_1}}}
 --x-network-driver=overlayフラグはコンテナのeth0にOverlayネットワークを作成します。
$ docker exec minion-3/rethink_proxy_1 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
134: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 02:42:0a:00:00:04 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.4/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe00:4/64 scope link
       valid_lft forever preferred_lft forever
136: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/16 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:3/64 scope link
       valid_lft forever preferred_lft forever
 /etc/hostsにもOverlayネットワークに参加してホスト名が登録されているので、Dockerホストをまたいだ名前解決ができます。
$ docker exec minion-3/rethink_proxy_1 cat /etc/hosts
10.0.0.4        f704478aaadf
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.0.0.2        rethink_seed_1
10.0.0.2        rethink_seed_1.rethink
10.0.0.3        rethink_worker_1
10.0.0.3        rethink_worker_1.rethink
10.0.0.5        rethink_worker_2
10.0.0.5        rethink_worker_2.rethink
10.0.0.6        rethink_worker_3
10.0.0.6        rethink_worker_3.rethink
scale
 upしている状態でworkerサービスのコンテナを3台にscaleします。
$ docker-compose \
  --x-networking \
  --x-network-driver=overlay \
  scale worker=3
Creating and starting 2 ... done
Creating and starting 3 ... done
 anti-affinityのフィルターを指定するとworkerサービスのコンテナはなるべく同じDockerホスト上で起動しないようスケジュールされます。worker=3としてSwarmクラスタのノード数と合わせたので1つずつコンテナが起動しました。
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                             NAMES
d6a1e40685f9        rethinkdb:2         "rethinkdb --bind all"   8 seconds ago       Up 7 seconds        8080/tcp, 28015/tcp, 29015/tcp                    minion-3/rethink_worker_3
4eb7c2959112        rethinkdb:2         "rethinkdb --bind all"   8 seconds ago       Up 7 seconds        8080/tcp, 28015/tcp, 29015/tcp                    minion-1/rethink_worker_2
b9f13b49004a        rethinkdb:2         "rethinkdb proxy --bi"   2 minutes ago       Up 2 minutes        28015/tcp, 10.3.0.103:8080->8080/tcp, 29015/tcp   minion-3/rethink_proxy_1
581d02852c24        rethinkdb:2         "rethinkdb --bind all"   2 minutes ago       Up 2 minutes        8080/tcp, 28015/tcp, 29015/tcp                    minion-2/rethink_worker_1
4ae146ed7671        rethinkdb:2         "rethinkdb -n seed --"   2 minutes ago       Up 2 minutes        28015/tcp, 29015/tcp, 10.3.0.101:8088->8080/tcp   minion-1/rethink_seed_1
トラブルシュート
 --x-networkingをつけないでscaleしたコンテナには/etc/hostsが入りません。scaleしたコンテナが同じDockerホストのコンテナも名前解決ができなくなり、少し嵌りました。
$ docker exec minion-3/rethink_worker_3 cat /etc/hosts
172.17.0.3      8df54f957347
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters