Amazon ECS on EC2でキャッシュされたコンテナイメージを使用するには?
Amazon ECS on EC2利用時に、コンテナの起動時間を短縮させるために、ホストでキャッシュされたコンテナイメージを使用したいことがあります。
Amazon ECS コンテナエージェントの環境変数「ECS_IMAGE_PULL_BEHAVIOR」を利用すると、イメージのプルプロセスをカスタマイズできます。
ECS_IMAGE_PULL_BEHAVIOR パラメーター
4つの中から選べます(説明文はマニュアルから引用)。
- キャッシュを優先しない
default
: リモートでイメージがプルされます。イメージのプルに失敗した場合、コンテナはそのインスタンスにキャッシュされたイメージを使用します。always
: 常にリモートでイメージがプルされます。イメージのプルに失敗した場合、そのタスクは失敗します。このオプションを選択すると、最新バージョンのイメージが常にプルされます。キャッシュされたイメージはすべて無視され、イメージの自動クリーンアッププロセスが適用されます。
- キャッシュを優先する
once
: 同じコンテナインスタンスの以前のタスクによりイメージがプルされていないか、自動クリーンアッププロセスによってキャッシュされたイメージが削除された場合にのみ、イメージがリモートでプルされます。それ以外の場合は、インスタンスにキャッシュされたイメージが使用されます。これにより、不要なイメージのプルがなくなります。prefer-cached
: キャッシュされたイメージがない場合に、リモートでイメージがプルされます。それ以外の場合は、インスタンスにキャッシュされたイメージが使用されます。キャッシュされたイメージが削除されないように、そのコンテナの自動イメージクリーンアップは無効です。
Linux/Windows ともにデフォルト値は default
でまずはリモートからプルします。
結果的に、タグ名を固定する運用であっても、常に最新のイメージを利用できます。
ECS on Fargate は挙動としては always
に該当します。
また、イメージの自動クリーンアッププロセスは次のドキュメントを参照ください。
自動化タスクとイメージのクリーンアップ - Amazon Elastic Container Service
やってみた
ホストでキャッシュされたイメージを使用するように設定変更し(ECS_IMAGE_PULL_BEHAVIOR=once
)、イメージhttpd:2.4
を利用したタスクを起動して設定の違いを確認します。
デフォルト設定
まずはデフォルト設定での挙動を確認します。
default
モードではリモートからイメージがプルされ、イメージのプルに失敗した場合、コンテナはそのインスタンスにキャッシュされたイメージを使用します。
初期状態
ECS_CLUSTER=test ECS_BACKEND_HOST=
ECSクラスター起動直後は、タスクのイメージはホストには存在しません。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazon/amazon-ecs-agent latest 52b440d0453a 7 days ago 61.4MB amazon/amazon-ecs-pause 0.1.0 4451bd4bb15a 7 days ago 954kB
タスクを起動
タスク起動時のエージェントのログを確認します。
Task engine [...]: pulling image httpd:2.4 for container sample-zz-app concurrently" module=docker_task_engine.go Task engine [...]: recording timestamp for starting image pulltime: 2021-01-28 19:36:11.914154829 +0000 UTC m=+125.610526843" module=docker_task_engine.go Adding image name- httpd:2.4 to Image state- sha256:683a7aad17d3baed344799b397c55a9ccbc3ddabf0d077862739585ee76d4cb3" module=types.go Updating container reference sample-zz-app in Image State - sha256:683a7aad17d3baed344799b397c55a9ccbc3ddabf0d077862739585ee76d4cb3" module=types.go Task engine [...]: finished pulling image httpd:2.4 for container sample-zz-app in 4.653489084s" module=docker_task_engine.go
※ msg 部分のみ抜粋
"pulling image httpd:2.4 for container ..." からイメージをプルしていることがわかります。 プルプロセスには約6秒かかっていました。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazon/amazon-ecs-agent latest 52b440d0453a 7 days ago 61.4MB amazon/amazon-ecs-pause 0.1.0 4451bd4bb15a 7 days ago 954kB httpd 2.4 683a7aad17d3 2 weeks ago 138MB
同じイメージを使ったコンテナをもう一度起動します。
Task engine [...]: pulling image httpd:2.4 for container sample-zz-app concurrently" module=docker_task_engine.go Task engine [...]: recording timestamp for starting image pulltime: 2021-01-28 19:43:08.580561889 +0000 UTC m=+31.046339842" module=docker_task_engine.go Updating container reference sample-zz-app in Image State - sha256:683a7aad17d3baed344799b397c55a9ccbc3ddabf0d077862739585ee76d4cb3" module=types.go Task engine [...]: finished pulling image httpd:2.4 for container sample-zz-app in 1.597031292s" module=docker_task_engine.go
ホストにイメージキャッシュが存在するにも関わらず、初回と同じくリモートからプルしています。 プルプロセスも約6秒かかっていました。
once設定
次に、ホストのキャッシュを優先する once
に設定変更します。
ECS_CLUSTER=test ECS_BACKEND_HOST= ECS_IMAGE_PULL_BEHAVIOR=once
タスクを起動
先ほどと同じイメージのコンテナを起動します。
Task engine [..]: image httpd:2.4 for container sample-zz-app has been pulled once, not pulling it again" module=docker_task_engine.go
"image httpd:2.4 for container sample-zz-app has been pulled once, not pulling it again" からキャッシュを利用していることがわかりますね。
約6秒かかっていたプルプロセスがほぼ0秒になりました。
ECS on Fargate ではキャッシュを利用できない
今回紹介したキャッシュ設定は ECS on EC2 では利用できますが ECS on Fargate では利用できません。
起動時間の短縮や転送量削減のために、待ち望んでいる人は多いかと思います。
次の GitHub 上のイシューでロードマップに積まれているので、今後に期待しましょう。