Seekable OCIでECSのタスク起動速度をお手軽に改善しよう

はじめに

DTダイナミクスでSREセクションのテックリードをしている霜鳥です。
今回はECSタスクの起動速度を改善するのにSeekable OCI(SOCI)が非常にお手軽で効果が抜群だったのでご紹介していきます!

その他、霜鳥が書いた過去の記事はこちら。

Seekable OCIとは

詳細は下記ドキュメントに譲りますが、
ECS on FargateにてECRからイメージをpullする際にインデックスを用いて、
まずタスクが起動するのに必要なレイヤーだけを読み込み、起動と並行しながら残りのレイヤーをダウンロードするという遅延読み込みの技術です。
250MBを超えるコンテナイメージに対しては非常に有効で、逆にそれ以下はあまり恩恵が得られないかもしれません。

cf: 詳解 : Seekable OCI を使用した AWS Fargate におけるコンテナイメージの遅延読み込み

導入

ここだけきくと導入難易度の高いものに聞こえるかもしれませんが、実は既存のシステムにもめちゃくちゃ簡単に導入できます!
必要な手順は2つだけ。

  1. ECRリポジトリにSOCIのメタデータを作成する
  2. ECSがSOCIを使えるようにする

これだけです。
詳しく解説していきます。

1. ECRリポジトリにSOCIのメタデータを作成する

ここが一番難易度の高そうな部分ではあるのですが、実はAWS側ですでに用意された仕組みがあります。
その名もSOCI Index Builder
ECRに新しいイメージがpushされたというイベントによってEventBridge経由でLambdaを起動し、自動でSOCIインデックスを作成してくれるCloudFormationのスタックです。
具体的手順は以下です。

  1. CloudFormationを開く
  2. スタックの作成
  3. Amazon S3 URL:https://aws-quickstart.s3.us-east-1.amazonaws.com/cfn-ecr-aws-soci-index-builder/templates/SociIndexBuilder.yml
  4. その他スタック名などは適当にスタックを作成
  5. ECRに新しいイメージをpushする

これでしばらくしてECRリポジトリアーティファクト・タイプSoci Indexが追加されていればOKです。

cf: CFN AWS SOCI Index Builder on AWS Partner Solution Deployment Guide

2. ECSがSOCIを使えるようにする

ECS on Fargateに対してする設定は1つだけで、タスク実行ロール(Task Execution Role)に以下の権限を追加するだけです。

# iam.tf
statement {
 effect = "Allow"
 actions = [
   "soci:ListSOCIIndexes"
 ]
 resources = ["*"]
}

効果

具体的にはECSのライフサイクルのPENDINGの部分が大幅に短縮されます。
これまで5分以上掛かっていた1〜3GB程度の大きなイメージを30〜1分程度で起動できるようになりました。
このあたりの定量的な評価はまた追々やっていきたいなと思います。

確認方法

ECR

ECRに正しくSOCIインデックスが作成されているかはdescribe-imagesコマンドで確認できます。
以下のようにartifactMediaTypeにSOCIインデックスが含まれていればOKです。

aws ecr describe-images --repository-name <リポジトリ名>
# {
#    "registryId": "XXXXXXXX",
#    "repositoryName": "XXXXXXXX",
#    "imageDigest": "XXXXXXXX",
#    "imageSizeInBytes": 27176954,
#    "imagePushedAt": "2025-02-20T20:29:09.554000+09:00",
#    "imageScanStatus": {
#        "status": "FAILED",
#        "description": "LayerError: Failed to extract layer for image scan."
#    },
#    "imageManifestMediaType": "application/vnd.oci.image.manifest.v1+json",
#    "artifactMediaType": "application/vnd.amazon.soci.index.v1+json",
#    "lastRecordedPullTime": "2025-02-20T20:29:10.460000+09:00"
# },

ECS

いちばん簡単なのはECSタスクのコマンドをオーバーライドして起動することです。
※このとき用いていたのが軽量のイメージだったためjqを追加したりしています。

bash -c apt-get update \
&& apt-get install -y jq \
&& curl -s $ECS_CONTAINER_METADATA_URI_V4 | jq -r .Snapshotter; curl -s $ECS_CONTAINER_METADATA_URI_V4/task | jq -r .Containers[0].Snapshotter

これでタスクを起動した際にそれぞれ以下のようにログが出力されます。

# SOCIが効いていないタスク
# overlayfs
# overlayfs
# SOCIが効いているタスク
# soci
# soci

既知の不具合

現在一部のAWS環境で正しく設定しているはずなのにECS側の確認するとoverlayfsと表示されECRからのpullに5分以上かかるという事象が社内で確認されています。
こちらはAWSのサポートケースと協力しながら調査を進めています。また進展があって技術的に面白そうなトピックや共有したいTipsがあったら記事化しようと思います。

さいごに

DTダイナミクスのSREチームでは様々な新しいチャレンジを通して#時間戦略#顧客時間価値にコミットしています。
わたしたちミスミ、そしてDTダイナミクスは一緒にmeviyを通して世界の製造業を支える仲間を募集しています!
少しでも興味のある方はぜひカジュアル面談しましょう!

www.wantedly.com