suin.io

Docker 1.12のヘルスチェック機能でコンテナを死活監視する

suin2016年7月30日

Docker 1.12からコンテナのヘルスチェックを行える機能が追加されました。DockerfileではHEALTHCHEK命令(instruction)が追加され、docker runコマンドには--healthで始まるいくつかのオプションが追加されています。

このヘルスチェックは自己診断的なもので、ヘルスチェックを行うコマンドをチェック対象のコンテナ内で実行します。

ヘルスチェックステータスは、startinghealthyunhealthyの3つです。「unhealthyになったら何かを行う」という機能はDocker 1.12にはないようで、あくまでステータス情報を提供するにとどまっているようです。もしかしたら、今後unhealthyをトリガーに何か行えるようになるかもしれませんが、現状はそうしたことはDockerコンテナを管理するツールで行うことになりそうです。

環境

  • docker client 1.12.0
  • docker server 1.12.0

HTTPサーバをヘルスチェックしてみる

ヘルスチェックに使えるオプションは次の4つです。

  • --health-cmd: ヘルスチェックを行うコマンド。このコマンドが連続して--health-retriesで指定した回数異常失敗するとunheallthyになります。
  • --health-interval: ヘルスチェックを行う間隔。デフォルトは30秒(30s)
  • --health-timeout: ヘルスチェックのタイムアウト。デフォルトは30秒(30s)。タイムアウトを超えると失敗回数にカウントされます。
  • --health-retries: 何回連続で失敗したらunhealthyとするかを指定するオプション。デフォルトは3回。

--health-interval--health-timeoutは秒・分などで指定でき、2秒なら2s、5分なら5m等で設定します。

これらのオプションを使って、HTTPサーバをヘルスチェックを試してみます。

docker run \
    --name php \
    --publish 80:80 \
    --volume $PWD:/var/www/html \
    --health-cmd='curl --silent --fail --output /dev/null http://localhost' \
    --health-interval=2s \
    --health-timeout=3s \
    --health-retries=3 \
    php:apache

ヘルスチェクのコマンドはcurlでHTTPサーバに繋いで見るシンプルなものです。このヘルスチェックでは200系であればhealthy、そうでなければunhealthyとしたいので、--failオプションを使います。これは200系のステータスコードでないとき、エラーで終了するオプションです。--silent--output /dev/nullはヘルスチェックのログにレスポンス等を残さいないためのものです。

実験用にコンテナのドキュメントルート/var/www/htmlには、HTTPステータスコードを返すPHPスクリプトを配置します。内容はhttp_response_code関数で200を返すだけのものになっています。

$PWD/index.php
<?php
http_response_code(200);

Dockerコンテナを起動すると、curlによるヘルスチェックのリクエストがApacheに来ていることがログからわかります。

::1 - - [30/Jul/2016:12:35:39 +0000] "GET / HTTP/1.1" 200 172 "-" "curl/7.38.0"
::1 - - [30/Jul/2016:12:35:41 +0000] "GET / HTTP/1.1" 200 172 "-" "curl/7.38.0"
::1 - - [30/Jul/2016:12:35:43 +0000] "GET / HTTP/1.1" 200 172 "-" "curl/7.38.0"
::1 - - [30/Jul/2016:12:35:45 +0000] "GET / HTTP/1.1" 200 172 "-" "curl/7.38.0"

ヘルスステータスはdocker psで確認できる

Dockerコンテナの健康状態は、docker psコマンドで見ることができます。STATUSの欄がに(healthy)と出ているのがヘルスチェックの結果です。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                    PORTS                NAMES
95e0ecf2bf68        php:apache          "apache2-foreground"   18 seconds ago      Up 17 seconds (healthy)   0.0.0.0:80->80/tcp   php

先ほどのPHPスクリプトで500ステータスを返すようにしてみます。

$PWD/index.php
<?php
http_response_code(500);

しばらくすると、docker psでのコンテナステータスがunhealthyになります。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS                NAMES
95e0ecf2bf68        php:apache          "apache2-foreground"   2 minutes ago       Up 2 minutes (unhealthy)   0.0.0.0:80->80/tcp   php

ヘルスチェックのコマンド実行結果はdocker inspectで調べることができます。

$ docker inspect -f '{{json .State.Health}}' php
{
  "Status": "unhealthy",
  "FailingStreak": 25,
  "Log": [
    {
      "Start": "2016-07-30T12:41:28.154318586Z",
      "End": "2016-07-30T12:41:28.262630621Z",
      "ExitCode": 22,
      "Output": ""
    },
    {
      "Start": "2016-07-30T12:41:30.264641942Z",
      "End": "2016-07-30T12:41:30.362703786Z",
      "ExitCode": 22,
      "Output": ""
    },
    {
      "Start": "2016-07-30T12:41:32.36376571Z",
      "End": "2016-07-30T12:41:32.469813522Z",
      "ExitCode": 22,
      "Output": ""
    },
    {
      "Start": "2016-07-30T12:41:34.470631218Z",
      "End": "2016-07-30T12:41:34.58472781Z",
      "ExitCode": 22,
      "Output": ""
    },
    {
      "Start": "2016-07-30T12:41:36.585436891Z",
      "End": "2016-07-30T12:41:36.695719043Z",
      "ExitCode": 22,
      "Output": ""
    }
  ]
}

この履歴は5件まで見ることができ、ログ自体は4096バイトまで保存されるようです。

おわり

Docker 1.12よりヘルスチェック機能が追加されました。unhealthyになったときに何かできるわけではありませんが、死活監視やモニタリングのツールとうまく組み合わせられれば、オペレーションに役立つかもしれませんね。

参考

RELATED POSTS