前回の続き。Cloud Build+Cloud Runで作られた不要なイメージを削除してくれる
gcr-cleanerを試してみたときの備忘録。
とりあえず、gcloudをアップデート。
$ gcloud components update
設定の流れ
READMEに書いてある流れ。
- Google APIの有効化(GAE/Cloud Scheduler/Cloud Run)
- gcr-cleaner用のサービスアカウントの作成
- gcr-cleaner用のコンテナサービスをCloud Runにデプロイ
- サービスアカウントにCloud Storageの削除権限を付与
- デプロイしたCloud Runサービスを呼び出すサービスアカウントを作成
- Cloud SchedulerでHTTPジョブを作成
全体像としてはこんな感じで、
サービスアカウント2つと
Cloud Runのサービスが1つと
Schedulerのジョブを1つ作成する
Google APIの有効化
まずは利用するAPIたちを有効化する。
すでに有効化済みの場合は、スキップでOK
gcloud services enable --project "${PROJECT_ID}" \ appengine.googleapis.com \ cloudscheduler.googleapis.com \ run.googleapis.com
gcr-cleaner用のサービスアカウントの作成
gcr-cleaner内で利用するサービスアカウントを作成
gcloud iam service-accounts create "gcr-cleaner" \ --project "${PROJECT_ID}" \ --display-name "gcr-cleaner"
gcr-cleaner用のコンテナサービスをCloud Runにデプロイ
用意されているgcr-cleanerのサービスをデプロイ。
サービス名や--region
や--timeout
は適宜変更する。
gcloud --quiet run deploy "gcr-cleaner" \ --async \ --project ${PROJECT_ID} \ --platform "managed" \ --service-account "gcr-cleaner@${PROJECT_ID}.iam.gserviceaccount.com" \ --image "us-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner" \ --region "us-central1" \ --timeout "60s"
サービスアカウントにCloud Storageの削除権限を付与
デプロイしたCloud Runサービス内で、Cloud Storageの削除をするので、
サービスアカウントで書き込み権限を追加する。
gsutil acl ch -u gcr-cleaner@${PROJECT_ID}.iam.gserviceaccount.com:W \ gs://asia.artifacts.${PROJECT_ID}.appspot.com
recursiveオプションを使う場合は、参照権限も必要。
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member "serviceAccount:gcr-cleaner@${PROJECT_ID}.iam.gserviceaccount.com" \ --role "roles/browser"
デプロイしたCloud Runサービスを呼び出すサービスアカウントを作成
まずはサービスアカウントを作成。
gcloud iam service-accounts create "gcr-cleaner-invoker" \ --project "${PROJECT_ID}" \ --display-name "gcr-cleaner-invoker"
次に、デプロイしたCloud Runサービスの「Cloud Run起動元」権限を付与。
gcloud run services add-iam-policy-binding "gcr-cleaner" \ --project "${PROJECT_ID}" \ --platform "managed" \ --region "us-central1" \ --member "serviceAccount:gcr-cleaner-invoker@${PROJECT_ID}.iam.gserviceaccount.com" \ --role "roles/run.invoker"
Cloud SchedulerでHTTPジョブを作成
まずはGAEを作成。Firebaseを利用している場合はスキップでOK。
gcloud app create \ --project "${PROJECT_ID}" \ --region "us-central" \ --quiet
次に、Cloud Schedulerを作成する。
--schedule
や--time-zone
は好きなように変更。
以下は、日本時間の毎週土曜の0時0分に実行する例
# 対象リポジトリのパス export REPO="asia.gcr.io/${PROJECT_ID}/gcf" # デプロイしたCloud RunのURLを取得: export SERVICE_URL=$(gcloud run services describe gcr-cleaner --project "${PROJECT_ID}" --platform "managed" --region "us-central1" --format 'value(status.url)') # Cloud Schedulerを作成 gcloud scheduler jobs create http "gcrclean-myimage" \ --project ${PROJECT_ID} \ --description "Cleanup ${REPO}" \ --uri "${SERVICE_URL}/http" \ --message-body "{\"repos\":[\"${REPO}\"]}" \ --oidc-service-account-email "gcr-cleaner-invoker@${PROJECT_ID}.iam.gserviceaccount.com" \ --schedule "0 0 * * 6" \ --time-zone="Asia/Tokyo"
--message-body
や--schedule
などは、
GCPコンソールからでも操作できるので、
変更などはそっちからのほうが便利。
あとはジョブを実行してみて、うまく削除されてたらOK(*´ω`*)
注意点
gcr-cleanerの仕組みとして、タグがないイメージを削除する形なので、
すでにタグをなにかつけていると削除されない。
その場合は、あらかじめタグを削除しておくか、
tag_filter_any
などで削除対象を指定しておく必要がある。
合わせて、keep
オプションで、残しておく数を指定することもできる。
具体的な処理は、pkg/gcrcleaner/cleaner.go
のshouldDelete ()
あたり。
流れとしては、以下の感じ。
- 更新時間が所定の時間以下の場合は、false
- タグがない場合は、true
- tagFilterにマッチした場合は、true
- それ以外は、false
tag_filter_any
などが未設定の場合は、
tagFilterにTagFilterNull
が渡されるが、常にfalseを返すよう。
今までは、$COMMIT_SHA
をタグにしてたけど、
least
を利用するように変更した。。
- name: docker id: Push args: - push - - "$_GCR_HOSTNAME/$PROJECT_ID/$_SERVICE_NAME:$COMMIT_SHA" + - "$_GCR_HOSTNAME/$PROJECT_ID/$_SERVICE_NAME:latest"
以上!! これで毎週勝手に削除してくれるように(*´ω`*)