Docker の Health check について確認した時のメモ

Docker の Health check について確認した時のメモ。
以下は`docker run`で指定する時のリファレンス。

[HEALTHCHECK](https://docs.docker.com/engine/reference/run/#healthcheck)

概要の理解としては以下がとても分かりやすかったです。

[Docker 1.12の新機能、ヘルスチェック機能を使ってみる](https://knowledge.sakura.ad.jp/6754/)

# 準備

コンテナは nginx を使い、Host の `/tmp/nginx`をマウントします。
参考にしたのは以下の記事。

+ [Tips for Deploying NGINX (Official Image) with Docker](https://blog.docker.com/2015/04/tips-for-deploying-nginx-official-image-with-docker/)
+ [docker の nginx イメージの設定ファイルを眺めながら、独自ページを表示します。](https://qiita.com/mochizukikotaro/items/1d28888b78f401227ed6)

```bash
# テスト用ファイルの作成
$mkdir /tmp/nginx
$echo 'Welcome nginx' > /tmp/nginx/index.html

# 8080ポートを80にマッピングし、/tmp/nginx をマウント
$docker run --name mynginx2 -v /tmp/nginx:/usr/share/nginx/html:ro -d -p 8080:80 nginx

# 表示できる
$curl http://localhost:8080/
Welcome nginx

# Host のファイルを変えると合わせて変わる
$echo 'Welcome nginx!' > /tmp/nginx/index.html
$curl http://localhost:8080/
Welcome nginx!
```

# Health check してみる

```bash
# curl -f オプションを利用して失敗したら exit 1 とする
$docker run --name mynginx2 -v /tmp/nginx:/usr/share/nginx/html:ro -d -p 8080:80 \
--health-cmd='curl -f http://localhost/ exit 1' \
--health-interval=2s \
nginx

$docker inspect --format='{{json .State.Health}}' mynginx2

# inspect で確認。curl がなくて失敗していた。。。
docker inspect --format='{{json .State.Health}}' mynginx2 | jq
{
  "Status": "unhealthy",
  "FailingStreak": 77,
  "Log": [
    {
      "Start": "2018-04-07T21:38:28.2369693Z",
      "End": "2018-04-07T21:38:28.3415581Z",
      "ExitCode": 127,
      "Output": "/bin/sh: 1: curl: not found\n"
    },
    {
      "Start": "2018-04-07T21:38:30.3505019Z",
      "End": "2018-04-07T21:38:30.4283306Z",
      "ExitCode": 127,
      "Output": "/bin/sh: 1: curl: not found\n"
    },
    {
      "Start": "2018-04-07T21:38:32.4371028Z",
      "End": "2018-04-07T21:38:32.5512819Z",
      "ExitCode": 127,
      "Output": "/bin/sh: 1: curl: not found\n"
    },
    {
      "Start": "2018-04-07T21:38:34.571161Z",
      "End": "2018-04-07T21:38:34.6569846Z",
      "ExitCode": 127,
      "Output": "/bin/sh: 1: curl: not found\n"
    },
    {
      "Start": "2018-04-07T21:38:36.6678242Z",
      "End": "2018-04-07T21:38:36.8905809Z",
      "ExitCode": 127,
      "Output": "/bin/sh: 1: curl: not found\n"
    }
  ]
}

# ps で見ると「unhealthy」となっている
$docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                  NAMES
1ceca5a87bfb        nginx               "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes (unhealthy)   0.0.0.0:8080->80/tcp   mynginx2
```

curl をインストールするのは面倒なので Docker run のリファレンス通り`docker exec`を使って確認。
(nginx の話は備忘録として残しておく)

```bash
# stat コマンドでファイルの存在確認。
$docker run --name=test -d \
    --health-cmd='stat /etc/passwd || exit 1' \
    --health-interval=2s \
    busybox sleep 1d
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
f70adabe43c0: Pull complete
Digest: sha256:58ac43b2cc92c687a32c8be6278e50a063579655fe3090125dcb2af0ff9e1a64
Status: Downloaded newer image for busybox:latest
2cbbf0dfc18f55a0ed77aeda5539d3bac77d11d09b235b3055b200ebfe4235bc

# ファイルがあるので Health
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                        PORTS               NAMES
2cbbf0dfc18f        busybox             "sleep 1d"          About a minute ago   Up About a minute (healthy)                       test

# docker inspect でも healthy であることが分かる
$docker inspect --format='{{.State.Health.Status}}' test
healthy

# ファイルを消す
$ docker exec test rm /etc/passwd

# ファイルがないので unhealthy
$docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
2cbbf0dfc18f        busybox             "sleep 1d"          3 minutes ago       Up 3 minutes (unhealthy)

$docker inspect --format='{{json .State.Health}}' test | jq .
{
  "Status": "unhealthy",
  "FailingStreak": 26,
  "Log": [
    {
      "Start": "2018-04-07T21:47:57.2611036Z",
      "End": "2018-04-07T21:47:57.4146157Z",
      "ExitCode": 1,
      "Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
    },

```

上記の通り、unhealhy になるものの、自動でコンテナを再起動するとかではないので注意。