Docker Swarmの概要
マネージャとノード
Docker Swarmはコンテナオーケストレーションツールの1種。マネージャとノードという2つの役割があり、マネージャはコントロールプレーンの機能を持つ。
ただし、他のオーケストレーションツールのコントロールプレーンと異なり、マネージャ自身もノードとしてコンテナを抱えるほか、ノードが落ちた際に他の別のノードにコンテナを割り当てる程度のことしかしない。
マネージャ以上の役割はconsul等のサードパーティ製ツールをSwarmネットワーク内のどこかにインストールして補うことが必要となっている。
マネージャはRaftアルゴリズムを用いるため奇数が望ましいとされる。実際にマネージャを偶数にするとWarningが出るようになっており、運用の際は3つないし5つのマネージャを立てることが想定される。マネージャ自身がノードでもあるので、小規模の場合はマネージャ3機というケースが想定される。
サービスとingress
マネージャはサービス毎に必要数のコンテナを立ち上げるようにプログラムされており、コンテナはサービスに対する通信をingressネットワークにより割り振られる。つまり自動的にロードバランサが配置される。ingressのロードバランシングで十分であれば、ロードバランサを別途立てる必要はない。
AWSインフラの設定
EC2インスタンスを立てる
領域はAZ=a1のパブリックネットワークとした。private領域に立てたかったのだが、privateサブネットからアウトバウンドの経路を確保するためにはインターネットゲートウェイまたはその他のエンドポイントを作る必要があり、費用がかかってしまう為断念。
-
タグ
- Name: Sandbox-***
- swarm-manager-0: プライマリマネージャ
- swarm-manager-1: セカンダリマネージャ
- swarm-manager-2: セカンダリマネージャ
- swarm-node-1: ノード
- swarm-node-2: ノード
- Unit: Sandbox
- Name: Sandbox-***
-
OSイメージ: AL2 64(x86)
-
タイプ: t2 micro(無料利用枠の対象)
-
セキュリティグループ: Sandbox-public-web-maintenance
-
キーペア
- Sandbox内で共通のキー(Sandbox-master-key)を設定する。
- タイプ: RSA
- 拡張子: pem
- キーがダウンロードされるので、保存してパーミッションを400に変更。
-
パブリック IP の自動割り当て: 有効化
- 後で逐一割り当ててもよい
- このIPはインスタンス再起動ごとに可変なので、サンドボックス的にはさほど嬉しくない
-
ストレージ: 最小の8BiBでEBSボリュームを構築
- 合計30GiBまでは無料の範囲だが、それを越えても1GiB辺り月額0.08$なのでOK
セッションマネージャ
費用が掛かるのであきらめた
AWS: 『Session Manager のセットアップ』
以下のような流れで利用可能になる。
- Session Manager APIに向けたエンドポイントを作成
- IAMロールを作成、セッションマネージャに関する権限を許可してEC2インスタンスに割り振る
- ユーザに割り振るわけではないので注意
- システムマネージャのクイックセットアップを実行
セッションマネージャ用の必須のエンドポイント以下の4つ
- com.amazonaws.region.ssm
- com.amazonaws.region.ec2messages
- com.amazonaws.region.ssmmessages
- com.amazonaws.region.s3 これらを全て建てると料金がかさみ、通常はpublic領域に踏み台EC2を立てた方が安く済む。
参考: DevelopersIO: 『そのセッションマネージャー、本当に必要?プライベートサブネットのEC2への通信方法を考えてみる』
リーチャビリティアナライザ
リソース間の接続が通らない場合、どこでスタックしているか分析できる。VPCコンソールの中に入っている。リソースからリソースの間のパスを設定したものを保存し、保存された設定を用いて分析を行う。
設定を所有しているだけでは無料だが、分析の度に0.10USD(2022/10/03 現在)がかかる。それなりに高いので注意。
インストール・セットアップ
Docker Engineインストール
Docker SwarmはAmazon Linux 2の場合、Docker Engineに同梱されている様子。
sudo amazon-linux-extras install -y docker
sudo systemctl enable --now docker && systemctl is-enabled docker && systemctl status docker
docker run hello-world
# この段階ではパーミッションの関係でエラーになる
ユーザ設定
作業ユーザにdockerの実行権限を与える。
grep docker /etc/group
sudo usermod -a -G docker ec2-user
ログアウトして再ログイン後、再度docker runを試す。
docker run hello-world
# 今度は成功する
Swarmマネージャの作成
以下のコマンドで最初のマネージャを立ち上げる。
docker swarm init --advertise-addr <manager-0 IP>
# 以下のようなトークンを含むメッセージが出力される
To add a worker to this swarm, run the following command:
docker swarm join --token <node token> <manager-0 IP>:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
指示に従ってノードを設定する。
# node-0
docker swarm join --token <node token> <manager-0 IP>:2377
# node-1
docker swarm join --token <node token> <manager-0 IP>:2377
ノード用のトークンは以下のコマンドで確認できる。
docker swarm join-token worker
サブのマネージャを立ち上げる。
# manager-0
docker swarm join-token manager
# 以下のようにトークンが表示される
To add a manager to this swarm, run the following command:
docker swarm join --token <manager token> <manager-0 IP>:2377
# manager-1
docker swarm join --token <token> <manager-0 IP>:2377
# manager-2
docker swarm join --token <token> <manager-0 IP>:2377
登録したノードの状態を確認。
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3w6p2wzfa7flp5z02idm6bub9 ip-10-0-0-235.ap-northeast-1.compute.internal Ready Active 20.10.17
atqoukct4t4azfo7pprpyui18 ip-10-0-3-18.ap-northeast-1.compute.internal Ready Active Reachable 20.10.17
ik1o754n0xn19n8sugo6ae44z * ip-10-0-3-183.ap-northeast-1.compute.internal Ready Active Leader 20.10.17
ll8v6mpxj9jioogxf92l68itg ip-10-0-4-168.ap-northeast-1.compute.internal Ready Active 20.10.17
v2nfuds30yo33lfqplpolqp9p ip-10-0-14-51.ap-northeast-1.compute.internal Ready Active Reachable 20.10.17
サービスをswarmに追加する
docker service create --replicas 1 --name helloworld alpine ping docker.com
alpineのdocker imageにping docker.comを渡してコンテナを作成。1種類のサービスに1つのレプリカが存在することが確認できる。このケースではnode-1でコンテナが立ち上がった。
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
ka92leyw2nua helloworld replicated 1/1 alpine:latest
docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lzazrvblzj17 helloworld.1 alpine:latest ip-10-0-0-235.ap-northeast-1.compute.internal Running Running 4 minutes ago
以下のコマンドでサービスを削除。
docker service rm helloworld
複製の数を増やして挙動を確かめる
試験用イメージの作成
コンテナ外から"curl localhost"すると、でdockerコンテナのIDが取得できるだけのWebサーバ内臓コンテナを作る。
docker run -d -p 80:80 php:apache
docker exec -it 5f8734a5e46d /bin/bash
echo "<?php" > index.php
echo "echo 'I am ' . gethostname() . PHP_EOL;" > index.php
apt update && apt install nano
応答を確認してOKならコミット。Docker hubに登録しておくとノードでインスタンスをpullして立ち上げてくれる。
docker login
docker commit 5f8734a5e46d mingsiro71/replyhost
docker push mingsiro71/replyhost
サービスを立てる
docker service create --replicas 8 --name reply --publish published=80,target=80 mingsiro71/replyhost
docker service ps reply
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
vhnnw3m2jwzb reply.1 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 30 seconds ago
o53q8wjmm0jh reply.2 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Running Running 46 seconds ago
r6awxvrxtlz4 reply.3 mingsiro71/replyhost:latest ip-10-0-4-168.ap-northeast-1.compute.internal Running Running 19 seconds ago
qtk5hnul8ccu reply.4 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 31 seconds ago
1fysxtkvseko reply.5 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Running Running 30 seconds ago
xl2gelheygid reply.6 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 30 seconds ago
53xv3tu2fdht reply.7 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Running Running 46 seconds ago
l1gbtycjg06q reply.8 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Running Running 30 seconds ago
各ノードに均等に分散してコンテナが立てられることが分かる。また、実際にcurlでリクエストを投げてやると
curl localhost
I am 33a882a6a259
curl localhost
I am a7bbf9a4e3b2
...
こんな感じでロードバランシングが効いている。どうやら各コンテナが上がりきるまでタイムラグがある様子なので、監視機能は合った方が便利かも。
サービス間の通信を確認する
同じイメージを使って追加で5個、別名で立ててインスタンス内から通信を試みる。
docker service create --replicas 5 --name reply2 mingsiro71/replyhost
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kz939p2szcun reply replicated 8/8 mingsiro71/replyhost:latest *:80->80/tcp
piyyj9bf7ylh reply2 replicated 5/5 mingsiro71/replyhost:latest
docker exec -it a6311f5020d9 /bin/bash
curl reply
# つながらない
今度はネットワークを作成して、ネットワーク上にサービスを展開する。
docker network create -d overlay my-overlay
docker service create --replicas 5 --name reply --network my-overlay mingsiro71/replyhost
docker service create --replicas 5 --name reply2 --network my-overlay mingsiro71/replyhost
こうするとどちらのコンテナも相手のコンテナと疎通することができる。外からの接続を考えずにコンテナ間でやり取りする分にはポート指定が不要。
可用性のチェック
ノードを落としてみる
1つのサービスを5つのレプリカで立ち上げた状態からノードを落とすと、代わりのレプリカが別のノードで立ち上がる。
docker service create --replicas 5 -p 8080:80 --name reply --network my-overlay mingsiro71/replyhost
docker service ps reply
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bg1niweytzwa reply.1 mingsiro71/replyhost:latest ip-10-0-4-168.ap-northeast-1.compute.internal Running Running 11 seconds ago
pyr9gy4tz9qn reply.2 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 12 seconds ago
y9ycol61ergj reply.3 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Running Running 12 seconds ago
4ntx13c4kxry reply.4 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 12 seconds ago
c90tewvduu6t reply.5 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Running Running 11 seconds ago
# node-1を停止
docker service ps reply
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bg1niweytzwa reply.1 mingsiro71/replyhost:latest ip-10-0-4-168.ap-northeast-1.compute.internal Running Running about a minute ago
pyr9gy4tz9qn reply.2 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running about a minute ago
jp0eytdnj0z2 reply.3 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 10 seconds ago
y9ycol61ergj \_ reply.3 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Shutdown Running about a minute ago
4ntx13c4kxry reply.4 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running about a minute ago
c90tewvduu6t reply.5 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Running Running about a minute ago
マネージャを落としてみる
リーダーが変更され、レプリカも別のノードに割り当てられる。
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3w6p2wzfa7flp5z02idm6bub9 ip-10-0-0-235.ap-northeast-1.compute.internal Down Active 20.10.17
atqoukct4t4azfo7pprpyui18 ip-10-0-3-18.ap-northeast-1.compute.internal Ready Active Leader 20.10.17
ik1o754n0xn19n8sugo6ae44z ip-10-0-3-183.ap-northeast-1.compute.internal Unknown Active Unreachable 20.10.17
ll8v6mpxj9jioogxf92l68itg ip-10-0-4-168.ap-northeast-1.compute.internal Ready Active 20.10.17
v2nfuds30yo33lfqplpolqp9p * ip-10-0-14-51.ap-northeast-1.compute.internal Ready Active Reachable 20.10.17
docker service ps reply
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bg1niweytzwa reply.1 mingsiro71/replyhost:latest ip-10-0-4-168.ap-northeast-1.compute.internal Running Running 59 seconds ago
pyr9gy4tz9qn reply.2 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running about a minute ago
jp0eytdnj0z2 reply.3 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running about a minute ago
y9ycol61ergj \_ reply.3 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Shutdown Running 6 minutes ago
4ntx13c4kxry reply.4 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 56 seconds ago
j47qujpxxqr6 reply.5 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 29 seconds ago
c90tewvduu6t \_ reply.5 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Shutdown Running 6 minutes ago
マネージャを復活させる
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3w6p2wzfa7flp5z02idm6bub9 ip-10-0-0-235.ap-northeast-1.compute.internal Down Active 20.10.17
atqoukct4t4azfo7pprpyui18 ip-10-0-3-18.ap-northeast-1.compute.internal Ready Active Leader 20.10.17
ik1o754n0xn19n8sugo6ae44z ip-10-0-3-183.ap-northeast-1.compute.internal Ready Active Reachable 20.10.17
ll8v6mpxj9jioogxf92l68itg ip-10-0-4-168.ap-northeast-1.compute.internal Ready Active 20.10.17
v2nfuds30yo33lfqplpolqp9p * ip-10-0-14-51.ap-northeast-1.compute.internal Ready Active Reachable 20.10.17
Reachableにはなるが、リーダーは入れ替わったまま運用されることが分かる。またノードは以下のように変更が発生しない。他の要因でノードの変更が起きない限り一度落ちてしまったノードの持ち主は手が空いた状態になる。
docker service ps reply
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bg1niweytzwa reply.1 mingsiro71/replyhost:latest ip-10-0-4-168.ap-northeast-1.compute.internal Running Running 3 minutes ago
pyr9gy4tz9qn reply.2 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 3 minutes ago
jp0eytdnj0z2 reply.3 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 3 minutes ago
y9ycol61ergj \_ reply.3 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Shutdown Running 9 minutes ago
4ntx13c4kxry reply.4 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 3 minutes ago
j47qujpxxqr6 reply.5 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 2 minutes ago
c90tewvduu6t \_ reply.5 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Shutdown Shutdown 58 seconds ago
updateでも再配分されない。この辺は実際の運用時に考えもの。
docker service update reply
docker service ps reply
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bg1niweytzwa reply.1 mingsiro71/replyhost:latest ip-10-0-4-168.ap-northeast-1.compute.internal Running Running 6 minutes ago
pyr9gy4tz9qn reply.2 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 6 minutes ago
jp0eytdnj0z2 reply.3 mingsiro71/replyhost:latest ip-10-0-14-51.ap-northeast-1.compute.internal Running Running 6 minutes ago
y9ycol61ergj \_ reply.3 mingsiro71/replyhost:latest ip-10-0-0-235.ap-northeast-1.compute.internal Shutdown Running 12 minutes ago
4ntx13c4kxry reply.4 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 6 minutes ago
j47qujpxxqr6 reply.5 mingsiro71/replyhost:latest ip-10-0-3-18.ap-northeast-1.compute.internal Running Running 6 minutes ago
c90tewvduu6t \_ reply.5 mingsiro71/replyhost:latest ip-10-0-3-183.ap-northeast-1.compute.internal Shutdown Shutdown 4 minutes ago
(参考)使用するポートについて
Open protocols and ports between the hosts
The following ports must be available. On some systems, these ports are open by default.
TCP port 2377 for cluster management communications
TCP and UDP port 7946 for communication among nodes
UDP port 4789 for overlay network traffic
If you plan on creating an overlay network with encryption (--opt encrypted), you also need to ensure ip protocol 50 (ESP) traffic is allowed
2377/TCPはマネージャとの通信、7946/TCPはノード間の通信、4789/UDPはオーバーレイネットワークの通信に利用する、とある。 実際にセキュリティグループでの制御は試していないが、プロダクションでギリギリまでポートを閉める際には要参照。
Back to prev page