Rails x k8s Health チェック
k8s で運用する Rails アプリケーションにHealthチェックエンドポイントを追加しようと思ったので、そもそもHealthチェックって?みたいなところから色々調べてみた
microservice.io から
For example, it might have ran out of database connections. When this occurs, the monitoring system should generate a alert. Also, the load balancer or service registry should not route requests to the failed service instance.
正常に動作してないアプリに、リクエスト飛ばすなってことみたい
k8s (EKS)でデプロイされているアプリに対して行われるヘルスチェックは
- ALB の healthcheck
- Ingress で指定するエンドポイント
- livenessProbe
- ReadinessProbe
- (StartupProbe)
- 今回は考慮しない
k8s のドキュメントで liveness と readiness の使い分けが載ってる
livenessProbe
コンテナが動いているかを示します。 livenessProbeに失敗すると、kubeletはコンテナを殺します、そしてコンテナはrestart policyに従います。 コンテナにlivenessProbeが設定されていない場合、デフォルトの状態はSuccessです。
readinessProbe
コンテナがリクエスト応答する準備ができているかを示します。 readinessProbeに失敗すると、エンドポイントコントローラーにより、ServiceからそのPodのIPアドレスが削除されます。 initial delay前のデフォルトのreadinessProbeの初期値はFailureです。 コンテナにreadinessProbeが設定されていない場合、デフォルトの状態はSuccessです。
コンテナが動いている is Railsサーバーが起動しているということで良いと思うので、liveness で使用するヘルスチェックエンドポイントは 単純に Status: 200 を返すだけで良さそう
コンテナがリクエスト応答する準備ができているかに関してもRailsサーバーが起動していれば良さそうな気はする
ただ、
正常に動作してないアプリに、リクエスト飛ばすなってことみたい
も考慮すると、依存するミドルウェアとか DB の接続に関してもチェックした方がよさそう
なので Readiness で使用するヘルスチェックエンドポイントは、DB, redis のチェックも行う
ALBのヘルスチェックに関してはPodがReady になった後(Readiness 成功後)、にALBから実行されるため、再度 Readiness と同様のチェックは必要ないはず
仮にDB や redis が落ちてる場合は、Readiness が失敗して該当 Pod へのルーティングは行われないので、大丈夫
なので ALB のヘルスチェックも単なる疎通確認で 200 を返すだけでよさそう
ちなみに、アプリケーションのDB接続やミドルウェア接続等を確認するヘルスチェックは DeepHealthCheck って呼ばれてるらしい
ちなみに、DeepHealthCheck の運用はしっかり考えた方が良いぞって記事
例えば DeepHealthCheck に認証サーバーの疎通確認を含めると、そのサーバーが死んだらその他サービスも全部死んでしまう
これはこれで正しいかもしれないが、もっと影響範囲を少なくできるかも?みたいな話
運用するプロダクトによって『準備完了(Readiness)』の定義はしっかり検討しよう
ヘルスチェックのレスポンスのフォーマットに関しては、標準化したいねみたいな話自体はあったっぽい
ただ、結局のところ進んでなさそう
k8s で ヘルスチェックする場合はレスポンスのステータスコードを参照するので、レスポンスボディを検証するのは大変そう?
一応 command 使えるので、自前で実装するのはできそうな気がする
なので成功した場合は 200, 失敗は 503 返す実装で良さそう
一応、外向けに何のチェックをしているのか分かりやすくするなら、レスポンスボディに何らかの情報を付与すれば良さそう