🗑️

Artifact Registry のクリーンアップポリシーでは設定できない条件でイメージを削除する方法

2024/08/26に公開

こんにちは!
GCPでArtifact Registryを長年使っていると、イメージが溜まってきて余分なコストを使ってしまうということがあったので、クリーンアップポリシーを使ってもう使わないイメージを削除してコスト削減しようと思いました。しかしながら、クリーンアップポリシーは単純な条件しか設定できず、最適なコスト削減ができないという問題があります。そこで、自分で削除スクリプトを書くことで、複雑な条件でもイメージを削除できるようにしようという目的で本記事を書きました。
想定読者

  • 業務でArtifact Registryを使っており、不要なイメージが溜まってきたので削除したい方

クリーンアップポリシーで設定できる条件

クリーンアップポリシーでは以下の条件で削除できます。

  • tagのprefix
  • versionのprefix
  • packageのprefix
  • 設定した期間より古いイメージ
  • 設定した期間より新しいイメージ

また、クリーンアップポリシーでは保持ポリシーというものがあり、削除ポリシーと条件が被ったイメージに関しては削除されず保持されます。保持ポリシーの条件は以下です。

  • tagのprefix
  • versionのprefix
  • packageのprefix
  • 設定した期間より古いイメージ
  • 設定した期間より新しいイメージ
  • 最新N件のイメージ

上記の条件でも十分に見えるのですが、この条件のみでは再現できないケースを考えてみます。例えば、「作成日ではなく更新日に着目して、設定した期間より更新日が古いイメージを削除したい」というケースの場合、上記の条件では再現できません。

今回扱う条件と書いたスクリプト

今回は「作成日ではなく更新日に着目して、設定した期間より更新日が古いイメージを削除したい」というケースに着目して削除スクリプトを書きました。以下削除スクリプトです。

import subprocess
import json
from datetime import datetime, timedelta

# 設定
REPOSITORY_NAME = 'your-repository-name'
DAYS_THRESHOLD = 30

# リポジトリ内のイメージを取得
list_images_cmd = f'gcloud artifacts docker images list {REPOSITORY_NAME} --format=json'
images = json.loads(subprocess.check_output(list_images_cmd, shell=True))

# 現在の日時
now = datetime.utcnow()

for image in images:
    image_name = image['package']

    # 最終更新日時を取得
    update_time = image['updateTime']
    last_update_date = datetime.strptime(update_time, '%Y-%m-%dT%H:%M:%S.%fZ')
    
    # 指定された期間よりも前に更新された場合に削除
    if (now - last_update_date) > timedelta(days=DAYS_THRESHOLD):
        # イメージダイジェストを取得
        digest = image['metadata']['name'].partition('@sha256:')[-1]
        
        # イメージの削除
        delete_image_cmd = f'gcloud artifacts docker images delete {image_name}@sha256:{digest} --quiet'
        subprocess.check_output(delete_image_cmd, shell=True)
        print(f'Deleted image: {image_name}@sha256:{digest}')
    else:
        print(f'Image {image_name}@sha256:{digest} is updated within threshold, skipped.')

# 設定の箇所で任意のリポジトリと、最終更新日時を設定してください。このスクリプトを実行することで条件に合うダイジェストを削除することができます。

まとめ

クリーンアップポリシーでは設定できないような条件を設定して削除する方法をまとめました。しかし、クリーンアップポリシーでは継続的に削除されるような仕組みとなっていますが、今回紹介したスクリプトだとスクリプトを実行した1回のみの削除となるため、継続的な削除の仕組みを独自で作る必要がありそうです。

Discussion