前回はDocker MachineでDockerノードを構築してみたので、今回は同時にアナウンスされたDocker Swarmでクラスタを構築してみます。
Docker Swarmとは
Docker Swarmは複数のDockerホストをクラスタ化するためのツールです。Docker SwarmをAPIを受け取るフロントエンドとして、コンテナをクラスタのメンバー上で動かすことができます。
Docker Swarmのマネージャをホストとして指定すれば各種Dockerのツールもそのまま使えるようです。
ノードの構築
今回はIDCFクラウド上にnode1〜node3の3つの仮想マシンを作成しクラスタを後置鵜してみます。
3台の役割とlistenしているIP・ポートは以下の通りとします。
- node1
- マネージャ(tcp://0.0.0.0:12375)
- ノード(tcp://0.0.0.0:2375)
- node2
- ノード(tcp://0.0.0.0:2375)
- node3
- ノード(tcp://0.0.0.0:2375)
仮想マシン作成用のVagrantfileは下記リンク先にあります。
vagrant up
で最小構成のUbuntu14.04の仮想マシン3台が起動します。
$ vagrant up
VagrantfileではDockerのインストールとswarmのイメージのpull、TCPを利用するための設定を行っています。
node.vm.provision "docker" do |d|
d.pull_images "swarm"
end
node.vm.provision "shell" do |s|
s.inline = <<-EOS
echo 'DOCKER_OPTS="-H tcp://0.0.0.0:2375 ${DOCKER_OPTS}"' >> /etc/default/docker
service docker restart
echo 'export DOCKER_HOST=tcp://localhost:2375' >> ~/.bashrc
EOS
end
実行が完了したらvagrant status
コマンドで3台とも起動している事を確認します。起動やプロビジョニングに失敗したノードについては再度vagrant up
やvagrant provision
をやり直してください。
$ vagrant status
Current machine states:
node1 running (cloudstack)
node2 running (cloudstack)
node3 running (cloudstack)
クラスタの構築
いずれかのノード(例ではnode1)でswarm create
コマンドを実行しトークンを発行します。
$ vagrant ssh node1 -c 'docker -H tcp://localhost:2375 run --rm swarm create'
6120a2e88cd767c8a1ee1f4c40ea013f
swarm join
コマンドで各ノードをクラスタにジョインします。
# ノードにログイン
$ vagrant ssh <ノード名>
# eth0のIPを確認
$ ip addr
# クラスタにジョイン
$ docker run -d swarm join --addr=<eth0のIP>:2375 token://<取得したトークン>
# ログアウト
$ exit
node1でswarm manage
コマンドを実行しマネージャーを起動します。
$ vagrant ssh node1
$ docker run -d -p 12375:2375 swarm manage token://<取得したトークン>
クラスタのステータス確認
node1にログインして、環境変数DOCKER_HOST
をswarmのマネージャに設定します。
$ export DOCKER_HOST=tcp://localhost:12375
swarm list
コマンドを実行すると各ノードのIPが表示されます。
$ docker run --rm swarm list token://<取得したトークン>
10.3.0.52:2375
10.3.0.67:2375
10.3.0.79:2375
docker info
コマンドでノード・コンテナの情報を表示することができます。
$ docker info
Containers: 4
Nodes: 3
VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal: 10.3.0.52:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 986.8 MiB
VM-35e5645b-75c2-43a7-b319-a08bec3415b2.csecidcfcloud.internal: 10.3.0.67:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 986.8 MiB
VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da.csecidcfcloud.internal: 10.3.0.79:2375
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 986.8 MiB
docker ps
コマンドでswarm関連のコンテナが各ホストで起動していることを確認する事ができます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91eef6434dec swarm:latest "/swarm manage token 8 minutes ago Up 8 minutes 10.3.0.79:12375->2375/tcp VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da.csecidcfcloud.internal/loving_curie
9f99e4992916 swarm:latest "/swarm join --addr= 9 minutes ago Up 9 minutes 2375/tcp VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/gloomy_poitras
1b9ade9d59d8 swarm:latest "/swarm join --addr= 10 minutes ago Up 9 minutes 2375/tcp VM-35e5645b-75c2-43a7-b319-a08bec3415b2.csecidcfcloud.internal/gloomy_archimedes
fd6764187dbc swarm:latest "/swarm join --addr= 10 minutes ago Up 10 minutes 2375/tcp VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da.csecidcfcloud.internal/determined_kirch
コンテナの起動
docker run
コマンドでコンテナを起動します。初回のダウンロードが実行されている場合などは少し時間がかかります。
swarm manage
を実行している端末に実行中の処理のメッセージが表示されます。
$ docker run -d -p 80:80 dockerfile/nginx
完了するとdocker ps
でコンテナの状態を確認できます。curlで80番ポートに接続するとnginxが起動していることが確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d21f305376aa dockerfile/nginx:latest "nginx" About a minute ago Up About a minute 443/tcp, 10.3.0.67:80->80/tcp VM-35e5645b-75c2-43a7-b319-a08bec3415b2.csecidcfcloud.internal/trusting_tesla
$ curl 10.3.0.67
もう1つコンテナを起動すると別のホストで起動しました。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63abf37db4cf dockerfile/nginx:latest "nginx" 11 seconds ago Up 6 seconds 443/tcp, 10.3.0.52:80->80/tcp VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/agitated_carson
d21f305376aa dockerfile/nginx:latest "nginx" 4 minutes ago Up 4 minutes 443/tcp, 10.3.0.67:80->80/tcp VM-35e5645b-75c2-43a7-b319-a08bec3415b2.csecidcfcloud.internal/trusting_tesla
ノードの停止
node3(例ではeth0のIPが10.3.0.52のノード)を停止してみます。
$ vagrant halt node3
しばらくするとマネージャのログにnode3が死んだことを示すメッセージが表示されました。
$ docker logs 91eef6434dec 2>&1 | grep error | tail -3
time="2015-03-01T12:11:22Z" level=error msg="Flagging node as dead. Updated state failed: Get http://10.3.0.52:2375/v1.15/containers/json?all=1&size=0: dial tcp 10.3.0.52:2375: no route to host. Are you trying to connect to a TLS-enabled daemon without TLS?" id="VG4H:VHCS:IBXK:5NHM:OAGR:HDK3:DKEH:OD2W:RA3Y:EYGN:4ZJE:KCFM" name="VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal"
time="2015-03-01T12:11:55Z" level=error msg="Flagging node as dead. Updated state failed: Get http://10.3.0.52:2375/v1.15/containers/json?all=1&size=0: dial tcp 10.3.0.52:2375: no route to host. Are you trying to connect to a TLS-enabled daemon without TLS?" id="VG4H:VHCS:IBXK:5NHM:OAGR:HDK3:DKEH:OD2W:RA3Y:EYGN:4ZJE:KCFM" name="VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal"
time="2015-03-01T12:12:28Z" level=error msg="Flagging node as dead. Updated state failed: Get http://10.3.0.52:2375/v1.15/containers/json?all=1&size=0: dial tcp 10.3.0.52:2375: no route to host. Are you trying to connect to a TLS-enabled daemon without TLS?" id="VG4H:VHCS:IBXK:5NHM:OAGR:HDK3:DKEH:OD2W:RA3Y:EYGN:4ZJE:KCFM" name="VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal"
docker ps
で見るとnode3で起動していたコンテナのSTATUSがPendingとなっています。
このコンテナについてはdaemonへ接続できないため操作ができなくなっています。
$ docker ps -a | grep VM-48692
63abf37db4cf dockerfile/nginx:latest "nginx" About an hour ago Pending 443/tcp, 10.3.0.52:80->80/tcp VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/agitated_carson
9f99e4992916 swarm:latest "/swarm join --addr= About an hour ago Pending 2375/tcp VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/gloomy_poitras
ノードの再ジョインとコンテナの再起動
node3を起動し同じトークンで再度joinさせてみます。
$ vagrant up node3
$ vagrant ssh node3
$ docker run -d swarm join --addr=<eth0のIP>:2375 token://<取得したトークン>
node1からswarmマネージャに接続し確認してみると、node3のコンテナのSTATUSがExitedになっています。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0819e0d4b157 swarm:latest "/swarm join --addr= 12 seconds ago Up Less than a second 2375/tcp VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/jovial_rosalind
63abf37db4cf dockerfile/nginx:latest "nginx" About an hour ago Exited (0) 6 minutes ago VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/agitated_carson
d21f305376aa dockerfile/nginx:latest "nginx" About an hour ago Up About an hour 443/tcp, 10.3.0.67:80->80/tcp VM-35e5645b-75c2-43a7-b319-a08bec3415b2.csecidcfcloud.internal/trusting_tesla
91eef6434dec swarm:latest "/swarm manage token About an hour ago Up About an hour 10.3.0.79:12375->2375/tcp VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da.csecidcfcloud.internal/loving_curie
9f99e4992916 swarm:latest "/swarm join --addr= About an hour ago Exited (2) 6 minutes ago VM-48692e09-2749-47eb-9b97-92d1b985d2ab.csecidcfcloud.internal/gloomy_poitras
1b9ade9d59d8 swarm:latest "/swarm join --addr= About an hour ago Up About an hour 2375/tcp VM-35e5645b-75c2-43a7-b319-a08bec3415b2.csecidcfcloud.internal/gloomy_archimedes
fd6764187dbc swarm:latest "/swarm join --addr= About an hour ago Up About an hour 2375/tcp VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da.csecidcfcloud.internal/determined_kirch
停止しているコンテナを起動すると再度nginxに接続できるようになります。
$ docker start 63abf37db4cf
トラブルシューティング
ノードが認識されないなどの問題が発生した場合には、swarmのマネージャ、各ノードのエージェントのログを確認する。
swarm関連のコンテナを表示させる場合には、-a
オプションを付ける。
$ docker ps -a | grep manage
91eef6434dec swarm:latest "/swarm manage token About an hour ago Up About an hour 10.3.0.79:12375->2375/tcp VM-2c5d1a87-15f8-4963-8cb9-754ff21d23da.csecidcfcloud.internal/loving_curie
$ docker logs 91eef6434dec 2>&1 | head -5
time="2015-03-01T10:51:06Z" level=info msg="Listening for HTTP" addr=":2375" proto=tcp
time="2015-03-01T10:55:48Z" level=info msg="HTTP request received" method=GET uri="/v1.17/info"
time="2015-03-01T10:56:08Z" level=info msg="HTTP request received" method=GET uri="/v1.17/containers/json"
time="2015-03-01T10:57:30Z" level=info msg="HTTP request received" method=GET uri="/v1.17/containers/json"
time="2015-03-01T10:57:32Z" level=info msg="HTTP request received" method=GET uri="/v1.17/containers/json?all=1"
まとめ
Dockerのクラスタを構築するツールが色々とでてきましたが、Docker SwarmはDockerのコンテナだけでクラスタが構築できるので比較的簡単に使えそうです。
以前は上手くいかなかったDocker MachineやDocker Composeとの連携もできるようになっているので試してみたいです。