Docker 1.12からコンテナのヘルスチェックを行える機能が追加されました。DockerfileではHEALTHCHEK
命令(instruction)が追加され、docker run
コマンドには--health
で始まるいくつかのオプションが追加されています。
このヘルスチェックは自己診断的なもので、ヘルスチェックを行うコマンドをチェック対象のコンテナ内で実行します。
ヘルスチェックステータスは、starting
・healthy
・unhealthy
の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を返すだけのものになっています。
<?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ステータスを返すようにしてみます。
<?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
になったときに何かできるわけではありませんが、死活監視やモニタリングのツールとうまく組み合わせられれば、オペレーションに役立つかもしれませんね。