How to run Docker's HEALTHCHECK
Dockerfile をいじらずに
HEALTHCHECKのテストが動くか確認したい。つまりヘルスチェック自体の動作確認をしたいのです。
- 「Docker とは」の検索結果 @ Google
TL;DR
health-intervalとhealth-start-periodを1秒(1s)に指定してdocker runし、docker psでStatusをgrepします。docker run -d --rm \ --health-start-period=1s \ --health-interval=1s \ my_image:my_tag my_command && \ sleep 5 && \ docker ps \ --filter ancestor=my_image:my_tag \ --format '{{json .Status}}' | grep healthy
Docker の HEALTHCHECK 動作は、コンテナを起動しないと確認できません。起動していれば docker ps の STATUS 項目で確認できます。
そのため「作成した Dockerfile のヘルスチェックが動いているか」の確認をしたい場合は、docker run のオプションで HEALTHCHECK の「開始」と「インターバル」を設定しながら実行した後、docker ps で確認します。
$ docker run -d --rm --health-start-period=1s --health-interval=1s my_image:my_tag my_command
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fdd3da5660c my_image:my_tag "my_command" 2 minutes ago Up 2 minutes (health: healthy) 0.0.0.0:4040->4040/tcp randomname
-
--health-start-period=1s(開始、1秒以上) -
--health-interval=1s(インターバル、1秒以上)
「docker how to run healthcheck」とググっても HEALTHCHECK の設定の仕方ばかりで、動作確認の方法がタイトルからわかるものがありませんでした。わかれば、どうってことないのですが自分のググラビリティとして。もっと簡単に確認できる方法があればコメントで教えてくださーい。
TS;DR(Are You Healthy?)
Dockle でチェックしたら不健康と言われた
PHP8(JIT 付き)のコンテナを作成したので、イメージがセキュアか最低限のチェックとして Docker のセキュリティ診断ツール「Dockle」で作成した Docker イメージを診断させたのです。
すると、「HEALTHCHECK ないよ」と WARN されました。ヽ( `Д´)ノ ウワァァァン!!
$ # CIS-DI-0005 は .dockleignore で意図的にスキップ
$ dockle php8:localbuild
PASS - CIS-DI-0001: Create a user for the container
IGNORE - CIS-DI-0005: Enable Content trust for Docker
WARN - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
* not found HEALTHCHECK statement
PASS - CIS-DI-0007: Do not use update instructions alone in the Dockerfile
PASS - CIS-DI-0008: Remove setuid and setgid permissions in the images
PASS - CIS-DI-0009: Use COPY instead of ADD in Dockerfile
PASS - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables
PASS - CIS-DI-0010: Do not store secret files
PASS - DKL-DI-0001: Avoid sudo command
PASS - DKL-DI-0002: Avoid sensitive directory mounting
PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade
PASS - DKL-DI-0004: Use apk add with --no-cache
PASS - DKL-DI-0005: Clear apt-get caches
PASS - DKL-DI-0006: Avoid latest tag
PASS - DKL-LI-0001: Avoid empty password
PASS - DKL-LI-0002: Be unique UID
PASS - DKL-LI-0002: Be unique GROUP
健康診断は大事です。泣いてもしかたないので、Dockerfile に HEALTHCHECK を以下のように指定しました。
...(略)...
HEALTHCHECK \
--start-period=10m \
--interval=60m \
--timeout=10s \
--retries=1 \
CMD [ "php -r 'echo phpversion();'" ]
...(略)...
開始時間とインターバル(start-period と interval)が長いのは、マシンがショボいためしばらく経過して、安定してからヘルスチェックさせたかったからです。
dockle のテストはパスしたのでコンテナを作成して作業をしていたところ、「もういいでしょう」とおもむろに docker ps を実行したところ STATUS が Up XX minutes (unhealthy) となっていました。不健康ですって。
ビックリしたのもつかの間、そもそも HEALTHCHECK で指定したテストの仕方が間違ってたのでした。。。(実行エラーを起こしていました)
最初は --start-period=0s と Dockerfile で指定したのですが docker ps のステータスが Up 10 minutes (health: starting) と一向に始まる気配がありません。
「なんか・・・確認のたび Dockerfile をいじるの面倒だな・・・普通に確認コマンドないのかな」
考える前に手が出る、検索猿人の悪い癖がでました。
結局のところ、イメージの状態で HEALTHCHECK の動作テストは行えず、一旦コンテナを立ち上げないといけないことがわかりました。
docker inspect でも確認できるのですが docker ps で確認する方が簡単でした。
最終的に動作する Dockerfile の HEALTHCHECK は以下の通りになりました。
...(略)...
HEALTHCHECK \
--start-period=10m \
--interval=60m \
--timeout=10s \
--retries=1 \
CMD [ 'php -r "echo phpversion();"' ]
...(略)...
- CMD [ "php -r 'echo phpversion();'" ]
+ CMD [ 'php -r "echo phpversion();"' ]
参考文献
- HEALTHCHECK @ Docker 公式