Artifact Registryのイメージを自動削除する「クリーンアップポリシー」を使ってみる
Artifact Registryの クリーンアップポリシーを利用すると、「期間」や「最新バージョン数」などの条件に基づいて、古いイメージを自動削除することができます。従来のGCRですとGCR Cleaner等のツールを自分で実行する必要があったので、これは非常に嬉しい機能です。
ただ、まだ登場したばかりの機能ということもあってか、ポリシーの設定方法や動作確認方法には若干癖があります。本記事では、実際にポリシーを設定する際の手順について簡単にまとめてみます。
なお、本記事ではDockerイメージレジストリとしての利用法を解説します。
ポリシーの適用単位
ポリシーを適用するのはArtifact Registryの「リポジトリ」単位となります。リポジトリ内には複数のパッケージ(Dockerで言うimage repository)を格納することができますが、ポリシーはリポジトリ内のすべてのパッケージに一律で適用されます。
一応、ポリシーの条件のpackageNamePrefixes
を使うことで特定のパッケージのみにポリシーを適用することは可能ですが、そもそもひとつのリポジトリに適用できるポリシーは最大10個までとなっています。このため、ポリシーを適用したいグループごとにリポジトリを分割するのが無難です。
ポリシーの種類
クリーンアップポリシーは、以下の2種類のポリシーを最大10個まで組み合わせて構成します。
「削除」ポリシー
本機能の基本となるポリシーで、自動削除を行う対象とするイメージの条件を指定します。使用できる条件は以下のとおりです。
- イメージにタグが付いているかどうか(tagState)
- タグのプレフィックス(tagPrefixes)
- パッケージ名のプレフィックス(packageNamePrefixes)
- 一定期間を経過したイメージ(olderThan)
- 一定期間内に作成されたイメージ(newerThan)
「保持」ポリシー
「保持」ポリシーは、上記の「削除」ポリシーで削除対象となったイメージのうち一部を保護する目的で使用します。したがって、保持ポリシーのみを設定しても効果がありませんので注意してください。
保持ポリシーに設定できる条件は基本的に「削除」ポリシーと同一ですが、それに加えて最新nバージョンの保持(mostRecentVersions)を設定することができます。なお、「最新nバージョン」のカウントはパッケージごとに行われます。
ポリシーの記述
例として、以下のようなポリシーを考えます。
- タグなしイメージは常に削除
- タグ付きイメージは過去10バージョンのみ保持
- ただし、過去30日以内に作成されたイメージは10バージョンを超えても削除しない
ポリシーはJSON形式で記述し、ファイルに保存する必要があります。ここではexamplePolicy.json
という名前のファイルに保存します。
[
{
"name": "clean-untagged",
"action": {"type": "Delete"},
"condition": {
"tagState": "untagged"
}
},
{
"name": "clean-tagged-older-than-30-days",
"action": {"type": "Delete"},
"condition": {
"tagState": "tagged",
"olderThan": "30d"
}
},
{
"name": "keep-last-10",
"action": {"type": "Keep"},
"mostRecentVersions": {
"keepCount": 10
}
}
]
注意する必要があるのが、バージョン数による条件の制御は保持ポリシーにしか使用することができないという点です。このため、今回は「期間」を削除ポリシーの条件に、「バージョン数」を保持ポリシーの条件に使用しています。
より詳しい条件の書き方に関しては、公式ドキュメントを参照してください。
dry-runによる動作確認
これでポリシーは完成しましたが、いきなりこれを使ってイメージを削除するのは若干不安があります。dry-runモードを使うことで、実際にイメージを削除することなくポリシーをテストできます。
監査ログの有効化
dry-runモードの動作結果を確認するには、事前に監査ログを有効化する必要があります。クリーンアップポリシーはBatchDeleteVersions
APIを呼び出すので、「データ書き込み」ログを有効化します。
dry-runの実行
先程作成したポリシーファイルをdry-runモードで適用します。
gcloud artifacts repositories set-cleanup-policies [リポジトリ名] \
--project=[プロジェクトID] \
--location=[リージョンまたはマルチージョンロケーション] \
--policy=examplePolicy.json \
--dry-run
実行すると、実際に解釈されたポリシーが出力されます。
Updated repository [xxxxxxxx].
Dry run is enabled.
[
{
"action": {
"type": "DELETE"
},
"condition": {
"olderThan": "2592000s",
"tagState": "TAGGED"
},
"name": "clean-tagged-older-than-30-days"
},
{
"action": {
"type": "DELETE"
},
"condition": {
"tagState": "UNTAGGED"
},
"name": "clean-untagged"
},
{
"action": {
"type": "KEEP"
},
"mostRecentVersions": {
"keepCount": 10
},
"name": "keep-last-10"
}
]
デフォルト値が暗黙的に挿入された場合でもここで確認できます。
これで削除ポリシーを仮適用することができたのですが、紛らわしいのがdry-runのポリシーを適用してもすぐに削除(のシミュレーション)が実行されるわけではないという点です。ポリシーに基づく削除は数時間に1回程度の頻度で実行されているものと思われ、dry-runモードであっても削除が試行されるのは同程度の頻度となります[1]。このため、ポリシーを適用してから実際にBatchDeleteVersions
の監査ログが出るまではしばらく時間がかかります。(自分は最初この挙動を認識できておらず、監査ログが全く現れなくて焦りました)
監査ログの確認
しばらく時間を置くと、クリーンアップポリシーによるバッチ削除のログが出現します。
Cloud Loggingで以下のクエリで検索すると引っ掛けることができます。
protoPayload.serviceName="artifactregistry.googleapis.com"
protoPayload.methodName="google.devtools.artifactregistry.v1.ArtifactRegistry.BatchDeleteVersions"
protoPayload.request.@type="type.googleapis.com/google.devtools.artifactregistry.v1.BatchDeleteVersionsRequest"
削除されたイメージがあれば、以下のようなログエントリが引っかかります。
names
に削除されたイメージのパスとsha256ハッシュが格納されています。なお、タグ付きイメージの場合でもイメージタグは含まれないようなのでご注意ください。また、dry-runで実行している場合、実際にはイメージを削除していないことを示すためにvalidateOnly: true
というフラグが付与されています。
特定のイメージが削除されたかどうかを確認するには、上記のクエリに以下の条件を加えます。
protoPayload.request.names:"sha256:xxxxxxx"
no-dry-runによる適用
イメージが正しく削除できていることを確認したら、no-dry-runモードに切り替えてイメージが削除されるようにします。
gcloud artifacts repositories set-cleanup-policies [リポジトリ名] \
--project=[プロジェクトID] \
--location=[リージョンまたはマルチージョンロケーション] \
--policy=examplePolicy.json \
--no-dry-run
まとめ
以上、クリーンアップポリシーを用いてイメージを自動削除する方法を見てきました。
dry-runの実行方法などに若干難はありますが、非常に便利な機能ですのでぜひ活用していきたいところです。
-
1日1回しかテストできないのは流石にキツい・・・ので、Googleさん何とかお願いします🙏 ↩︎
Discussion