Elastic Container Registryにライフサイクルポリシーを導入し75%のコスト削減してみました

はじめに

こんにちは、21新卒のがんがんこと岩丸です。

皆様、春の風はいかがお過ごしでしょうか。私は遂に花粉症を発症し、例に漏れず花粉症と日々闘っております。暖かい春は待ち遠しくもあり、花粉症民からすると防御の構えが続くそんな季節ですね。

5月に入ってからは花粉対策と合わせて暑さ対策も急務ですね。体調変化が日々忙しい限りです。


エンジニア界隈はChatGPTで盛り上がっていますが、1つ前の話題として「円安」があったかと思います。2023年に入って以降は130円/ドル台が続いており、引き続き円安のことを意識する必要があります。

この話はAWSのAmazon Elastic Container Registry (ECR)、GCPのArtifact Registryにも同様のことが言えます。ECRの料金はRDS・EC2に比べると高くないですが円安が継続する昨今においては気にしておきたいコストです。


そこで今回はECRのライフサイクルポリシーを調査した際の備忘録と考えられるバッドパターン(障害を招くこともある)の紹介をしたいと思います。

やりたかったこと

EKSで利用するイメージは全てECRに格納されており、このECRイメージはテストフェーズに入るとちょっとずつ増えていく形になっています。また、開発環境で実験を行う際のイメージもECRイメージを利用しており、気づいたら増えている形になります。

例えば、あるリポジトリには約1300コのイメージが保持されていました。ただ、実際に使っているのは4〜5コです。過去ログ用のイメージを残しておくとしても最大10コくらいでいいのかなと思います(もっと少なくていい)。


イメージが増えていく原因として不要になったイメージを削除するという機構がないことが挙げられます。今回はこの削除する機構としてECRのライフサイクルポリシーを採用してみました。

今回導入したポリシールールと適応した結果

今回導入したポリシールール

今回は以下のようなルールを設定しました。

  • workがつくイメージの経過日数が14日を超えていた場合は削除する

AWSコンソールからECRライフサイクルポリシーを設定する

設定手順のキャプチャは今回割愛しています。以下の記事に画面キャプチャを用いた導入手順がありますのでそちらを参照ください。

適応した結果

ライフサイクルポリシーを適応した結果、75%のコスト削減に成功しました。 EC2やRDSに比べると削減量は目に見えて多くありませんが、無駄なコストを確実に削減することができました。

Terraformでの実装例

今回はAWSコンソールより設定を行いましたが、Terrafromを用いている環境であればTerrafromで設定した方が楽です。 Terrafromの公式ドキュメントを参考にしました。JSONはAWSコンソールで出力したものです。

公式ドキュメントを見る限りtagPrefixListlist[string]型となっていました。そのため、正規表現でゴニョゴニョやるのは厳しそうでした。

ecr_repository_policy = {
    policy = jsonencode({
      "rules": [
          {
            "action": {
              "type": "expire"
            },
            "selection": {
              "countType": "sinceImagePushed",
              "countUnit": "days",
              "countNumber": 14,
              "tagStatus": "tagged",
              "tagPrefixList": [
                "work"
              ]
            },
            "description": "workイメージを14日後に自動削除する",
            "rulePriority": 1
          }
      ]
    })
  }

気をつけておきたいECRライフサイクルポリシールール例

ECRのイメージを自動で整理してくれるライフサイクルポリシーですが、時としてこの設定が時限爆弾になることもあります。 このライフサイクルポリシーを設定をした人がチームにいない場合、障害発生の原因がイメージ自動削除によるものと切り分け・特定するのは容易ではないでしょう。

そこで気をつけておきたい例を何点か記載します。明日は我が身ですね。

保持するイメージ数をN個に設定する

例えば以下のような設定です。

ECR保持イメージを計30コとする

公式でもexampleが記載されている設定ケースです。一見おかしいところはない設定に感じますが以下だとどうでしょうか。

ECR保持イメージを最新ものから計30コとする。31コ目以上のものは使用の可否に関わらず削除する


お気づきの方もいると思いますがNコ目以上のものは使用の可否に関わらず削除するという部分が重要です。これは本番環境で利用しているイメージが気づいたら削除されるかもしれないということです。

例えば、テストフェーズで開発環境用のイメージをどんどんデプロイしたとします。デプロイを繰り返した結果、ステージング環境で利用しているイメージがNコ以内に含まれなくなりました。その結果、次のライフサイクル時にステージング環境で利用しているイメージが削除され、ステージング環境で障害が発生します。

対象のステージング環境を複数の部署が利用している場合、各部署から障害報告アラートが飛んでくることでしょう。もし本番環境で同様の事象が発生したと考えると、正直考えたくないですね。


シンプルな設定であるが故に注意しておきたい設定方法です。

保持するイメージの経過日数をN日に設定する

こちらもシンプルな設定であるが故に注意しておきたい設定方法です。

本設定の場合、しばらく更新しないが稼働し続ける必要があるみたいなケースで時限爆弾となり得ます。チームの開発ライフサイクルに合わせて注意する必要があります。

ライフサイクルポリシールールによる障害発生を防ぐには?

2023.05現在のライフサイクルポリシーの設定では特定のイメージをロックしてライフサイクル対象から外す設定やコンテナの利用可否を判断する仕組みがありません。 そのため、利用者側できちんとルールを設定し運用するしかありません。例えば、以下のようなものが挙げられるかと思います。

  • 開発環境/本番環境ごとにECR環境を用意する
  • 本番リリース用イメージにはライフサイクルルールに該当しないprefixを付ける

運用改善のために設定したルールが起因して障害が発生すると非常に悲しいですよね。 そのため、コンテナのタグ命名ルール・運用ルールはチーム内できちんと議論・検討していきましょう。

参考

おわりに

今回はAmazon Elastic Container Registry(ECR)のコスト削減事例について紹介しました。不要なリソース・コストはどんどん削減し、より投資できるところに回していきたいお気持ちです。私が日々実施している効率化・自動化も同様のマインドで行っています。


OPTiMでは運用改善やDevOpsに興味があるエンジニア、新卒からどんどんチャレンジしていきたいエンジニア学生を随時募集しております。少しでもご興味のある方はこちらも合わせてご覧ください。

www.optim.co.jp