ECSの文脈でヘルスチェックといえば、次の2通りが挙げられる。
1はECSではなくELBの機能なので、これら2つを組み合わせて使う場合に限定される。
結論
- 1.のELBによるヘルスチェックでは、「アプリケーションが新規のリクエストを受付できること」だけを検証するべき。例えば、"ok"などの単純な文字列を返したり、小さな静的コンテンツを返すようなパスを指定する。
- 2.のコンテナヘルスチェックに関しては任意のコマンドが書けるためHTTPリクエストとは限らないが、方針としては1.と同じ。
説明
上記の2通りのヘルスチェックが失敗した場合はいずれもタスクが終了し、ECSスケジューラによって新たなタスクに置換される。 そのため、タスク(コンテナ)を再起動するしか新たなリクエストを受付できない、あるいは終了するほかない場合に限り、ヘルスチェックを失敗させるべき。このような状況は次のようなケースが該当する。
- アプリケーションが完全にハングした
- タスクのメモリ・ストレージが限界
- ハードウェア障害
そのため、ヘルスチェックで実行される処理はこういった状況を検出できる必要十分なものに留める必要がある。
逆に、DBや外部APIに接続するような処理を含むエンドポイントはヘルスチェックに指定すべきではない。これらの外部の依存が利用できない時は
- インフラ設定の不備によって疎通できない
- 認証情報などの誤りで接続できない
- 外部依存側の障害で接続できない
などが考えられるが、いずれも(特定のケースを除いて)ECSタスクを再起動して解決する問題ではない。その上、
- タスクが終了してしまうことによって、ecs execなどを使ったトラブルシューティングが難しくなる。
- ECSが再起動を繰り返すため、エンドユーザがアプリケーション自体に接続できなくなる。部分的にアプリケーションを利用したり、案内メッセージを出したりできないため、ユーザに対しては不親切。
といった問題が生じる。
DBや外部APIに接続するような処理を含むエンドポイントは、モニタリングの統合監視(Synthetics Monitoring)で利用するのが良さそう。
補足
よくECSの比較対象として挙げられるKubernetesでは、失敗時の挙動が異なる複数のヘルスチェックが用意されている。
- liveness probe: 失敗時は該当Podを終了させる
- rediness probe: 失敗時は該当Podにトラフィックが転送されない
ECSにはこれらの違いはなく、ヘルスチェックが失敗した場合はタスクが終了し、スケジューラによって新たなタスクに置換される。つまり、ECSはKubenetesで言うliveness probeの機能を持ったヘルスチェック機構しか持っていない(rediness probeに対応するヘルスチェック機構を求めるfeature requestはある)。