ECSのHEALTHCHECKオプションでサービスの継続性を高めよう
ECSでは、Fargateや従来のECSサービスで「HEALTHCHECK」オプションを利用できるようになっています。
Amazon ECSはコンテナの健全性チェックとタスクの健全性管理をサポート AWS Fargate プラットフォームのバージョン 1.1 が、タスクメタデータ、コンテナのヘルスチェック、サービスディスカバリのサポートを追加
Docker自体は1.12
以降で「HEALTHCHECK」オプションを利用することができますが、ECSで利用するとステータスが「不健康」なタスクを止めて新しいものに置き換えることが自動で可能になります。
DockerのSwarmモードだと、HEALTCHCHCK機能を使ってサービスの再起動をすることができますが、同じことがECSでも可能になった、ということになります。
ECSでHEALTHCHECKオプションを設定する
すでにECS環境は作成されていることを前提として、その状態で新しいリビジョンの「タスク定義」を作成します。 「タスク定義」を作成する時に、「コンテナ定義」にある「詳細コンテナ設定」> 「HEALTHCHECK」の箇所で下記の通り編集します。
- Command
- ヘルスチェックに利用したいコマンドを記載します。
- 今回のコンテナはWebサーバを動かしているので、下記内容にしています。
CMD-SHELL,curl -f http://localhost/ || exit 1
- Inteval(second(s))
- 30
- 5〜300の間で秒指定です。デフォルト30です。
- Timeout(second(s))
- 5
- 2〜60の間で秒指定です。デフォルト5です。
- Start period(second(s))
- 3
- 0〜300の間で秒指定です。
- Retries(second(s))
- 3
- 1〜10の間で秒指定です。デフォルト3です。
上記設定で新しいリビジョンのタスク定義を作成して、新しいコンテナをリリースします。
この状態で、ECSインスタンス上のコンテナを確認してみます。
タスクの更新直後(新しいコンテナのリリース後)は、STATUS
がUp Less than a second (health: starting)
になってます。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfe94e48febd xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:1.4 "/usr/sbin/apache2 -…" 1 second ago Up Less than a second (health: starting) 0.0.0.0:80->80/tcp ecs-mytask-11-myapp-dcfb90ced0a8be83da01
30秒後に確認するとUp 30 seconds (healthy)
になりました。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfe94e48febd xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:1.4 "/usr/sbin/apache2 -…" 31 seconds ago Up 30 seconds (healthy) 0.0.0.0:80->80/tcp ecs-mytask-11-myapp-dcfb90ced0a8be83da01
表示が長くて見づらい時はdocker inspect
で確認することも可能です。
$ docker inspect --format="{{ .State.Health.Status }}" cfe94e48febd healthy
ちなみにdocker inspect
の出力ではヘルスチェックの定義内容も参照することが出来ます。Healthcheck
の定義部分を抜粋したものが以下です。
"Healthcheck": { "Test": [ "CMD-SHELL", "curl -f http://localhost/ || exit 1" ], "Interval": 30000000000, "Timeout": 5000000000, "StartPeriod": 3000000000, "Retries": 3 },
コンテナの自動置換えを試してみる
試す内容
これまでの作業でHEALTHCHECKが有効な状態になっていますので、この状態で「わざとunhealthyな状態」にしてみます。 期待するのは「ECSサービススケジューラでunhealthyなタスクを停止して、新規タスクを自動的に起動する事」です。
やってみる
ECSインスタンスで下記コマンドを実行してコンテナのステータスをunhealthy
にします。
HELTHCHECKでcurlコマンドを使っているので、curlコマンドをrm
で削除して実行できないようにしています。
$ docker exec rm /usr/bin/curl
しばらくするとSTATUSがunhealthy
になります。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8a820cc482a xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:1.4 "/usr/sbin/apache2 -…" 7 minutes ago Up 7 minutes (unhealthy) 0.0.0.0:80->80/tcp ecs-mytask-11-myapp-9692b7b9bac0d3e59a01 6bdec8b99246 amazon/amazon-ecs-agent:latest "/agent" 32 minutes ago Up 32 minutes ecs-agent
しばらくdocker ps
を叩いて確認していると、unhealthyなタスクが停止されて、新しいタスクが起動しました。
Up 59 seconds (healthy)
ECSのマネジメントコンソールでも、この様子を確認することができます。unhealthy
にするとタスクのステータスが「UNHEALTHY」と表示されています。
自動的にタスクの置き換えが発生した後に確認すると、下記のように「HEALTHY」に変わります。
最後に
本番環境でECSを利用する際は、Datadog等も併用した監視運用の体制を整える必要があるかと思いますが、このHEALTHCHECKオプションも組み合わせて利用することで、効率的な運用を行うことができると思います。 是非ご活用下さい!
以上です。