Carpe Diem

備忘録

ECSとFargateでコンテナの起動順が制御できるようになりました

概要

先日AWSの発表で

aws.amazon.com

と、コンテナの依存関係が制御できると発表がありました。

何が嬉しいかというと、サイドカー系コンテナに依存している場合アプリケーション側でそのコンテナの起動を待つ処理が必要だったのが、不要になるという点です。

christina04.hatenablog.com

こちらで以前デメリットとして指摘した点ですが、AWS側でサポートしてくれました!

まだ新しい機能なのでドキュメントも日本語対応していないため、確認する際は英語ドキュメントを参照してください。

Task Definition Parameters - Amazon Elastic Container Service

環境

以下の環境で利用可能です。旧バージョンで利用しようとするとコンテナが起動しないので注意してください。

  • ECS Container Agent 1.26.0-1以降
  • Fargate 1.3.0以降

Task Definitionの設定

以下の設定を追加することで制御できるようになります。

"dependsOn": [
    {
        "containerName": "string",
        "condition": "string"
    }
]

containerNameには依存するコンテナ名を。conditionは以下のパラメータです。

パラメータ 説明
START 依存するコンテナが起動したら
※起動完了ではない
従来のlinksと同じ挙動
COMPLETE 依存するコンテナが終了したら
SUCCESS COMPLETEと同じだがexit code: 0のときだけ
HEALTHY 依存するコンテナでdocker healthcheckを使ってHealthyになったら

いくつか例を示します。
環境はFargateを想定しています。

redisコンテナの起動後に起動したい

  {
    "name": "redis",
    "image": "redis:alpine",
    "cpu": 128,
    "memoryReservation": 512,
    "portMappings": [
      {
        "hostPort": 6379,
        "containerPort": 6379
      }
    ]
  },
  {
    "name": "web-app,
    "image": "web-app:latest",
    "cpu": 128,
    "memoryReservation": 128,
    "portMappings": [
      {
        "protocol": "tcp",
        "hostPort": 8000,
        "containerPort": 8000
      }
    ],
    "essential": true,
    "dependsOn": [
      {
        "containerName": "redis",
        "condition": "START"
      }
    ]
  }

dependsOnで依存するコンテナのnameを指定(今回だとredis)し、"condition": "START"でredisコンテナ起動後にweb-appコンテナを起動するようにしています。

redisコンテナが疎通可能(readiness)になってから起動したい

先程の書き方は起動順は守られていますが、redis自体がちゃんと疎通できるようになるまではまだ時間がかかります
それを考慮しないとせっかく起動順を制御したはずなのにコネクションを張れずコケる、ということも起きてしまいます。
なので以下のようにdocker healthcheckで疎通確認が取れてから起動させるのが安全です。
KubernetesでいうReadiness Probeみたいなものですね。

  {
    "name": "redis",
    "image": "redis:alpine",
    "cpu": 128,
    "memoryReservation": 512,
    "portMappings": [
      {
        "hostPort": 6379,
        "containerPort": 6379
      }
    ],
    "healthCheck": {
      "command": [
        "CMD-SHELL",
        "ping=\"$(redis-cli -h localhost ping)\" && [ \"$ping\" = 'PONG' ] || exit 1"
      ],
      "interval": 5,
      "retries": 3,
      "startPeriod": 5,
      "timeout": 5
    }
  },
  {
    "name": "web-app,
    "image": "web-app:latest",
    "cpu": 128,
    "memoryReservation": 128,
    "portMappings": [
      {
        "protocol": "tcp",
        "hostPort": 8000,
        "containerPort": 8000
      }
    ],
    "essential": true,
    "dependsOn": [
      {
        "containerName": "redis",
        "condition": "HEALTHY"
      }
    ]
  }

このように依存するコンテナではhealthCheckを設定し、dependsOn"condition": "HEALTHY"を設定します。

まとめ

コンテナの依存関係を管理できるようになり、また一つAWS ECS & Fargateが使いやすくなりました。

ソース