AWS FargateでSeekable OCIを使ってみた
Fargateの弁慶の泣き所である、コンテナ起動時間の短縮に役立ちそうな機能ができてたので、構築中のアプリケーションで試してみました。
Seekable OCIとは
「Seekable OCI」は、コンテナイメージの各レイヤーを、コンテナ起動時に非同期で読み込むことで、起動時間を短縮する機能のようです。
イメージ自体をいじらずとも適用できるので、手離れもよく利用しやすいのではないかと思います。
なお、本機能の利用自体は無料ですが、ECRリポジトリに追加でインデックスを保存するため、ECRの従量料金がかかることに注意が必要です。
Fargate上で利用する場合は、
- コンテナイメージがx86_64アーキテクチャであること
- Linuxプラットフォームバージョンが
1.4.0
であること
が必須のようです。
前提
- nginx + php-fpmをベースとしたLaravelアプリケーション
- イメージサイズはnginxが58.09MB、appが253.41MB
- 構築にTerraformを利用
実装
SOCI インデックスの作成方法には2つあるようですが、手動で作るのは普通にめんどくさそうなので、今回はAWS SOCI Index Builderを利用してみます。
Terraformコード
親切なことに、CloudformationでBuilderを構築するテンプレートが用意されているので、以下のようにECRとCloudformationのリソースを用意するだけです。
resource "aws_ecr_repository" "main" {
name = local.ecr_repository_name
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
tags = merge(
local.module_tags,
{
"Name" = local.ecr_repository_tag_name
}
)
}
resource "aws_cloudformation_stack" "soci_index_builder" {
name = local.soci_index_builder_cloudformation_stack_name
template_url = local.soci_index_builder_cloudformation_template_url
capabilities = ["CAPABILITY_IAM"]
parameters = {
"SociRepositoryImageTagFilters" = "${aws_ecr_repository.main.name}:*"
}
tags = merge(
local.module_tags,
{
"Name" = local.soci_index_builder_cloudformation_stack_name
}
)
}
Local変数は適宜指定します。
また、template_url
には、https://aws-quickstart.s3.us-east-1.amazonaws.com/cfn-ecr-aws-soci-index-builder/templates/SociIndexBuilder.yml
を指定します。
テンプレートを見るとわかりますが、IAM Policyを作成する必要があるので、capabilities
にはCAPABILITY_IAM
を指定しておきます。
なお、SociRepositoryImageTagFilters
はリポジトリ名もタグ名もワイルドカード指定ができるので、AWSアカウント内のすべてのECRリポジトリを対象にする場合は、Terraformで書かずとも普通にAWSコンソールからCloudformationを実行すればよいかと思われます。
2023/07/28 17:39追記
ステージごとにCloudFormationスタックを作ろうとしたら、IAMポリシーが同じ名前になって失敗するので、こういう使い方は想定されてないかもしれない。
もし解消するならテンプレートごとコピーしてこないとアカンので、めんどくさいので普通にGUIで1つだけスタックを作ったほうが良さそう。
効果
計測のため、参考記事からシェルスクリプトをお借りしました。
CLUSTER=<クラスタ名>
TASKDEF=<タスク定義名>
REGION=ap-northeast-1
TASKS=$(aws ecs list-tasks \
--cluster $CLUSTER \
--family $TASKDEF \
--region $REGION \
--query 'taskArns[*]' \
--output text)
aws ecs describe-tasks \
--tasks $TASKS \
--region $REGION \
--cluster $CLUSTER \
--query "tasks[] | reverse(sort_by(@, &createdAt)) | [].[{startedAt: startedAt, createdAt: createdAt, taskArn: taskArn}]" \
--output table
SOCIあり
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| DescribeTasks |
+----------------------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| createdAt | startedAt | taskArn |
+----------------------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| 2023-07-28T15:26:51.984000+09:00| 2023-07-28T15:27:27.017000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-dev-application-internet-main-ecs-cluster/cfdcfb02386b44c1b3281902cf6b68bd |
| 2023-07-28T15:26:51.984000+09:00| 2023-07-28T15:27:17.523000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-dev-application-internet-main-ecs-cluster/c949491479f84705b12ddbd850b2caa4 |
| 2023-07-28T15:26:51.984000+09:00| 2023-07-28T15:27:27.529000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-dev-application-internet-main-ecs-cluster/b42613cf3da440f5b7140c9debb98eb6 |
| 2023-07-28T15:12:22.130000+09:00| 2023-07-28T15:12:51.774000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-dev-application-internet-main-ecs-cluster/4b5e0ca2d205455096e2133986767141 |
+----------------------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
SOCIなし
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| DescribeTasks |
+----------------------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| createdAt | startedAt | taskArn |
+----------------------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| 2023-07-28T15:32:47.351000+09:00| 2023-07-28T15:33:28.911000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-stg-application-internet-main-ecs-cluster/ab5206b22b934273b535cedd21c891a9 |
| 2023-07-28T15:32:47.351000+09:00| 2023-07-28T15:33:26.963000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-stg-application-internet-main-ecs-cluster/532399ba040a41f8821796b061e98b15 |
| 2023-07-28T15:32:47.351000+09:00| 2023-07-28T15:33:32.574000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-stg-application-internet-main-ecs-cluster/4a77056382b1491bbc774c513fb9419a |
| 2023-07-28T11:11:25.552000+09:00| 2023-07-28T11:12:06.761000+09:00 | arn:aws:ecs:ap-northeast-1:************:task/********-stg-application-internet-main-ecs-cluster/514908dafca24894b7dbd3a03a878e6b |
+----------------------------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
同一内容のイメージを利用しているdev(SOCIあり)とstg(SOCIなし)で比較した結果、SOCIありは26秒~36秒、SOCIなしは39秒~43秒ということで、たしかに高速化しているようです。
まとめ
- AWS FargateにおいてSeekable OCIが使えるようになった
- 起動時間は数秒~十数秒程度短縮された
- もっとイメージサイズが大きいと効果が大きいかも?
- Cloudformationテンプレートが用意されているので、一瞬で利用開始できた
Discussion