👀

AWS FargateでSeekable OCIを使ってみた

2023/07/28に公開

https://dev.classmethod.jp/articles/update-aws-fargate-seekable-oci/?utm_source=go.pardot.com&utm_medium=mail&utm_content=blog&utm_campaign=2307_mailmagazine

Fargateの弁慶の泣き所である、コンテナ起動時間の短縮に役立ちそうな機能ができてたので、構築中のアプリケーションで試してみました。

Seekable OCIとは

https://aws.amazon.com/jp/about-aws/whats-new/2023/07/aws-fargate-container-startup-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コード

https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create?stackName=cfn-ecr-aws-soci-index-builder&templateURL=https://aws-quickstart.s3.us-east-1.amazonaws.com/cfn-ecr-aws-soci-index-builder/templates/SociIndexBuilder.yml

親切なことに、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失敗の図
ステージごとに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