Dockerコンテナにヘルスチェックを追加する方法(および理由)
あなたはDockerイメージを作成し、それをレジストリにプッシュして、プロダクション環境で新しいコンテナを起動しました。すべてがうまくいっていると思いながら帰宅しましたが、翌朝戻ると障害報告を受けました。コンテナはまだ動作していますが、リクエストに応答していません。
このシナリオは、Dockerを使用しているオペレーションチームにとって不快に思えるほどお馴染みかもしれません。ここでは、Dockerのヘルスチェック機能を使用して、サービスの可用性について正確なデータを取得する方法を紹介します。
健康チェックの仕組み
ヘルスチェックは、コンテナがそのワークロードの可用性を公開することを可能にします。これは、コンテナが動作しているかどうかとは異なります。データベースがダウンすると、APIサーバーはリクエストを処理できなくなりますが、Dockerコンテナはまだ動作しています。
これにより、トラブルシューティング中に役に立たない体験が生まれます。シンプルなdocker psはコンテナが利用可能であると報告します。ヘルスチェックを追加することで、docker psの出力がコンテナの真の状態を含むように拡張されます。
あなたはコンテナのヘルスチェックをあなたの中で構成します
Dockerfileこれにより、Dockerデーモンが30秒ごとに実行するコマンドを受け付けます。Dockerはコマンドの終了コードを使用して、コンテナの健康状態を判断します:
0- コンテナは正常に動作しており、健康です。1- コンテナが不健康です; ワークロードが機能していない可能性があります。2
- このステータスコードはDockerによって予約されており、使用すべきではありません。
DockerfileにHEALTHCHECKが存在する場合、コンテナの健康状態が表示されます。
STATUSdocker psを実行するときの列。
コンテナが作成されたときに健康状態はすぐにはチェックされません。ステータスは表示されます。
starting最初のチェックが実行される前。これにより、コンテナは起動タスクを実行する時間を得ます。健康チェックに合格したコンテナは、次のように表示されます
healthy; 不健康なコンテナは unhealthy を表示します。
ヘルスチェックコマンドを書く
コンテナのヘルスチェックは、HEALTHCHECK 命令を使用して構成されます。
Dockerfile
コンテナに適したヘルスチェックコマンドを使用するべきです。ウェブサーバーの場合、curlを使うことで基本的な準備チェックを簡単に行うことができます。サービスが稼働しているときには常に利用できるべき既知のエンドポイントにpingを送信してください。
FROM nginx:latest
HEALTHCHECK CMD curl --fail http://localhost/api/healthcheck || exit 1
この例では、サーバーの/api/healthcheckエンドポイントがエラーステータスを発行した場合に、コンテナを不健康としてマークします。
docker inspectを使用すると、ヘルスチェックコマンドの出力を確認できます。これは、HEALTHCHECK命令をデバッグしているときに役立ちます。
docker inspect --format='{{json .State.Health}}' my-containermy-containerを検査したいコンテナのIDまたは名前に置き換えてください。これらの詳細はdocker psの出力に表示されます。
ヘルスチェックのカスタマイズ
Dockerでは、ヘルスチェックの頻度をカスタマイズできます。また、コンテナを不健康と見なす基準を変更することもできます。
利用可能なオプションは4つあります。
--interval- ヘルスチェックの間隔を設定します。これにより、デフォルトの30秒をオーバーライドすることができます。チェック間の時間を増やすために、より高い間隔を使用します。これは、定期的なヘルスチェックがパフォーマンスに影響を与える可能性がある低優先度のサービスに役立ちます。重要なサービスには、より定期的な頻度を使用してください。--start-period- コンテナが起動した後、ヘルスチェックを無視する期間を設定します。このコマンドは実行されますが、健康でない状態はカウントされません。これにより、コンテナは起動手続きを完了する時間が与えられます。--retries- これは、コンテナがunhealthyとしてマークされる前に、複数の連続した失敗を要求することができます。デフォルトは3回です。ヘルスチェックが失敗しても、その後のチェックが成功すれば、コンテナはunhealthyに遷移しません。3回連続でチェックに失敗すると、コンテナは不健康になります。--timeout- 健康チェックコマンドのタイムアウトを設定します。コマンドがこの時間内に終了しない場合、Dockerはチェックを失敗とみなします。
HEALTHCHECK命令にはオプションがフラグとして渡されます。ヘルスチェックコマンドの前にそれらを指定してください:
HEALTHCHECK --interval=60s --retries=5 CMD curl --fail http://localhost || exit 1この設定は、Dockerに60秒ごとにcurlを実行するよう指示します。5回連続して非ゼロの終了コードがある場合、コンテナは不健全と見なされます。
コマンド形式
このHEALTHCHECKコマンドの構文は、プレーンなCMDまたはエントリーポイントスタイルのexec配列のいずれかをサポートしています。また、ヘルスチェックを無効にするためにCMDの代わりにNONEを渡すこともできます:
HEALTHCHECK NONE
これにより、ベースイメージのヘルスチェックを無効にすることができます。各HEALTHCHECK文は、イメージのレイヤー内の以前の指示を上書きします。
Docker Composeはどうですか?
Docker Composeはヘルスチェック定義もサポートしています。サービスにhealthcheckセクションを追加してください。
version: "3"
services:
app:
image: nginx:latest
ports:
- 80:80
healthcheck:
test: curl --fail http://localhost || exit 1
interval: 10s
retries: 5
start_period: 5s
timeout: 10s
testキーは実行するコマンドを定義します。他のキーはDockerfileのHEALTHCHECK命令で受け入れられるパラメータにマッピングされます。
要約
HEALTHCHECK 指示を設定することで、誤動作しているコンテナの診断が容易になります。コンテナの「実行」状態とは独立して、ワークロードの準備状況を追跡できます。
ヘルスチェックは、0 または 1 の終了コードを発行する任意のコマンドと互換性があります。curl や ping のような一般的なコマンドを使用して、ウェブサービスやデータベースを検査することができます。より高度な制御が必要な場合は、専用のスクリプトを書き、それをイメージに含めてください。

