Swarm Modeにおけるローリングアップデートはhealthcheckの結果を見るのか？

# Swarm Modeにおけるローリングアップデートはhealthcheckの結果を見るのか？

## 経緯

- 本番環境でSwarm Modeを使う際に、コンテナのアップデートはローリングアップデートにしたい
- でもちゃんとアップデート後のコンテナの起動の成否だけでなく、ヘルスチェックまで見てくれるの？
- 私、気になります

## 検証内容

- アップデート後のコンテナのヘルスチェックに失敗したら、アップデート中断される？
	- healthcheckのコマンドにexit 1を設定してみる

## 検証環境

- Swarm
	- GCPのdebianインスタンス 1ノードのみで構成
		- `Docker version 17.03.1-ce, build c6d412e`
- 初期スタック
	- nginxサービス
		- nginx:1.11 * 4
		- アップデート設定
			- コンテナ更新単位: 1個
			- コンテナ更新間隔: 10秒
		- ヘルスチェック設定
			- コマンド: exit 0
				- 強制healthy
			- ヘルスチェック間隔: 1分
			- リトライ回数: 3階

```
$ cat docker-compose_0.yml
version: '3'

services:
  nginx:
    image: nginx:1.11
    ports:
      - "8080:80"
    deploy:
      replicas: 4
      update_config:
        parallelism: 1
        delay: 10s
    healthcheck:
      test: exit 0
      interval: 1m
      retries: 3
```

```
$ docker stack ps nginx
ID            NAME           IMAGE       NODE        DESIRED STATE  CURRENT STATE          ERROR  PORTS
xoy4khwl9ayk  nginx_nginx.1  nginx:1.11  instance-1  Running        Running 6 seconds ago
ynx2z9cizmio  nginx_nginx.2  nginx:1.11  instance-1  Running        Running 6 seconds ago
n2eionryfbs7  nginx_nginx.3  nginx:1.11  instance-1  Running        Running 6 seconds ago
kmtp9tf3li9p  nginx_nginx.4  nginx:1.11  instance-1  Running        Running 6 seconds ago

$ docker container ps
CONTAINER ID        IMAGE                                                                           COMMAND                  CREATED              STATUS                        PORTS               NAMES
fe359c9176d4        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   About a minute ago   Up About a minute (healthy)   80/tcp, 443/tcp     nginx_nginx.1.xoy4khwl9ayku36vlefu4dlsf
c18817fb6cd0        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   About a minute ago   Up About a minute (healthy)   80/tcp, 443/tcp     nginx_nginx.3.n2eionryfbs768z6r7eotqt8a
c49cbce6ad28        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   About a minute ago   Up About a minute (healthy)   80/tcp, 443/tcp     nginx_nginx.2.ynx2z9cizmiobwfwr2p2sqckr
9c1ff1d8bc0e        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   About a minute ago   Up About a minute (healthy)   80/tcp, 443/tcp     nginx_nginx.4.kmtp9tf3li9py71jm31b7ifai
```

## 検証結果

- 初期スタックを更新し、nginxのバージョンを1.12, ヘルスチェックのコマンドをexit 1にする

```
$ diff docker-compose_0.yml docker-compose_1.yml
5c5
<     image: nginx:1.11
---
>     image: nginx:1.12
14c14
<       test: exit 0
---
>       test: exit 1
```

- ローリングアップデート実施

```
$ docker stack ps nginx
ID            NAME               IMAGE       NODE        DESIRED STATE  CURRENT STATE               ERROR  PORTS
xoy4khwl9ayk  nginx_nginx.1      nginx:1.11  instance-1  Running        Running about a minute ago
ynx2z9cizmio  nginx_nginx.2      nginx:1.11  instance-1  Running        Running about a minute ago
n2eionryfbs7  nginx_nginx.3      nginx:1.11  instance-1  Running        Running about a minute ago
89nblxzgbxb5  nginx_nginx.4      nginx:1.12  instance-1  Running        Starting 36 seconds ago
kmtp9tf3li9p   \_ nginx_nginx.4  nginx:1.11  instance-1  Shutdown       Shutdown 36 seconds ago
$ docker container ps
CONTAINER ID        IMAGE                                                                           COMMAND                  CREATED             STATUS                             PORTS               NAMES
acf07a295f76        nginx@sha256:cbd4365b235b1955d64d282fbe6245992dd61331d6a72afae303183fe6ac56f0   "nginx -g 'daemon ..."   43 seconds ago      Up 40 seconds (health: starting)   80/tcp              nginx_nginx.4.89nblxzgbxb5pfc7p3yqysolm
fe359c9176d4        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes (healthy)             80/tcp, 443/tcp     nginx_nginx.1.xoy4khwl9ayku36vlefu4dlsf
c18817fb6cd0        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes (healthy)             80/tcp, 443/tcp     nginx_nginx.3.n2eionryfbs768z6r7eotqt8a
c49cbce6ad28        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes (healthy)             80/tcp, 443/tcp     nginx_nginx.2.ynx2z9cizmiobwfwr2p2sqckr
```

- ヘルスチェックがリトライ回数失敗するまで待つ(ヘルスチェック間隔*リトライ回数+タイムアウト)

```
$ docker stack ps nginx
ID            NAME               IMAGE       NODE        DESIRED STATE  CURRENT STATE            ERROR  PORTS
xoy4khwl9ayk  nginx_nginx.1      nginx:1.11  instance-1  Running        Running 4 minutes ago
ynx2z9cizmio  nginx_nginx.2      nginx:1.11  instance-1  Running        Running 4 minutes ago
n2eionryfbs7  nginx_nginx.3      nginx:1.11  instance-1  Running        Running 4 minutes ago
lbb8dv22ekjr  nginx_nginx.4      nginx:1.12  instance-1  Running        Starting 23 seconds ago
89nblxzgbxb5   \_ nginx_nginx.4  nginx:1.12  instance-1  Shutdown       Complete 28 seconds ago
kmtp9tf3li9p   \_ nginx_nginx.4  nginx:1.11  instance-1  Shutdown       Shutdown 3 minutes ago

$ docker container ps -a
CONTAINER ID        IMAGE                                                                           COMMAND                  CREATED             STATUS                             PORTS               NAMES
b9c29f7088fd        nginx@sha256:cbd4365b235b1955d64d282fbe6245992dd61331d6a72afae303183fe6ac56f0   "nginx -g 'daemon ..."   35 seconds ago      Up 29 seconds (health: starting)   80/tcp              nginx_nginx.4.lbb8dv22ekjrv6kuq2zf7hu3x
acf07a295f76        nginx@sha256:cbd4365b235b1955d64d282fbe6245992dd61331d6a72afae303183fe6ac56f0   "nginx -g 'daemon ..."   3 minutes ago       Exited (0) 35 seconds ago                              nginx_nginx.4.89nblxzgbxb5pfc7p3yqysolm
fe359c9176d4        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   5 minutes ago       Up 5 minutes (healthy)             80/tcp, 443/tcp     nginx_nginx.1.xoy4khwl9ayku36vlefu4dlsf
c18817fb6cd0        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   5 minutes ago       Up 5 minutes (healthy)             80/tcp, 443/tcp     nginx_nginx.3.n2eionryfbs768z6r7eotqt8a
c49cbce6ad28        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   5 minutes ago       Up 5 minutes (healthy)             80/tcp, 443/tcp     nginx_nginx.2.ynx2z9cizmiobwfwr2p2sqckr
9c1ff1d8bc0e        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   5 minutes ago       Exited (0) 3 minutes ago                               nginx_nginx.4.kmtp9tf3li9py71jm31b7ifai
```

- nginxサービスで作られた4個のコンテナのうち、1個のコンテナがアップデート後のヘルスチェックで失敗している
	- 失敗後は他の3個のコンテナへのアップデートは行われない
		- ちゃんとヘルスチェックの結果が反映されて、ローリングアップデートが中断されている
	- ヘルスチェック失敗後に再度コンテナが生成されている
		- 延々と繰り返されるっぽい？

## 結論

- Swarm Modeのローリングアップデートはちゃんとヘルスチェックの結果を判定した上でローリングアップデートしてくれます。やったぜ


## おまけ

### 失敗したアップデートを戻す

- アップデート前のcomposeファイルを使って再デプロイ

```
$ docker stack deploy --compose-file docker-compose_0.yml nginx
Updating service nginx_nginx (id: la4spmofxsvyx4ybncahtaz7h)
```

```
$ docker stack ps nginx
ID            NAME               IMAGE       NODE        DESIRED STATE  CURRENT STATE            ERROR  PORTS
xoy4khwl9ayk  nginx_nginx.1      nginx:1.11  instance-1  Running        Running 19 minutes ago          
ynx2z9cizmio  nginx_nginx.2      nginx:1.11  instance-1  Running        Running 19 minutes ago          
n2eionryfbs7  nginx_nginx.3      nginx:1.11  instance-1  Running        Running 19 minutes ago          
mhqs49bwd1uz  nginx_nginx.4      nginx:1.11  instance-1  Running        Running 3 minutes ago           
xh63uycqldgu   \_ nginx_nginx.4  nginx:1.12  instance-1  Shutdown       Shutdown 4 minutes ago          
i8t033tqssde   \_ nginx_nginx.4  nginx:1.12  instance-1  Shutdown       Complete 5 minutes ago          
v6319wprtuvx   \_ nginx_nginx.4  nginx:1.12  instance-1  Shutdown       Complete 8 minutes ago          
lbb8dv22ekjr   \_ nginx_nginx.4  nginx:1.12  instance-1  Shutdown       Complete 12 minutes ago         

$ docker container ps
CONTAINER ID        IMAGE                                                                           COMMAND                  CREATED             STATUS                    PORTS               NAMES
540979d88580        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   4 minutes ago       Up 4 minutes (healthy)    80/tcp, 443/tcp     nginx_nginx.4.mhqs49bwd1uzfuswbxfwohrc2
fe359c9176d4        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   20 minutes ago      Up 20 minutes (healthy)   80/tcp, 443/tcp     nginx_nginx.1.xoy4khwl9ayku36vlefu4dlsf
c18817fb6cd0        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   20 minutes ago      Up 20 minutes (healthy)   80/tcp, 443/tcp     nginx_nginx.3.n2eionryfbs768z6r7eotqt8a
c49cbce6ad28        nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582   "nginx -g 'daemon ..."   20 minutes ago      Up 20 minutes (healthy)   80/tcp, 443/tcp     nginx_nginx.2.ynx2z9cizmiobwfwr2p2sqckr
```

- 失敗した分がちゃんと戻っている

### 初回のヘルスチェックのタイミング

- 初回のヘルスチェックはコンテナの起動した瞬間に行われるものだと思っていたが、実際には起動してからinterval時間おいてからだった
	- これだとコンテナ起動してからinterval時間待たないとコンテナ使えないのでちょっとあれ