Amazon Web Services ブログ

Amazon ECS におけるソフトウェアバージョンの一貫性の実現

この記事は Announcing software version consistency for Amazon ECS services (記事公開日: 2024 年 7 月 11 日) の翻訳記事です。

概要

コンテナイメージタグは、様々なバージョンのコンテナイメージを管理および追跡するためのユーザーフレンドリーな方法を提供します。しかし、コンテナイメージの可変性 (mutability) は、組織にセキュリティリスクをもたらします。適切な予防策を実施しない場合、コンテナイメージリポジトリにおいて、全く別のコンテナイメージを参照するようにコンテナイメージタグが変更されてしまう恐れがあります。そのため、ワークロード定義時に指定したコンテナイメージと、ワークロード実行時に使用されるコンテナイメージが異なる状況が発生します。

本日より、Amazon Elastic Container Service (ECS) は、アプリケーションのソフトウェアバージョンの一貫性を保証するようになりました。この新機能では、ECS サービスの各バージョン (デプロイメント) において、Amazon ECS がコンテナイメージタグをコンテナイメージダイジェストに解決します。これにより、デプロイメントライフサイクル全体で同一のコンテナイメージが使用されることを保証し、ECS サービスとしてデプロイされたアプリケーションのセキュリティと一貫性を向上させることができます。

背景

ECS サービスは、Web や API ワークロードなど、長時間実行されるアプリケーションで使用される同一のタスクのグループです。Amazon ECS では、ECS サービスのデプロイメントという形で ECS サービスのバージョンとタスク定義リビジョンを紐付けることで、サービス内のすべてのタスクが同一であることを保証します。ただし、タスク定義リビジョン内で (コンテナイメージダイジェストではなく) コンテナイメージタグを使用した場合、この一貫性が損なわれる可能性があります。

コンテナイメージはイミュータブル (不変) です。コンテナイメージをビルドすると、コンテナイメージダイジェスト (sha256 ダイジェスト) が作成されます。このイメージダイジェストは、コンテナイメージの中身のチェックサムを元に作成されるため、そのコンテナイメージを象徴するメタデータの 1 つとなります。しかし、イメージダイジェストを用いてコンテナイメージを参照することはあまりなく、多くの場合、イメージタグを用いて参照します。

コンテナイメージタグはイミュータブル (不変) ではなく、ミュータブル (可変) です。ある時点でイメージタグが特定のコンテナイメージダイジェストを参照していたとしても、その後、別のコンテナイメージダイジェストを参照するように更新される可能性があります。これは latest イメージタグを使用する場合にありがちです。latest という名前のイメージタグを使用し、ソフトウェアの新しいバージョンがリリースされる度に latest タグを新しいコンテナイメージに紐付け直しているプロジェクトをよく見かけます。Amazon ECR のタグイミュータビリティのように、コンテナイメージレジストリがイメージタグの変更を防ぐ機能を実装している場合もありますが、未だに多くのプロジェクトで latest タグを用いた運用が採用されています。

Amazon ECS におけるソフトウェアバージョンの一貫性

本日より、ECS デプロイメントコントローラー (ローリングアップデート) を使用する ECS サービスは、タスク定義リビジョンがコンテナイメージタグを参照していても、デプロイメントライフサイクル全体で同一のコンテナイメージダイジェストを使用することが保証されます。Amazon ECS は、最初のタスクのデプロイ時にコンテナランタイムがイメージタグを解決する際、イメージダイジェストを保存しておきます。そして、そのデプロイメントにおける他のすべてのタスクは、保存したイメージダイジェストを参照する形になります。

これまで Amazon ECS では、それぞれのタスクのコンテナランタイムが独立してイメージタグをイメージダイジェストに解決していました。そのため、特定のデプロイメントにおいて頻繁にスケールインまたはスケールアウトが発生し、その間にコンテナイメージタグが新しいコンテナイメージダイジェストを参照するように更新された場合、同一の ECS サービスのデプロイメント内で異なるコンテナイメージが実行される可能性がありました。

今後、ECS サービスのデプロイメント (新規サービスの作成または既存サービスの更新) では、最初のタスクのデプロイ後、コンテナイメージタグがコンテナイメージダイジェストに変換、保存されます。ECS サービスのデプロイメントは、以下の順番で実施されます。

Amazon ECS サービス

  1. ユーザーが ECS サービスを新規作成または更新します。
  2. Amazon ECS は、ECS サービスの desiredCount に関わらず、まず 1 つのタスクをスケジューリングします。
  3. このタスクが実行状態になると、タスク内で実際に使用されたすべてのコンテナイメージダイジェストが確認され、Amazon ECS に報告されます。
  4. このデプロイメントにおける他のすべてのタスクは、コンテナイメージタグではなく、コンテナイメージダイジェストを用いてスケジューリングされます。これにより、このデプロイメントに含まれるすべてのタスクが同じコンテナイメージを使用することが保証されます。

注 : タスク定義でコンテナイメージタグを使用せず、各コンテナイメージをダイジェストで参照している場合、この新しいデプロイメントの仕組みに従いません。この場合、すべてのタスクを同時にスケジューリングする従来の ECS の動作が適用されます。

ウォークスルー

ECS サービスにおけるソフトウェアバージョンの一貫性は、既存の ECS サービスにおいて新しくデプロイメントを開始することで確認できます。新しく ECS サービスを作成する場合は、Amazon ECS 開発者ガイドが参考になります。既存の ECS サービスを利用する場合は、aws ecs update-service コマンドで新しくデプロイメントを開始できます。

$ aws ecs update-service --cluster $CLUSTER --service $SERVICE --force-new-deployment

新しくデプロイメントが作成されたら、DescribeTask API を使用してタスクを検証し、コンテナイメージタグが解決されていることを確認できます。まず、ECS サービスで実行中のタスクの一覧を取得します。

$ TASK_ARNS=$(aws ecs list-tasks --cluster $CLUSTER --service $SERVICE --query 'taskArns[]' --output text)

次に、タスクの詳細を出力して --query フラグで解析すると、ある 1 つのタスクではコンテナイメージタグが使用されている一方で、その他のすべてのタスクではコンテナイメージダイジェストが使用されていることを確認できます。

$ aws ecs describe-tasks --tasks $TASK_ARNS --query 'tasks[*].{taskArn:taskArn,containerName:containers[0].name,containerImage:containers[0].image}'
[
    {
        "taskArn": "arn:aws:ecs:eu-west-1:111222333444:task/default/279034d4f56b40239e72881c19acc58f",
        "containerName": "containerone",
        "containerImage": "public.ecr.aws/docker/library/nginx@sha256:ac96a05e4b3dd2c57c9ca2637012f4fa17b11d5fdd2ce856c2f937bd843f0440"
    },
    {
        "taskArn": "arn:aws:ecs:eu-west-1:111222333444:task/default/e1174f0425ab435fb5abb1a661e6fd9c",
        "containerName": "containerone",
        "containerImage": "public.ecr.aws/docker/library/nginx@sha256:ac96a05e4b3dd2c57c9ca2637012f4fa17b11d5fdd2ce856c2f937bd843f0440"
    },
    {
        "taskArn": "arn:aws:ecs:eu-west-1:111222333444:task/default/199bd6a195f645a7ab1b503e3598e5c4",
        "containerName": "containerone",
        "containerImage": "public.ecr.aws/docker/library/nginx:stable"
    }
]

また、DescribeService API を使用して、デプロイメントのイベントを表示してみます。この出力では、コンテナイメージダイジェストを取得するために 1 つのタスクを起動し、その後で他のタスクを開始する、新しいデプロイメントのパターンを確認できます。このとき、古いイベントが下の方に表示されることに注意してください。

$ aws ecs describe-services --cluster $CLUSTER --services $SERVICE --query 'services[0].events'
[
    {
        "id": "bf43bbc6-ad78-4316-9a8c-6b561a0c035a",
        "createdAt": "2024-06-07T14:22:31.089000+00:00",
        "message": "(service fargate-service-demo) has reached a steady state."
    },
    {
        "id": "4c3f3830-6291-47e0-a0d6-ee19f43076f8",
        "createdAt": "2024-06-07T14:22:31.088000+00:00",
        "message": "(service fargate-service-demo) (deployment ecs-svc/4506290861204002986) deployment completed."
    },
    {
        "id": "350e8c3c-890e-428c-846f-f900d964f234",
        "createdAt": "2024-06-07T14:22:13.171000+00:00",
        "message": "(service fargate-service-demo) registered 2 targets in (target-group arn:aws:elasticloadbalancing:us-west-2:111222333444:targetgroup/defaulttgtss/74939c377ec7273a)"
    },
    {
        "id": "985ce76c-ade8-4103-9569-82dca19f95af",
        "createdAt": "2024-06-07T14:21:24.685000+00:00",
        "message": "(service fargate-service-demo) has started 2 tasks: (task 569abf2a0c1f4694882c643194278919)."
    },
    {
        "id": "290cdfd3-513a-4477-83d9-690352865bc6",
        "createdAt": "2024-06-07T14:21:18.138000+00:00",
        "message": "(service fargate-service-demo) registered 1 targets in (target-group arn:aws:elasticloadbalancing:us-west-2:111222333444:targetgroup/defaulttgtss/74939c377ec7273a)"
    },
    {
        "id": "63bfc91d-8ad6-4764-9c35-149fdfa668e9",
        "createdAt": "2024-06-07T14:20:33.898000+00:00",
        "message": "(service fargate-service-demo) has started 1 tasks: (task 08738ec750d84695ae2e12800d7a31df)."
    }
]

CodeDeploy または External デプロイメントコントローラーを使用する ECS サービスなど、コンテナイメージタグがコンテナイメージダイジェストに解決されない場合もあります。例外事項の詳細については、Amazon ECS ドキュメントを参照してください。

まとめ

ソフトウェアバージョンの一貫性のリリースにより、ECS サービスとして実行されるすべてのタスクが、同一かつイミュータブルなコンテナイメージを使用することを保証できるようになりました。この機能追加によって、Amazon ECS 上で実行されるコンテナアプリケーションの信頼性とセキュリティが大幅に向上します。タスクが意図せずに異なるコンテナイメージを使用するリスクを排除することで、開発者はワークロードの一貫性と予測可能性に対して自信を持つことができます。この機能の利用方法や Amazon ECS の他の機能の詳細は、Amazon ECS ドキュメントを参照してください。AWS コンテナサービスのロードマップにて、フィードバックや提案をお待ちしています。