はじめに
先日swarm manager1台/worker1台の構成で、おもむろにmanagerノードのOS再起動したらクラスタがぶっ壊れて悲しい思いをしたので、ちゃんとswarmクラスタのメンテナンス手順を調べました。
クラスタ運用する場合はスプリットブレインを避けるためにmanagerノードを3台以上立てるのが理想的ではありますが、開発環境などではそこまでリソースを割けないのでmanager1台運用にしてます。で、おもむろにmanagerを止めるとクラスタが壊れるので、安全にやるには一旦workerをmanagerに昇格してフェールオーバさせて、managerノードを再起動し、フェールバックさせるという手順を踏む必要があります。
前提となる構成
docker swarmは現在アクティブに開発されているので、バージョンによってコマンドやオプションが変わる可能性があります。
稼働確認したdockerバージョンは以下のとおりです。
$ docker version
Client:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:49:51 2016
OS/Arch: linux/amd64
Experimental: true
Server:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:49:51 2016
OS/Arch: linux/amd64
Experimental: true
manager1台でworker1台構成
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8whfywtdhji3dthpn8v0aymjx swarm-worker-i-058bd84d2dd57b5d2 Ready Active
codakltgk6yjnjoscffa8yh94 * swarm-manager Ready Active Leader
フェールオーバ
docker node promote (workerノードID)
でworkerをmanagerに昇格します。
$ docker node promote 8whfywtdhji3dthpn8v0aymjx
Node 8whfywtdhji3dthpn8v0aymjx promoted to a manager in the swarm.
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8whfywtdhji3dthpn8v0aymjx swarm-worker-i-058bd84d2dd57b5d2 Ready Active Reachable
codakltgk6yjnjoscffa8yh94 * swarm-manager Ready Active Leader
docker node update --availability drain (managerノードID)
で起動中のコンテナを他のノードに寄せます。
$ docker node update --availability drain codakltgk6yjnjoscffa8yh94
codakltgk6yjnjoscffa8yh94
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8whfywtdhji3dthpn8v0aymjx swarm-worker-i-058bd84d2dd57b5d2 Ready Active Reachable
codakltgk6yjnjoscffa8yh94 * swarm-manager Ready Drain Leader
ちなみにAVAILABILITYにpauseというのもありますが、新規のコンテナを振り分けなくなるだけで、pauseでは既存のコンテナは移動しないようです。
起動中のコンテナがいなくなるまで待ちます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
メンテナンス実施
OS再起動などメンテナンスを実施します。
$ sudo shutdown -r -h now
フェールバック
docker node update --availability active (managerノードID)
でnodeのAVAILABILITYをactiveに戻します
$ docker node update --availability active codakltgk6yjnjoscffa8yh94
codakltgk6yjnjoscffa8yh94
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8whfywtdhji3dthpn8v0aymjx swarm-worker-i-058bd84d2dd57b5d2 Ready Active Leader
codakltgk6yjnjoscffa8yh94 * swarm-manager Ready Active Reachable
docker node demote (workerノードID)
で一時的にmanagerに昇格していたノードをworkerに降格します
$ docker node demote 8whfywtdhji3dthpn8v0aymjx
Manager 8whfywtdhji3dthpn8v0aymjx demoted in the swarm.
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8whfywtdhji3dthpn8v0aymjx swarm-worker-i-058bd84d2dd57b5d2 Ready Active
codakltgk6yjnjoscffa8yh94 * swarm-manager Ready Active Leader
以上。
負荷をリバランスしたい場合は、現状コンテナを個別に再起動するしかなさそうです。
まとめ
swarm managerが1台しかなくても安全にフェールオーバ/フェールバックしてメンテナンスが実施できるようになりました。
これでクラスタがぶっ壊れて泣きながら再構築しなくても済むはず。dockerのバグを踏まなければね。。。