概要
Kubernetesでは稼働しているpodの稼働状態に応じて再起動やサービスアウトを行うヘルスチェック機能としてLivenessProbeとReadinessProbeがあります。
これらのヘルスチェック条件は柔軟に設定する事が可能です。
http通信を受け付けるpodでは下記の様にhttpGet
を使ったヘルスチェック用のpathを使って判定する事が多いと思います。
readinessProbe:
httpGet:
path: /health-readiness
port: 80
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 4
successThreshold: 1
failureThreshold: 3
livenessProbe:
httpGet:
path: /health-liveness
port: 80
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 4
successThreshold: 1
failureThreshold: 3
今回http通信を受け付けないpodを運用する事になり、ファイルの更新時間を使ったLivenessProbeの判定を行ったのでご紹介します。
ヘルスチェックの要件
今回運用するpodはKinesisDataStreamに対してポーリングを行い、取得したキュー数に応じて処理を行うアプリケーションです。
このpodはキューを処理する際にpod内の特定ファイル(/tmp/healthcheck)を更新する挙動になっています。
システムの役割上ほぼ毎秒毎にキューが発生しているはずなので、2~3回ポーリングする時間内に特定ファイルが更新されていなければ該当のpodは正常に処理ができてない状態と判断する事ができます。
このような状態になったpodは再起動を行うことで新たに処理を開始する運用を想定していました。
まとめると以下の通りになります。
- ヘルスチェックエラー時の挙動が再起動なので
LivenessProbe
にて実装する -
/tmp/healthcheck
の更新時間をヘルスチェック条件とする -
/tmp/healthcheck
の更新時間はポーリング間隔の2~3倍以内でなければ異常とする
実装内容
上記のヘルスチェック要件を受けて下記の実装を行いました。
livenessProbe:
exec:
command:
- sh
- -c
- find /tmp/ -name "healthcheck" -mmin -`echo $POLLING_IDLE_TIME_BETWEEN_READS_MILLIS | awk '{print $1/60000*3}'` | grep /tmp/healthcheck
initialDelaySeconds: 180
periodSeconds: 5
※ポーリング間隔(ミリ秒)を変数POLLING_IDLE_TIME_BETWEEN_READS_MILLIS
にて指定しています
ファイルの更新時間をチェックするために、今回はcommandを使ったシェルにおける確認方法を選択しました。
find /tmp/ -name "healthcheck" -mmin -`echo $POLLING_IDLE_TIME_BETWEEN_READS_MILLIS | awk '{print $1/60000*3}'`
こちらで特定ファイル(/tmp/health)の更新時間が既定値以内かをチェックしています。
findコマンドのmminオプションが分単位でPOLLING_IDLE_TIME_BETWEEN_READS_MILLIS
の指定がミリ秒単位なのでawk '{print $1/60000*3}'
にて単位を合わせています。
grep /tmp/healthcheck
commandでは実行したコマンドのリターンコードにて判定を行うので要件を満たしている場合はリターンコード0を、要件を満たしていない場合はリターンコード1となるために『要件を満たしたファイルの有無』にて判定を行う形にしました。
最後に
これまではAPIとなるpodの運用が多く、httpGet
以外のLivenessProbe/ReadinessProbeの実装を行ったのは初めてでした。
複雑な処理を行う場合はコンテナ内にヘルスチェック用のスクリプトを設置してLivenessProbe/ReadinessProbeにて実行してリターンコードを取得する方が良いですが、シンプルな確認であれば今回の様にコマンド実行が便利でした。
本記事が誰かの助けになれば嬉しく思います。