ECSのHEALTHCHECKオプションでサービスの継続性を高めよう

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ECSでは、Fargateや従来のECSサービスで「HEALTHCHECK」オプションを利用できるようになっています。

Amazon ECSはコンテナの健全性チェックとタスクの健全性管理をサポート
AWS Fargate プラットフォームのバージョン 1.1 が、タスクメタデータ、コンテナのヘルスチェック、サービスディスカバリのサポートを追加

Docker自体は1.12以降で「HEALTHCHECK」オプションを利用することができますが、ECSで利用するとステータスが「不健康」なタスクを止めて新しいものに置き換えることが自動で可能になります。

DockerのSwarmモードだと、HEALTCHCHCK機能を使ってサービスの再起動をすることができますが、同じことがECSでも可能になった、ということになります。

ECSでHEALTHCHECKオプションを設定する

すでにECS環境は作成されていることを前提として、その状態で新しいリビジョンの「タスク定義」を作成します。 「タスク定義」を作成する時に、「コンテナ定義」にある「詳細コンテナ設定」> 「HEALTHCHECK」の箇所で下記の通り編集します。

01-ecs-health-check

  • 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インスタンス上のコンテナを確認してみます。 タスクの更新直後(新しいコンテナのリリース後)は、STATUSUp 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 <CONTAINER ID>の出力ではヘルスチェックの定義内容も参照することが出来ます。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 <CONTAINER ID> 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」と表示されています。

03-unhealthy-amc

自動的にタスクの置き換えが発生した後に確認すると、下記のように「HEALTHY」に変わります。

04-healthy-amc

最後に

本番環境でECSを利用する際は、Datadog等も併用した監視運用の体制を整える必要があるかと思いますが、このHEALTHCHECKオプションも組み合わせて利用することで、効率的な運用を行うことができると思います。
是非ご活用下さい!

以上です。