背景
過去に大好評だったDocker入門の内容を2016年版にupdateした再入門投稿3本が終わったので、
まだ紹介していない機能を投稿していきます。
- Docker Compose 入門
- Docker Machine 入門(Hyper-Vの場合)
- Docker Machine 入門(AWSの場合)
- Docker 再入門3 2016
- Docker 再入門2 2016
- Docker 再入門1 2016
- Docker 入門 (SlideShare)
動作環境
- ThinkPad X200s OS:Linux MINT 18
- ThinkPad X1 Carbon OS:Windows 10 Pro (Hyper-V)
個人的に開発環境OSはLinuxが主なので、MacOSやWindowsについては優先度が低いのでご了承ください。
Docker 1.12(docker swarm mode)
複数のホストでDockerコンテナのクラスタを構築する場合、専用のDocker Swarmイメージを使用してクラスタ構築を実現していました。
2016年にリリースされたDocker 1.12からはDocker Engineに統合されてswarm modeとして構築する事が可能になりました。
- Swarm mode overview(docker.com)
Dockerクラスタの構築
通常のwebサイトではクラスタ構築は馴染みが無いかもしれませんが、冗長化や負荷分散といった効果がありますので、積極的に使って行きたいですね。
では、公式ドキュメントを参考にDockerクラスタを構築してみましょう。
クラスタのノードを3ホスト用意する
まず最初に3つのホストをdocker-machineで作成します。
ここでは例として、Windows 10 Pro(Hyper-V)上にBoot2Dockerのホストを3つ(node1,node2,node3)作成してみました。
docker-machine create -d hyperv --hyperv-virtual-switch "Primary Virtual Switch" node1
docker-machine create -d hyperv --hyperv-virtual-switch "Primary Virtual Switch" node2
docker-machine create -d hyperv --hyperv-virtual-switch "Primary Virtual Switch" node3
動作状況を確認しておきます。
PS C:\WINDOWS\system32> docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node1 - hyperv Running tcp://192.168.99.11:2376 v1.12.3
node2 - hyperv Running tcp://192.168.99.12:2376 v1.12.3
node3 - hyperv Running tcp://192.168.99.13:2376 v1.12.3
パラメーターのSWARMにステータスが無い事が確認出来ます。これがDockerの通常モードです。
親ノード(manager)の設定
全てのノードの元になる親ノード(manager)を設定します。ここではnode1のホストを親ノード(manager)とします。
docker-machineコマンドでnode1ホストにSSHログインします。
そしてdockerコマンドでswarm modeに初期化します。IPアドレスはnode1ホストの番号を指定する事でサービスが開始されます。
PS C:\WINDOWS\system32> docker-machine ssh node1
docker@node1:~$ docker swarm init --advertise-addr 192.168.99.11
Swarm initialized: current node (28d8rbrnzxz4ktgmhhattzc52) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-0z7y5jvysq0kuwao3itq783ncslyxw3ugn1l5w9l4k64z83lzi-9v684gv2g9tp28blu3hvhplrd \
192.168.99.11:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
表示文中のコマンド例は、別の追加する子ノード(worker)上で実行するモノで、これをメモしておきましょう。
また最終行にあるコマンド'docker swarm join-token manager'で再表示も可能です。
swarm modeへの変更を確認してみましょう。
docker@node1:~$ docker info
・・・中略・・・
Swarm: active
NodeID: 28d8rbrnzxz4ktgmhhattzc52
Is Manager: true
ClusterID: 5t03nqvt7btkh1y88dfsb2f2t
Managers: 1
Nodes: 1
swarm modeが有効になって、ID表示がされています。
全ノードの状態表示をして確認してみましょう。
docker@node1:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
28d8rbrnzxz4ktgmhhattzc52 * node1 Ready Active Leader
親ノード(manager)として動作していることが確認できます。
子ノード(worker)の追加設定
それでは、他のホストを子ノードとして設定しましょう。
docker-machineコマンドでnode2ホストにSSHログインします。
そしてdockerコマンドで先程メモしたコマンドを入力して実行します。
PS C:\WINDOWS\system32> docker-machine ssh node2
docker@node2:~$ docker swarm join \
> --token SWMTKN-1-0z7y5jvysq0kuwao3itq783ncslyxw3ugn1l5w9l4k64z83lzi-9v684gv2g9tp28blu3hvhplrd \
> 192.168.99.11:2377
This node joined a swarm as a manager.
無事に子ノード(worker)が追加されたら同じようにnode3ホストも設定します。
全クラスタの動作確認
親ノード(manager)にSSHログインしてノード状態を表示してみます。
PS C:\WINDOWS\system32> docker-machine ssh node1
docker@node1:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
28d8rbrnzxz4ktgmhhattzc52 * node1 Ready Active Leader
7yt8lf2zmcxt16dkcw5b4ors1 node2 Ready Active Reachable
877vnv6x40xzd6uf8c2i0rvdp node3 Ready Active Reachable
サービスをデプロイ
それでは親ノード(manager)にDockerコンテナのサービスをデプロイしてみます。
例として、AlpineLinuxでdocker.comへpingする単純なコンテナです。
Dockerコンテナ名にhelloworldを付けています。
docker@node1:~$ docker service create --replicas 1 --name helloworld alpine ping docker.com
0vu955zjrfh294mw1ivdzdr67
作成したDockerコンテナサービス(helloworld)の状態表示をしてみます。
docker@node1:~$ docker service ls
ID NAME REPLICAS IMAGE COMMAND
0vu955zjrfh2 helloworld 1/1 alpine ping docker.com
docker@node1:~$ docker service inspect --pretty helloworld
ID: 0vu955zjrfh294mw1ivdzdr67
Name: helloworld
Mode: Replicated
Replicas: 1
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
ContainerSpec:
Image: alpine
Args: ping docker.com
Resources:
docker@node1:~$ docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
f0i0te74m5in3qehhtgkg1yfv helloworld.1 alpine node1 Running Running 2 minutes ago
docker@node1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
a1e9f32ec207 alpine:latest "ping docker.com" 3 minutes ago Up 3 minutes helloworld.1.f0i0te74m5in3qehhtgkg1yfv
親ノード(manager)でDockerコンテナ(helloworld)のサービスが稼動している状況が確認できました。
子ノード(worker)へスケール
親ノード(manager)で動作しているDockerコンテナのサービス(helloworld)を子ノード(worker)へスケールさせてみましょう。
docker@node1:~$ docker service scale helloworld=5
helloworld scaled to 5
このコマンドでは、親ノード(manager)で動作しているhelloworldのコンテナを5個スケールさせています。
ノードの数は全部で3個ですが、どうなるでしょう。
docker@node1:~$ docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
f0i0te74m5in3qehhtgkg1yfv helloworld.1 alpine node1 Running Running 6 minutes ago
1p3u9x2po7vlgfph2vw2stqt0 helloworld.2 alpine node2 Running Running 23 seconds ago
2rxzqe66wdyd4tao016ktcmh8 helloworld.3 alpine node1 Running Running 25 seconds ago
5xrj8yxz54faehzr591xjqb9k helloworld.4 alpine node3 Running Running 23 seconds ago
5vpxaiqy8slos9j81bmuydy7m helloworld.5 alpine node2 Running Running 23 seconds ago
1個のノードに複数のDockerコンテナサービスが稼働しています。
node1のホストでも2個のDockerコンテナサービスが稼働しているので確認してみましょう。
docker@node1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
166d6e7a8dbe alpine:latest "ping docker.com" About a minute ago Up About a minute helloworld.3.2rxzqe66wdyd4tao016ktcmh8
a1e9f32ec207 alpine:latest "ping docker.com" 7 minutes ago Up 7 minutes helloworld.1.f0i0te74m5in3qehhtgkg1yfv
最初に実行したオリジナルのDockerコンテナの他にもう1個のDockerコンテナが実行されているのが確認できます。
この様にして1つのDockerコンテナを複数のホストにスケールする事でクラスタが構築出来ます。
後片付け方法
複数のホストで複数のDockerコンテナで構成されたクラスタですが、コマンド1つで簡単に消す事が出来ます。
docker@node1:~$ docker service rm helloworld
helloworld
docker@node1:~$ docker service inspect helloworld
[]
Error: no such service: helloworld