ECRのライフサイクルポリシー
- 古いイメージがたまると、ストレージ料金が余計にかかる
- ECRリポジトリ1つにつき、イメージは1000まで
こういった問題に対して、ライフサイクルポリシーを適切に設定することで、自動で古いイメージを削除することができます。
Amazon ECRのライフサイクルポリシーでコンテナイメージのクリーンアップ
タグ付けルールとライフサイクルポリシー
実際のプロジェクトで、ライフサイクルポリシーがうまく機能するように、どのようにタグ付けのルールを工夫したか紹介します。
これは、私が携わっているプロジェクトの運用に応じたものなので、あくまで参考です。
前提
タグ付け以前に、次のような前提がありました。
- Github への Push をトリガーに CI が実行され、 docker image のビルドと Push が行われる
- 開発者は、任意の git branch (からビルドされたimage) を ECS にデプロイしたい
どのようにタグ付けするか
また、次のような事情があります。
- 現在、ECS Service にデプロイされている image が消えてしまうと困る
- Task が作り直された際に image が見つからなくて実行できない
- 開発者がデプロイしたいのは、ほとんどの場合、git branch の head に対応する image
- branch の head より古い image は長く保持しておく必要がない
- しばらく commit がない branch についても、ほとんどデプロイされることはない
そこで、次の3パターンのタグをつけることにしました。
git-hash.*
git-branch.*
deploy.*
それぞれのタグについて、説明します。
CI で docker image をビルドしたら、そのときの git の hash に従って、 git-hash.*
のタグを付けます。(例えば、 git-hash.8db0a1
のようになります)
また、それと同時に、branch 名に従って git-branch.*
のタグを付けます。
ただし、git の branch には、スラッシュ/
など、 docker のタグとして使用できない記号が含まれる場合があります。なので、branch 名を SHA などで適当にハッシュ化してその先頭の数文字をとります。 (例えば、 git-branch.7e5170
のようになります)
deploy.*
タグは、実際にデプロイされたときに、後からつけます。デプロイ先の環境名をふくめて、例えば deploy.production
のようにします。
ライフサイクルポリシーの設定
それぞれのタグに、次のように expire を設定します。
-
deploy.*
=> 十分に長い期間(半永久的) -
git-branch.*
=> 数週間・数ヶ月程度 -
git-hash.*
=> 数日程度
上に記載したタグほど、優先度を高く します。
そうすることで、deploy.*
がついたイメージは消えず、 git-hash.*
だけついた image はすぐに消えるようになります。
設定例
具体的な設定例を残しておきます。
{
"rules": [
{
"rulePriority": 10,
"description": "Keep images with the tag deploy.* forever",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": [
"deploy."
],
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 36500
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 20,
"description": "Keep images with the tag git-branch.* for 14 days",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": [
"git-branch."
],
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 14
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 30,
"description": "Keep images with the tag git-hash.* for 3 days",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": [
"git-hash."
],
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 3
},
"action": {
"type": "expire"
}
}
]
}
aws ecr put-lifecycle-policy --repository-name $repo --lifecycle-policy-text "$(cat policy.json)"