Swarmでもローリングアップデートは可能です。公式のドキュメントはこちらです。Swarmにおけるローリングアップデートの動作を確認したいと思います。とくに気にしている点は以下の6つです。
- composeファイルを使用した場合の方法
- 旧バージョンに戻したいときはどうするか
- アップデート後、旧バージョンが残るか
- update-delayの動作
- 新旧バージョンが混在しているときのルーティング
- replicas:1の時のローリングアップデート
確認結果を先に書くと以下の通りでした。
確認結果サマリ
観点 | 検証結果 | 詳細 |
---|---|---|
composeファイルを使用した場合の方法 | composeファイル内のイメージ指定を書き換えてdocker stack deploy すれば良い。 |
ここ |
旧バージョンに戻したいときはどうするか | イメージ指定を再修正しcomposeファイルを再デプロイする。またはdocker service rollbackコマンドで戻す。どちらの場合も結果は同じになる。後者の場合はcomposeファイルと実機の状態に差分が出るためあまりオススメしない。 | ここ |
アップデート後、旧バージョンが残るか | タスクの履歴としては残るがコンテナとしては削除される。タスク履歴はデフォルトでは5つまで残る。 | ここ |
update-delayの動作 | 前のタスクが更新完了(Running)してから次のタスクを更新するまでの待ち時間。 | ここ |
新旧バージョンが混在しているときのルーティング | 新旧関係なくラウンドロビンで振り分けられる。 | ここ |
replicas:1のときのローリングアップデート | stop-firstの場合は切り替わり時に断が発生する。start-firstの場合は切り替わり中の振り分けが新旧混在する | ここ |
検証準備
クラスタ構成
AWSのEC2にdockerをインストールしています。dockerのバージョンは20.10.7です。EC2は全部で5台あります。マネージャ3台、ワーカー2台です。マネージャはdrainしてあるのでコンテナはスケジュールされません。クラスタを構成するノード間はポート8000の通信をSGのインバウンドで許可しています。デプロイなどの操作は基本的にマネージャで行います。
コンテナイメージの準備
検証用のコンテナとしてcurlするとバージョンを表示するNginxのコンテナイメージを用意します。以下Dockerfileでビルドしたものです。RUNの<バージョン>
部分を変えてv1
とv2
の2つのイメージをビルドします。イメージ名はryotamori/swarm-rollingup-nginx:<バージョン>
といった具合です。ビルドしたらdocker hubにpushしておきます。
FROM nginx:1.21
RUN echo <バージョン> > /usr/share/nginx/html/index.html
テスト用composeファイルの準備
以下のシンプルなcomposeファイルを準備します。ノード間はポート8000を許可してあるのでポート8000で公開します。イメージのタグ、deployの設定、レプリカ数は検証の中で変えていきます。
version: "3.9"
services:
rollingupdate:
image: ryotamori/swarm-rollingup-nginx:v1
deploy:
replicas: 1
ports:
- 8000:80
上記composeファイルを以下のコマンドでデプロイします。
$ docker stack deploy -c ./rolling-update.yaml test
マネージャノードで以下のようにcurlするとデプロイしたタスクにアクセスできます。
$ curl 127.0.0.1:8000
v1
検証
普通にやってみる
ベースのcomposeでスタックをデプロイしている状態でイメージタグをv2に変えてデプロイしなおします。
$ docker stack deploy -c ./rolling-update.yaml test
Updating service test_rollingupdate (id: puu48mpsds8wfveg32l9wsz93)
タスクを確認すると以下のように新バージョンのイメージに更新されています。
$ docker stack ps test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zrpjiw85r1z1 test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 2 seconds ago
ni4gahckagdu \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 4 seconds ago
マネージャでcurlしv2であることを確認します。
$ curl 127.0.0.1:8000
v2
旧バージョンへの戻し方
スタックを再デプロイ
、service rollback
の2つの方法があります。
スタックを再デプロイ
前のバージョンに戻したい場合はタグをv1にまた書き換えてデプロイし直せばいいです。
$ docker stack deploy -c ./rolling-update.yaml test
Updating service test_rollingupdate (id: puu48mpsds8wfveg32l9wsz93)
タスクを確認します。
$ docker stack ps test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
tt7qhn9qcb61 test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Ready Ready 3 seconds ago
zrpjiw85r1z1 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running 3 seconds ago
ni4gahckagdu \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 3 minutes ago
上記のとおり、旧バージョンのタグを指定してデプロイし直してもタスク(tt7qhn9qcb61)は新しく作成されます。以前作成したv1のタスク(ni4gahckagdu)をリランさせるわけではありません。ちなみに過去のタスク履歴はデフォルトでは5つまで保存され、swarmの設定task-history-limit
を指定することで履歴をいくつまで残すか調整可能なようです。詳しくはこちらを確認ください。
service rollback
docker service rollbackコマンドを使って戻すこともできます。スタックでデプロイしたservice名はtest_rollingupdate
なので以下のようにコマンドを実行します。
$ docker service rollback test_rollingupdate
test_rollingupdate
rollback: manually requested rollback
overall progress: rolling back update: 1 out of 1 tasks
1/1: running [> ]
verify: Service converged
タスクを確認します。
$ docker stack ps test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
m8jbjkxyjcyo test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 48 seconds ago
up17gw36atzq \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 49 seconds ago
wsqqzfqrbldn \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 13 minutes ago
s5oggq0q3z7k \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 15 minutes ago
この場合でもスタックを再デプロイの時と同じように新しくタスク(m8jbjkxyjcyo)が作成されます。ただ、このコマンドで戻した場合はcomposeの内容と実機の状態に差異ができてしまうためあまりオススメはできないやり方かなと思います。
オプションの動作確認
composeで使えるアップデート関連のオプションはこちらにある。
delay
更新までの待機時間。ここで待機時間はアップデート開始(deployを実行)から10秒待つのか、次のタスクを更新するときの待ち時間なのか気になったので確認します。結論としては後者の理解で正しかったです。以下のように確認しました。
composeは以下のように書き換え、v1からデプロイします。
deploy:
replicas: 4
update_config:
parallelism: 1
delay: 20s
order: stop-first
この状態からスタート
$ docker stack ps test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
r3nsf50a8vu3 test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 14 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 14 seconds ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 14 seconds ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 14 seconds ago
composeのイメージタグをv2に修正してdeployする。deployする前に別ターミナルを開いておき以下コマンドで動きを観察します。
$ for i in `seq 1000`;do date;docker stack ps test;sleep 1;done
すると以下のようになりました。
アップデートの開始コマンドは14時34分24秒ごろに実行しました。まずtest_rollingupdate.1
のアップデートがdeployしてすぐに開始されます。このため、delay
はdeployしてからの待ち時間ではなくタスクごとの切り替えの待ち時間であることがわかるります。
2021年 7月 7日 水曜日 14時34分23秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
r3nsf50a8vu3 test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 38 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 38 seconds ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 38 seconds ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 38 seconds ago
2021年 7月 7日 水曜日 14時34分25秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Ready Ready less than a second ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running less than a second ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 40 seconds ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 40 seconds ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 40 seconds ago
2021年 7月 7日 水曜日 14時34分27秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Ready Ready 2 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running 2 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 42 seconds ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 42 seconds ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 42 seconds ago
2021年 7月 7日 水曜日 14時34分29秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running less than a second ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 1 second ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 44 seconds ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 44 seconds ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 44 seconds ago
2021年 7月 7日 水曜日 14時34分31秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 2 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 3 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 46 seconds ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 46 seconds ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 46 seconds ago
14時34分25秒からアップデートが開始している。まず新しいタスクを作成し状態がReadyになる。そして旧バージョンタスクの終了が実行される。 14時34分29秒に新しいタスクの状態がReadyからRunningになったことがわかる。
それからdelay
に設定した20秒後付近の状態が以下の通り。
2021年 7月 7日 水曜日 14時34分48秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 19 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 20 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
bhhu5yubm0ah test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
2021年 7月 7日 水曜日 14時34分50秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 21 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 22 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Ready Ready 1 second ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running 1 second ago
2021年 7月 7日 水曜日 14時34分52秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 23 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 24 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Ready Ready 3 seconds ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running 3 seconds ago
2021年 7月 7日 水曜日 14時34分55秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 25 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 26 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 1 second ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 2 seconds ago
2021年 7月 7日 水曜日 14時34分57秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 27 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 28 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 3 seconds ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 4 seconds ago
1つ目のタスクがRunningになった20秒後(delayで設定した秒数後)の14時34分50秒から2つ目の更新が開始している。そこから1つ目と同じ様に5秒ほどたった14時34分55秒に2つ目のタスクもReadyとなったいる。
そこからさらに20秒後付近の状態が以下の通り。
2021年 7月 7日 水曜日 14時35分11秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 42 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 43 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
fp0xvn255jsh test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 18 seconds ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 19 seconds ago
2021年 7月 7日 水曜日 14時35分14秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 44 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 45 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
t5jkp52cugkk test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Ready Assigned less than a second ago
fp0xvn255jsh \_ test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running about a minute ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 20 seconds ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 21 seconds ago
2021年 7月 7日 水曜日 14時35分16秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4g33i3q5l7ts test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 47 seconds ago
r3nsf50a8vu3 \_ test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 48 seconds ago
p6tzrv4i8mqv test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running about a minute ago
t5jkp52cugkk test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Ready Ready 2 seconds ago
fp0xvn255jsh \_ test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running 2 seconds ago
kekw7do91x4b test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 22 seconds ago
bhhu5yubm0ah \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Shutdown 23 seconds ago
14時35分14秒から3つ目のタスクの更新が始まっている。以下は1つ目、2つ目の動きと同じなため割愛します。
order
stop-first
とstart-first
があります。stop-firstは古いバージョンのタスクを停止してから新バージョンのタスクに切り替えます。start-firstは新しいバージョンのタスクを起動(Running)してから古いバージョンのタスクを消します。デフォルトはstop-first
です。
stop-first
の動作はdelayで確認しました。新バージョンがReadyになり、旧バージョンをShutdownし、最後に新バージョンがRunningしてました。
start-first
の動きもみておきます。composeは以下のように書き換え、v1からデプロイします。
deploy:
replicas: 4
update_config:
parallelism: 1
delay: 20s
order: start-first
結果以下の通りです。アップデートの開始コマンドは16時25分41秒ごろに実行しました。
2021年 7月 7日 水曜日 16時25分41秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ew3lx627z3bp test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 31 seconds ago
ob7zmh24jk3w test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 31 seconds ago
rxzmr8uga009 test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 31 seconds ago
qhea8s62vw4x test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 31 seconds ago
2021年 7月 7日 水曜日 16時25分43秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ew3lx627z3bp test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 33 seconds ago
ob7zmh24jk3w test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 33 seconds ago
rxzmr8uga009 test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 33 seconds ago
ukgow7auo1nb test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running less than a second ago
qhea8s62vw4x \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running less than a second ago
2021年 7月 7日 水曜日 16時25分45秒 JST
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ew3lx627z3bp test_rollingupdate.1 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 36 seconds ago
ob7zmh24jk3w test_rollingupdate.2 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 36 seconds ago
rxzmr8uga009 test_rollingupdate.3 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Running Running 36 seconds ago
ukgow7auo1nb test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v2 ip-10-0-1-189.us-east-2.compute.internal Running Running 2 seconds ago
qhea8s62vw4x \_ test_rollingupdate.4 ryotamori/swarm-rollingup-nginx:v1 ip-10-0-1-189.us-east-2.compute.internal Shutdown Running 2 seconds ago
test_rollingupdate.4
の新バージョンのタスクがすぐにRunningとなり、同時に旧バージョンの削除が実行されているのがわかります。切り替え時間はこっちの方が早そうですが、コンテナの起動処理を考えるとstop-first
の方が安全そうです。他のタスクの更新についてはdelay秒後に更新されるだけなので割愛します。
新旧バージョンが混在しているときのルーティング
たとえばdelayの検証をした時はv1のタスクとv2のタスクが混在しています。この混在している状態でアクセスしたときにどのように振り分けられるか確認します。結果を先に書くと新旧関係なくラウンドロビンで振り分けられます。
composeファイルはdelayの時と同じものを使用し、v1をデプロイした状態から開始します。その後、イメージタグをv2に書き換えて再デプロイし、ローリングアップデートを開始します。
マネージャで以下のようにcurlを連続で実行し、どのバージョンのタスクに接続するか確認します。
$ for i in `seq 1000`;do date; curl 127.0.0.1:8000;sleep 1;done
デプロイは07:38:45ごろに実行しました。結果以下のようになりました。長いので途中割愛します。
2021年 7月 7日 水曜日 07:38:44 UTC
v1
2021年 7月 7日 水曜日 07:38:45 UTC
v1
2021年 7月 7日 水曜日 07:38:46 UTC
v1
2021年 7月 7日 水曜日 07:38:47 UTC
v1
2021年 7月 7日 水曜日 07:38:48 UTC
v1
2021年 7月 7日 水曜日 07:38:49 UTC
v1
2021年 7月 7日 水曜日 07:38:50 UTC
v1
2021年 7月 7日 水曜日 07:38:51 UTC
v1
2021年 7月 7日 水曜日 07:38:52 UTC
v1
2021年 7月 7日 水曜日 07:38:53 UTC
v1
2021年 7月 7日 水曜日 07:38:54 UTC
v2
2021年 7月 7日 水曜日 07:38:55 UTC
v1
2021年 7月 7日 水曜日 07:38:56 UTC
v1
2021年 7月 7日 水曜日 07:38:57 UTC
v1
2021年 7月 7日 水曜日 07:38:58 UTC
v2
2021年 7月 7日 水曜日 07:38:59 UTC
v1
2021年 7月 7日 水曜日 07:39:00 UTC
v1
2021年 7月 7日 水曜日 07:39:01 UTC
v1
...
デプロイした10秒後くらいの07:38:54にはv2の出力があります。その後、07:38:58にもv2が出力されています。以降、タスク数が増えるにしたがってv2の出現頻度が上がることを確認しました。新旧関係なくラウンドロビンで振り分けられています。
replicas:1のときのローリングアップデート
少し気になったのでこれも検証しておきます。replica:1の場合、orderをstop-firstにした時とstart-firstにした時でそれぞれリクエストの失敗があるか確認します。
composeファイルは以下のような内容です。orderは検証中で修正します。
deploy:
replicas: 1
update_config:
order: stop-first
stop-firstの場合
v1を先にデプロイしておきv2に修正したcomposeをデプロイします。
マネージャでは以下コマンドで失敗するか監視します。
$ for i in `seq 1000`;do curl 127.0.0.1:8000;sleep 1;done
結果以下の通りでした。
v1
v1
v1
v1
v1
curl: (7) Failed to connect to 127.0.0.1 port 8000: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8000: Connection refused
curl: (7) Failed to connect to 127.0.0.1 port 8000: Connection refused
v2
v2
v2
v2
更新中に3秒ほどcurlに失敗していることが確認できます。stop-firstの場合、サービス断が発生するようです。
start-firstの場合
orderをstart-firstにして同じように確認します。
結果以下の通りでした。
v1
v1
v1
v1
v2
v1
v2
v2
v2
v2
サービス断は発生しないものの切り替わり中、新旧にリクエストが分散していることが確認できます。