Docker Swarm
Docker Swarm とは複数の Docker ホストをまとめて、クラスタを作るためのツール。
Swarm クラスタでは Swarm マネージャが Docker ホストと同様に Docker サーバーとして動作する。Docker クライアントからは Swarm マネージャにコンテナ実行などのコマンドを送信でき、Swarm マネージャは送られた Docker コマンドを適切な Docker ホストに振り分けて実行する。
Swarm クラスタは外部からは 1 大の Docker ホストとして見えるため、Docker ホストに対応したツールとの連携が容易となる。
Swarm クラスタ内で独自のネットワークを構築することが可能であり、異なる Docker ホスト上のコンテナでもお互いに通信できるようになっている。
Docker Swarm クラスタの構成
Docker Swarm は以下の要素から構成されている。
- Swarm マネージャ: クラスタ全体を管理
- Swarm エージェント: 個々の Docker ホストを管理
- key-value ストア: クラスタの状態を保持する
Swarm マネージャや Swarm エージェントという Swarm ツール自体も Docker コンテナとして動作する。
Docker Swarm クラスタの構築
以下では実際に Docker Swarm クラスタを構築してみる。
Swarm クラスタは Docker ホストで直接動作させることもできるが、今回は Docker Machine で構築する。
key-value ストアは Consul を利用。
key-value ストア (Consul) の構築
Consul はコンテナ ( “progrium/consul” ) として提供されているので、Docker ホストを構築し、その上で Consul を稼働させる。
まずは Docker ホストを swarm-keystore という名前で作成。
$ docker-machine create -d amazonec2 --amazonec2-region ap-northeast-1 \
--amazonec2-zone a \
--amazonec2-instance-type t2.large \
--amazonec2-root-size "50" \
--amazonec2-vpc-id vpc-xxxxxxxxx \
--amazonec2-subnet-id subnet-xxxxxxxx \
--amazonec2-security-group YourSecurityGroupName \
swarm-keystore
上記で起動した Docker ホスト上に progrium/consul を用いてコンテナを実行。
$ eval $(docker-machine env swarm-keystore)
$ docker run -d -p 8500:8500 -h consul progrium/consul -server -bootstrap
念の為確認してみる。
$ docker-machine ssh swarm-keystore
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-1020-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
118 packages can be updated.
42 updates are security updates.
Last login: Tue Nov 7 15:16:21 2017 from 13.115.204.186
ubuntu@swarm-keystore:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98c35ef0b72f progrium/consul "/bin/start -serve..." 18 seconds ago Up 16 seconds 53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8301-8302/udp, 0.0.0.0:8500->8500/tcp quizzical_bose
ちゃんと起動している。
Docker ホストの IP アドレスを確認し、Consul が動作しているか確認。
具体的にはキー “key1” に値 “value1” を設定する。
$ docker-machine ip swarm-keystore
13.115.140.247
$ curl -X PUT -d 'value1' http://13.115.140.247:8500/v1/kv/key1
true
$ curl http://13.115.140.247:8500/v1/kv/key1
[{"CreateIndex":13,"ModifyIndex":13,"LockIndex":0,"Key":"key1","Flags":0,"Value":"dmFsdWUx"}]
$ echo "dmFsdWUx" | base64 --decode
value1
なお、ブラウザからもアクセス可能。
Docker ホストの構築
docker-machine create
コマンドに --swarm
オプションを指定することで、Docker ホストを Swarm クラスタとして構築する。
Swarm マネージャーを動作させる Docker ホストでは --swarm-master
オプションも指定し、Swarm マネージャーのコンテナを実行する。
key-value ストアには先ほど構築した Consul を指定。
なお、docker-machine で AWS 上に Docker ホストを起動した際は基本的に Public IP を Docker ホストの IP アドレスとして認識するっぽい…
[ Swarm マネージャー用ホスト ]
$ docker-machine create -d amazonec2 \
--amazonec2-region ap-northeast-1 \
--amazonec2-zone a \
--amazonec2-instance-type t2.large \
--amazonec2-root-size "50" \
--amazonec2-vpc-id vpc-xxxxxxxx \
--amazonec2-subnet-id subnet-xxxxxxxx \
--amazonec2-security-group YourSecurityGroup \
--swarm \
--swarm-master \
--swarm-discovery="consul://13.115.140.247:8500/" \
--engine-opt="cluster-store=consul://13.115.140.247:8500" \
--engine-opt="cluster-advertise=eth0:2376" \
swarm-manager
Running pre-create checks...
Creating machine...
(swarm-manager) Launching instance...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ubuntu(systemd)...
Installing Docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Configuring swarm...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env swarm-manager
[ Swarm Node ]
# Node 1
$ docker-machine create -d amazonec2 \
--amazonec2-region ap-northeast-1 \
--amazonec2-zone a \
--amazonec2-instance-type t2.large \
--amazonec2-root-size "50" \
--amazonec2-vpc-id vpc-xxxxxxxx \
--amazonec2-subnet-id subnet-xxxxxxxx \
--amazonec2-security-group YourSecurityGroup \
--swarm \
--swarm-discovery="consul://13.115.140.247:8500/" \
--engine-opt="cluster-store=consul://13.115.140.247:8500" \
--engine-opt="cluster-advertise=eth0:2376" \
swarm-node1
# Node 2
$ docker-machine create -d amazonec2 \
--amazonec2-region ap-northeast-1 \
--amazonec2-zone c \
--amazonec2-instance-type t2.large \
--amazonec2-root-size "50" \
--amazonec2-vpc-id vpc-xxxxxxxx \
--amazonec2-subnet-id subnet-xxxxxxxx \
--amazonec2-security-group YourSecurityGroup \
--swarm \
--swarm-discovery="consul://13.115.140.247:8500/" \
--engine-opt="cluster-store=consul://13.115.140.247:8500" \
--engine-opt="cluster-advertise=eth0:2376" \
swarm-node2
構築した Swarm クラスタの確認
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
swarm-keystore * amazonec2 Running tcp://13.115.140.247:2376 v17.10.0-ce
swarm-manager - amazonec2 Running tcp://13.112.139.104:2376 swarm-manager (master) v17.10.0-ce
swarm-node1 - amazonec2 Running tcp://13.230.3.210:2376 swarm-manager v17.10.0-ce
swarm-node2 - amazonec2 Running tcp://52.68.237.52:2376 swarm-manager v17.10.0-ce
-> 全て Public IP なのが気になる…
$ docker-machine ssh swarm-manager
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-1020-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
118 packages can be updated.
42 updates are security updates.
swarm-manager の待ち受けポートを確認する。
ubuntu@swarm-manager:~$ sudo netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 10.1.11.136:7946 0.0.0.0:* LISTEN 10221/dockerd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1330/sshd
tcp6 0 0 :::2376 :::* LISTEN 10221/dockerd
tcp6 0 0 :::3376 :::* LISTEN 10482/docker-proxy
tcp6 0 0 :::22 :::* LISTEN 1330/sshd
2376 で Docker ( dockerd ) が、3376 で Swarm マネージャー ( docker-proxy ) が待ち受けている。
Docker クライアントは 3376 番の Swarm マネージャーに接続することで、Swarm クラスタを利用できる。
consul でも node の情報に関する key が登録されている。
-> ここではなぜか Private IP が指定されている…。どこかのレイヤーがよしなにやってくれているようだが、そこまでは追求しないでおくか。
Docker Swarm を利用する
以下のコマンドで Swarm クラスタの状態を確認できる。
$ eval $(docker-machine env --swarm swarm-manager)
$ docker info
Containers: 4
Running: 4
Paused: 0
Stopped: 0
Images: 3
Server Version: swarm/1.2.8
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint, whitelist
Nodes: 3
swarm-manager: 13.112.139.104:2376
└ ID: 72NB:ROJB:MVQ5:5626:BDNQ:6PVS:IGCF:Y6LE:LT3H:WBPN:43CZ:DYGK|13.112.139.104:2376
└ Status: Healthy
└ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 2
└ Reserved Memory: 0 B / 8.185 GiB
└ Labels: kernelversion=4.4.0-1020-aws, operatingsystem=Ubuntu 16.04.2 LTS, ostype=linux, provider=amazonec2, storagedriver=aufs
└ UpdatedAt: 2017-11-07T17:00:42Z
└ ServerVersion: 17.10.0-ce
swarm-node1: 13.230.3.210:2376
└ ID: EKS3:RI3Y:R2OU:4RM7:7PZV:5SST:5HYI:GFVM:LYTT:GFMX:3NGU:TS5I|13.230.3.210:2376
└ Status: Healthy
└ Containers: 1 (1 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 2
└ Reserved Memory: 0 B / 8.185 GiB
└ Labels: kernelversion=4.4.0-1020-aws, operatingsystem=Ubuntu 16.04.2 LTS, ostype=linux, provider=amazonec2, storagedriver=aufs
└ UpdatedAt: 2017-11-07T17:00:27Z
└ ServerVersion: 17.10.0-ce
swarm-node2: 52.68.237.52:2376
└ ID: B2PQ:KEO6:PF6Q:GZCN:GPQL:MRPA:YZM5:DEW3:SZLF:O5QE:K7KS:NJCH|52.68.237.52:2376
└ Status: Healthy
└ Containers: 1 (1 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 2
└ Reserved Memory: 0 B / 8.185 GiB
└ Labels: kernelversion=4.4.0-1020-aws, operatingsystem=Ubuntu 16.04.2 LTS, ostype=linux, provider=amazonec2, storagedriver=aufs
└ UpdatedAt: 2017-11-07T17:00:40Z
└ ServerVersion: 17.10.0-ce
Plugins:
Volume:
Network:
Log:
Swarm:
NodeID:
Is Manager: false
Node Address:
Kernel Version: 4.4.0-1020-aws
Operating System: linux
Architecture: amd64
CPUs: 6
Total Memory: 24.56GiB
Name: d128bd6f0925
Docker Root Dir:
Debug Mode (client): false
Debug Mode (server): false
Experimental: false
Live Restore Enabled: false
WARNING: No kernel memory limit support
swarm-manager 、swarm-node1 、swarm-node2 で構成されるクラスタであることが確認できる。
コンテナも確認。
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af344e852149 swarm:latest "/swarm join --adv..." 21 minutes ago Up 21 minutes 2375/tcp swarm-node2/swarm-agent
7e37c2f772e2 swarm:latest "/swarm join --adv..." 21 minutes ago Up 21 minutes 2375/tcp swarm-node1/swarm-agent
c366400e9c30 swarm:latest "/swarm join --adv..." 23 minutes ago Up 23 minutes 2375/tcp swarm-manager/swarm-agent
d128bd6f0925 swarm:latest "/swarm manage --t..." 23 minutes ago Up 23 minutes 2375/tcp, 13.112.139.104:3376->3376/tcp swarm-manager/swarm-agent-master
-> Swarm クラスタ周りのコンテナが確認できる。
試しに nginx コンテナを 6 個動かす。
$ docker run -d nginx
b81c5abe67ed956a61b0a0dda98bcd0399dca6116ed5d99d9f35212bc2763683
$ docker run -d nginx
9dc4c90e580e036f80a947e7a0b8cc408b05ed58ed2590a644a276fa7c44ff99
$ docker run -d nginx
631f5867b08e75f9723f2d9800d0601929276f2301a5f15c4e844395932fa52e
$ docker run -d nginx
9e6fbf5ff31484789a9baadbe8bafe5b58557239701517da1430c341cc80c78e
$ docker run -d nginx
10e8c8859a62c14f0a62fc8ff905e9a875502968d853c46804567ee276fa2b8e
$ docker run -d nginx
6a1bfbf4af43ef31a7a7a7c17fea6951aa2fbf7a6a3131566c18cafe54b85834
$ docker run -d httpd
この際最初の三つはそれぞれの Docker ホストのローカルにイメージが存在しないため、ちょっと時間がかかる。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a1bfbf4af43 nginx "nginx -g 'daemon ..." 2 minutes ago Up 2 minutes 80/tcp swarm-node1/eager_ride
10e8c8859a62 nginx "nginx -g 'daemon ..." 2 minutes ago Up 2 minutes 80/tcp swarm-node2/lucid_murdock
9e6fbf5ff314 nginx "nginx -g 'daemon ..." 2 minutes ago Up 2 minutes 80/tcp swarm-node1/focused_einstein
631f5867b08e nginx "nginx -g 'daemon ..." 2 minutes ago Up 2 minutes 80/tcp swarm-manager/zen_franklin
9dc4c90e580e nginx "nginx -g 'daemon ..." 3 minutes ago Up 3 minutes 80/tcp swarm-node2/nervous_northcutt
b81c5abe67ed nginx "nginx -g 'daemon ..." 3 minutes ago Up 3 minutes 80/tcp swarm-node1/suspicious_stallman
-> 三つのノードに分散されていることがわかる。