🌟

ECRのライフサイクルポリシー適用でコスト最適化を実現

に公開

研究開発において、インフラ周りの処理を IaC で管理しようということで、AWS CDK (AWS Cloud Development Kit) を活用しています。
https://aws.amazon.com/jp/cdk/

PyTorch などの巨大ライブラリを Lambda で利用しようとした場合、サイズの問題からコンテナイメージを使うことになると思います。この際、ECR (Elastic Container Registry) を活用にすることになりますが、意外なところにデータが溜まっていたために無駄なコストがかかってしまっていました。今回はそのような「ゴミデータ問題」に直面した話と、その解決策を共有します。

問題は突然に

ある日、弊社テックリードから「ECR のストレージコストが高い」と指摘されました。
日頃から CDK において各 ECR リポジトリに対してはライフサイクルポリシーを設定しておりますので、やや寝耳に水でした。実際いくつかのリポジトリを確認して、必要最小限のイメージしか保持されていないことを確認しましたが、コスト通知の Slack Bot が嘘を言っているわけもないので調査をしました。

参考までに、CDK で記述しているあるリポジトリ設定のサンプルを掲載しておきます。

const prefixName = projectKey + '-' + envcode;
...

this.someapi_ecrRepo = new ecr.Repository(this, 'someapi_ecrRepo', {
  repositoryName: `${prefixName}-someapi`,
  imageScanOnPush: true,
  removalPolicy: RemovalPolicy.DESTROY
});
this.someapi_ecrRepo.addLifecycleRule({
  tagPrefixList: [prefixName],
  maxImageCount: 1,
});
this.someapi_ecrRepo.addLifecycleRule({
  tagStatus: ecr.TagStatus.UNTAGGED,
  maxImageAge: Duration.days(1)
});

この設定のおかげで、通常のリポジトリでは問題が発生しないはずです。

ところが…。

まさかのゴミデータ

普段触らないリポジトリを確認すると、そこには 700 個以上のイメージが溜まっていました。

このリポジトリの正体は、cdk-hnb659fds-container-assets-ACCOUNT-REGION という、AWS CDKが自動生成するステージングリポジトリでした[1]

弊社では AI 活用も推進しておりますので、GitHub Copilot 等が利用できます。今回、Copilotに助けを求めてみました。

Copilotに訊いてみた

Copilotからの回答によると以下とのことでした。

  1. このリポジトリの役割
    AWS CDKが、デプロイ時に必要なコンテナアセットを管理するために自動生成。

  2. なぜ勝手に作成されるのか?
    デプロイ時のバックエンドプロセスとして必要。

  3. 削除しても良いのか?
    削除は非推奨。ただし、ライフサイクルポリシーを適用することでデータを整理可能。

確かに言われてみるとそうだなと思いますが、盲点でした。CDK がうまいことやってくれるだろうと思い込んでいたのです。

解決策: ライフサイクルポリシーを適用

通常の ECR リポジトリと同じように、cdk-hnb659fds-container-assets-ACCOUNT-REGION にもライフサイクルポリシーを設定できることが分かりました。

そこで、以下のような設定を ECR リポジトリのライフサイクルポリシーに追加しました。

{
  "rules": [
    ...,
    {
      "rulePriority": 2,
      "description": "Keep only the last 20 images",
      "selection": {
        "tagStatus": "any",
        "countType": "imageCountMoreThan",
        "countNumber": 20
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

内容としては最新 20 個のイメージを保持するというものです。利用頻度やデプロイ状況に応じて、この値は調整可能でして、実際にはもっと少ない値でも大丈夫だろうとは思います。

設定後、AWS の非同期プロセスにより、数時間から数日かけてライフサイクルポリシーが適用されます。今回の場合には運良くその日のうちに実行され、cdk-hnb659fds-container-assets-ACCOUNT-REGION のイメージ数は最新 20 個だけとなりました。

まとめ

今回の経験から得た教訓は以下です。

  1. 定期的な ECR リポジトリの監視やメンテナンスが重要

    • AWS Cost Explorer や CloudWatch アラームを活用して、ストレージ利用量や費用を定期チェック。
  2. 自動生成リポジトリにも注意を払う

    • 特に AWS CDK を使っている場合、デプロイ時に生成されるリポジトリの挙動を把握しておくことが重要。
  3. 問題が発生したら対策を実施し、効果を確認する

    • ライフサイクルポリシーを適用後、ストレージ利用量に変化があったかモニタリングする。

私自身が AWS CloudFormation に詳しくないという理由でツール、つまり CDK に頼りっぱなしだったため、ツールが裏で行った処理について幾分無頓着でした。ストレージ系は知らず知らずにコストが嵩むことがあります。見落としがないかいまいちど ECR のリポジトリや S3 のバケットの状況を見直してみるのも良いと思います。普段意識していないところで、意外な問題が見つかるかもしれません。

また、今回私は GitHub Copilot を活用して解決策に至りましたが、生成 AI もまた完璧ではないツールです。ツールが生成した内容についても、絶対的に過信するのではなく、疑問に思うことがあれば調べたり実験を行なって検証することをお勧めいたします。

脚注
  1. ステージングバケットやステージングリポジトリについては、例えば CDK スタック合成をカスタマイズする を参照願います。 ↩︎

モリサワ Tech Blog

Discussion