GCR Cleaner deletes untagged images in Google Container Registry. This can help reduce costs and keep your container images list in order.
GCR Cleaner is designed to be deployed as a Cloud Run service and invoked periodically via Cloud Scheduler via Cloud Pub/Sub.
+-------------------+ +-------------+ +-------+
| Cloud Scheduler | -> | Cloud Run | -> | GCR |
+-------------------+ +-------------+ +-------+
GCR Cleaner is largely inspired by ahmetb's gcrgc.sh, but it is written in Go and is designed to be run as a service.
-
Install the Cloud SDK for your operating system. Alternatively, you can run these commands from Cloud Shell, which has the SDK and other popular tools pre-installed.
-
Export your project ID as an environment variable. The rest of this setup assumes this environment variable is set.
export PROJECT_ID=my-project
Note this is your project ID, not the project number or name.
-
Enable the Google APIs - this only needs to be done once per project:
gcloud services enable --project "${PROJECT_ID}" \ appengine.googleapis.com \ cloudscheduler.googleapis.com \ run.googleapis.com
This operation can take a few minutes, especially for recently-created projects.
-
Create a service account which will be assigned to the Cloud Run service:
gcloud iam service-accounts create gcr-cleaner \ --project "${PROJECT_ID}" \ --display-name "gcr-cleaner"
-
Deploy the
gcr-cleaner
container on Cloud Run running as the service account just created:gcloud alpha run deploy gcr-cleaner \ --project ${PROJECT_ID} \ --platform "managed" \ --service-account "gcr-cleaner@${PROJECT_ID}.iam.gserviceaccount.com" \ --image "gcr.io/gcr-cleaner/gcr-cleaner" \ --region "us-central1" \ --timeout "60s" \ --quiet
-
Grant the service account access to delete references in Google Container Registry:
gsutil acl ch -u gcr-cleaner@${PROJECT_ID}.iam.gserviceaccount.com:W gs://artifacts.${PROJECT_ID}.appspot.com
To cleanup refs in other GCP projects, replace
PROJECT_ID
with the target project ID. For example, if the Cloud Run service was running in "project-a" and you wanted to grant it permission to cleanup refs in "gcr.io/project-b/image", you would need to grant the Cloud Run service account in project-a permission onartifacts.projects-b.appspot.com
. -
Create a service account with permission to invoke the Cloud Run service:
gcloud iam service-accounts create gcr-cleaner-invoker \ --project "${PROJECT_ID}" \ --display-name "gcr-cleaner-invoker"
gcloud beta 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"
-
Create a Cloud Scheduler HTTP job to invoke the function every day:
gcloud app create \ --project "${PROJECT_ID}" \ --region "us-central" \ --quiet
# Replace this with the full name of the repository for which you # want to cleanup old references. export REPO="gcr.io/my-project/my-image"
# Capture the URL of the Cloud Run service: export SERVICE_URL=$(gcloud beta run services describe gcr-cleaner --project "${PROJECT_ID}" --platform "managed" --region "us-central1" --format 'value(status.url)')
gcloud beta scheduler jobs create http gcrclean-myimage \ --project ${PROJECT_ID} \ --description "Cleanup ${REPO}" \ --uri "${SERVICE_URL}/http" \ --message-body "{\"repo\":\"${REPO}\"}" \ --oidc-service-account-email "gcr-cleaner-invoker@${PROJECT_ID}.iam.gserviceaccount.com" \ --schedule "every monday 09:00"
You can create multiple Cloud Scheduler instances against the same Cloud Run service with different payloads to clean multiple GCR repositories.
-
(Optional) Run the scheduled job now:
gcloud beta scheduler jobs run gcrclean-myimage \ --project ${PROJECT_ID}
Note: for initial job deployments, you must wait a few minutes before invoking.
The payload is expected to be JSON with the following fields:
-
repo
- Full name of the repository to clean, in the formatgcr.io/project/repo
. This field is required. -
grace
- Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted).
How do I clean up multiple Google Container Registry repos at once?
To clean multiple repos, create a Cloud Scheduler job for each repo, altering
the payload to use the correct repo.
Does it work with Cloud Pub/Sub?
Yes! Just change the endpoint from /http
to /pubsub
!
This library is licensed under Apache 2.0. Full license text is available in LICENSE.