💨

Amazon ECS Managed Instance は Image Pull Cache を使うのか

に公開

先に結果

  • ECS Managed Instance では Image Pull Cache は使われている
  • しかし、Document に明記されている場所はない
  • 挙動について Document に追記されました。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/managed-instance-pull-behavior.html

コンテナ基盤ごとの Image Pull Cache について

Amazon ECS で AWS Fargate を利用するとコンテナイメージはタスクが起動するたびに pull されます。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/fargate-pull-behavior.html

Fargate 上で Linux コンテナを実行すると、コンテナイメージまたはコンテナイメージレイヤーはインスタンスにキャッシュされません。したがって、タスクで定義されたコンテナイメージごとに、コンテナイメージ全体を各 Fargate タスクのコンテナイメージレジストリからプルする必要があります。イメージをプルするのにかかる時間は、Fargate タスクを開始するのにかかる時間と直接相関しています。

そのため、サイズの大きいコンテナイメージを毎回 pull することにより、パフォーマンスの低下や通信のコストが課題となることがあります。

一方、EC2 を利用する場合は Image Pull Cache が利用できます。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-config.html

Image Pull Cache の設定方法

具体的には ecs-agent の ECS_IMAGE_PULL_BEHAVIOR を設定することで cache の動作を設定できます。
https://github.com/aws/amazon-ecs-agent/blob/master/README.md#:~:text=ECS_IMAGE_PULL_BEHAVIOR

  • default
    • リモートでイメージがプルされます。イメージのプルに失敗した場合、コンテナはそのインスタンスにキャッシュされたイメージを使用します。
  • always
    • 常にリモートでイメージがプルされます。イメージのプルに失敗した場合、そのタスクは失敗します。このオプションを選択すると、最新バージョンのイメージが常にプルされます。キャッシュされたイメージはすべて無視され、イメージの自動クリーンアッププロセスが適用されます。
  • once
    • 同じコンテナインスタンスの以前のタスクによりイメージがプルされていないか、自動クリーンアッププロセスによってキャッシュされたイメージが削除された場合にのみ、イメージがリモートでプルされます。それ以外の場合は、インスタンスにキャッシュされたイメージが使用されます。これにより、不要なイメージのプルがなくなります。
  • prefer-cached
    • キャッシュされたイメージがない場合に、リモートでイメージがプルされます。それ以外の場合は、インスタンスにキャッシュされたイメージが使用されます。キャッシュされたイメージが削除されないように、そのコンテナの自動イメージクリーンアップは無効です。

しかし、ECS Managed Instance において ecs-agent は AWS 管理であるため設定の変更ができません。ECS_IMAGE_PULL_BEHAVIOR を確認/変更できないため Image Pull Cache がどのように設定されているのかわかりません。

実際にためしてみる

  • CDK で ECS Managed Instance を利用する ECS Cluster を作成

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ManagedInstancesCapacityProvider.html

  • ECS Managed Instance で起動した EC2 を連続で使用するために keep-alive 用の ECS Task を作成

Task Definition (一部抜粋)

  "compatibilities": [
    "EC2",
    "MANAGED_INSTANCES"
  ],
  "containerDefinitions": [
    {
      "command": [
        "sleep",
        "infinity"
      ],
      "cpu": 128,
      "image": "alpine:latest",
      "logConfiguration": {
        ...
      },
      "memoryReservation": 256,
      ...
    }
  ],
...

これを ECS Service として登録し、起動しておく

  • 計測用の ECS Task を作成

Task Definition (一部抜粋)

  "compatibilities": [
    "EC2",
    "MANAGED_INSTANCES"
  ],
  "containerDefinitions": [
    {
      "cpu": 1024,
      "image": "tensorflow/tensorflow:latest-gpu",
      "logConfiguration": {
        ...
      },
      "memoryReservation": 2048,
      "name": "TestContainer",
    }
  ],
  ...

これを Run Task で起動する

$ aws ecs run-task \
  --cluster [クラスター名] \
  --task-definition [タスク定義名]:[リビジョン] \
  --capacity-provider-strategy capacityProvider=[キャパシティプロバイダーのID],weight=1 \
  --network-configuration "awsvpcConfiguration={subnets=[サブネットID],securityGroups=[セキュリティグループID],assignPublicIp=DISABLED}" \
  --query 'tasks[0].taskArn' \
  --output text

計測結果

ECS のイベントから pull 時間を計算

1回目の Run Task

$ aws ecs describe-tasks --cluster [クラスター名] --tasks [1回目のタスクID] --query 'tasks[0].{PullStartedAt:pullStartedAt,PullStoppedAt:pullStoppedAt}' --output table
--------------------------------------------------------------------------
|                              DescribeTasks                             |
+-----------------------------------+------------------------------------+
|           PullStartedAt           |           PullStoppedAt            |
+-----------------------------------+------------------------------------+
|  2025-10-17T14:38:27.766000+09:00 |  2025-10-17T14:40:32.403000+09:00  |
+-----------------------------------+------------------------------------+

2回目の Run Task

$ aws ecs describe-tasks --cluster [クラスター名] --tasks [2回目のタスクID] --query 'tasks[0].{PullStartedAt:pullStartedAt,PullStoppedAt:pullStoppedAt}' --output table
--------------------------------------------------------------------------
|                              DescribeTasks                             |
+-----------------------------------+------------------------------------+
|           PullStartedAt           |           PullStoppedAt            |
+-----------------------------------+------------------------------------+
|  2025-10-17T14:42:21.361000+09:00 |  2025-10-17T14:42:21.580000+09:00  |
+-----------------------------------+------------------------------------+
n Pull開始 Pull完了 Pull時間
1回目 14:38:27 14:40:32 2分5秒
2回目 14:42:21.361 14:42:21.580 0.219秒

だいぶ早いですね。
もうちょっとやってみましょう。

1回目

--------------------------------------------------------------------------
|                              DescribeTasks                             |
+-----------------------------------+------------------------------------+
|           PullStartedAt           |           PullStoppedAt            |
+-----------------------------------+------------------------------------+
|  2025-10-17T15:21:04.716000+09:00 |  2025-10-17T15:23:12.327000+09:00  |
+-----------------------------------+------------------------------------+

2回目

--------------------------------------------------------------------------
|                              DescribeTasks                             |
+-----------------------------------+------------------------------------+
|           PullStartedAt           |           PullStoppedAt            |
+-----------------------------------+------------------------------------+
|  2025-10-17T15:24:38.885000+09:00 |  2025-10-17T15:24:39.136000+09:00  |
+-----------------------------------+------------------------------------+

3回目

--------------------------------------------------------------------------
|                              DescribeTasks                             |
+-----------------------------------+------------------------------------+
|           PullStartedAt           |           PullStoppedAt            |
+-----------------------------------+------------------------------------+
|  2025-10-17T15:25:27.408000+09:00 |  2025-10-17T15:25:27.651000+09:00  |
+-----------------------------------+------------------------------------+
n Pull開始 Pull完了 Pull時間
1回目 15:21:04.716 15:23:12.327 2分8秒
2回目 15:24:38.885 15:24:39.136 0.251秒
3回目 15:25:27.408 15:25:27.651 0.243秒

Image Pull Cache が効いていそうですね!

再度結果

  • ECS Managed Instance では Image Pull Cache は使われている
  • しかし、Document に明記されている場所はない
  • 挙動について Document に追記されました。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/managed-instance-pull-behavior.html

Discussion