Edited at
DockerDay 7

docker swarm でホットデプロイを試してみよう

More than 1 year has passed since last update.


背景

個人のサービスをdockerで本番運用を行うにあたって


  • コンテナアップデート時のダウンタイムは無くしたい

  • 1つのサーバーで完結したい(別途ロードバランサーを用意したくない)

みたいなことを考えていたのですが、docker swarmを利用すると、とても簡単に実現できたので共有したいと思います。


検証環境

Docker version 17.10.0-ce, build f4ffd25


docker swarm の作成

managerのnodeが1つだけある環境を用意します。


swarmの作成

$ docker swarm init --advertise-addr="リモートのIPアドレス"



nodeの起動を確認

$ docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
qjdzkq17bxva02am04rou51dw * digitalocean Ready Active Leader


Serviceの作成

1つのサービスを2つのコンテナ(レプリカ)で作成します。


Serviceの作成

$ docker service create --name demo --replicas 2 --update-delay 10s -p 8080:8080 hashicorp/http-echo -listen=:8080 -text="demo-1"


今回の検証にはhashicorp/http-echoのイメージを使用しています。

これは起動時に引数で渡した文字列を表示してくれるWebサーバーのコンテナです。

https://hub.docker.com/r/hashicorp/http-echo/


Service起動の確認

--replicas 2を指定したのでコンテナが2つ作成できています。


コンテナの確認

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0dcff10b6c8 hashicorp/http-echo:latest "/http-echo -text=..." 10 hours ago Up 10 hours 5678/tcp demo.3.9zba9ygmdnjo764rt8fgprcip
baffe41b305d hashicorp/http-echo:latest "/http-echo -text=..." 24 hours ago Up 24 hours 5678/tcp demo.2.ydki5edzc2r1henjtw343el6f


動作の確認

$ curl http://サーバーIPアドレス:8080/

demo-1


Serviceのアップデート

docker service updateコマンドを利用すると、各コンテナを順にローリングアップデートしてくれます。アップデート中も一方のコンテナが起動しているので、サービスを継続しながらのアップデートが可能です。

起動時とは引数を変えてイメージをアップデートします。


Serviceのアップデート

$ docker service update --image hashicorp/http-echo --args  "-text="demo-2" -listen=:8080" demo

demo
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged

外部からウォッチしながらアップデートをすると次のようなログになります。

$ while true; do curl http://サーバーIPアドレス:8080/; sleep 1s; done

demo-1
demo-1
demo-1
demo-2 ←片方のコンテナがアップデート完了
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-1
demo-2
demo-2 ←両方のコンテナがアップデート完了
demo-2
demo-2

※今回はService作成時に--update-delay 10sを指定しているので、各コンテナのアップデートには10秒の間隔が空きます。


アップデートのロールバック

docker swarm rollbackコマンドを使えば、デプロイ後に問題が見つかった場合も、サービスを1世代前に戻すことができます。


ロールバック

$ docker service rollback demo

rollback: manually requested rollback
overall progress: rolling back update: 2 out of 2 tasks
1/2: running [> ]
2/2: running [> ]
verify: Service converged


動作の確認

$ curl http://サーバーIPアドレス:8080/

demo-1

rollbackコマンドは、Docker 17.09.0-ce以降で利用できます

https://docs.docker.com/release-notes/docker-ce/


参考

Apply rolling updates to a service

https://docs.docker.com/engine/swarm/swarm-tutorial/rolling-update/