如何自动从 Artifact Registry 中删除图像

How to remove an image from Artifact Registry automatically

使用 gcloud 我可以通过这些命令列出和删除我想要的图像:

gcloud artifacts docker images list LOCATION/PROJECT-ID/RESPOSITORY-ID/IMAGE \
  --include-tags --filter="tags:IPLA*" --filter="create_time>2022-04-20T00:00:00"

然后

gcloud artifacts docker images delete LOCATION/PROJECT-ID/RESPOSITORY-ID/IMAGE:tag

我正在尝试将其自动化,以便我可以每天或每周按标签名称和日期以及 运行 进行过滤。

我试过在云函数内部使用,但我认为这是不允许的。

  const { spawn } = require("child_process");
  const listening = spawn('gcloud', ['artifacts', 'docker', 'images', 'list', 
     'LOCATION/PROJECT-ID/RESPOSITORY-ID/IMAGE',
     '--include-tags', 
     '--filter="tags:IPLA*"', 
     '--filter="create_time>2022-04-20T00:00:00"'
  ]);

  listening.stdout.on("data", data => {
      console.log(`stdout: ${data}`);
  });

  listening.stderr.on("data", data => {
      console.log(`stderr: ${data}`);
  });

  listening.on('error', (error) => {
      console.log(`error: ${error.message}`);
  });

我在 运行 启用云功能时遇到此错误:

error: spawn gcloud ENOENT

我接受任何其他解决方案,例如云构建触发器、terraform,只要它可以在 google 云上运行即可。

您使用 Cloud Functions,这是一种无服务器产品,您可以将代码 运行 部署在您不管理的某处。

在这里,在您的代码中,您假设 gcloud 安装在 运行 时间。这是一个错误,你不能执行那个假设(那是错误的!)


但是,您可以使用另一个无服务器产品来管理您的 运行 时间环境:云 运行。原则是创建您的容器(并因此在其中安装您想要的东西)然后部署它。那个时候你可以使用 gcloud 命令,因为你知道它存在于 VM 上。


但是,这不是正确的选择。你有 2 个更好的东西

  • 首先,使用 Google Cloud Developer Advocate (Seth Vargo) 已经为您完成的工作。它被命名为 GCR cleaner 并删除早于某物
  • 的图像
  • 或者您可以直接使用 API 通过调用 Artifact registry REST API 来执行与没有 gcloud 的 GCLOUD bur 完全相同的操作。如果你想作弊并走得更快,你可以使用带有 --log-http 参数的 gcloud 命令来显示 CLI 执行的所有 API 调用。复制 URL 和参数,享受吧!!

最初我开始研究 Guillaume 建议的解决方案,尽管部署整个图像只是为了清理 Artifact Registry 看起来太过分了。最终找到了一种更轻松的方法。

我创建了一个 shell 脚本文件来使用我想要的滤镜清理图像:

#!/usr/bin/env bash

_cleanup() {
  image_path="$location-docker.pkg.dev/$project_id/$repository_id/$image_name"
  echo "Starting to filter: $image_path"
  tags=$(gcloud artifacts docker images list $image_path \
    --include-tags \
    --filter="tags:IPLA*" \
    --filter="UPDATE_TIME.date('%Y-%m-%d', Z)<=$(date --date="-$older_than_days days" +'%Y-%m-%d')" \
    --format='value(TAGS)')
  if [ -z "$tags" ]; then
    echo "No images to clean"
  else
    echo "Images found: $tags"
    for tag in $tags; do
      echo "Deleting image: $image_path:$tag"
      gcloud artifacts docker images delete "$image_path:$tag" --quiet
    done
  fi
}
location=
project_id=
repository_id=
image_name= #In this case I just want to clean the old branchs for same image
older_than_days= #7 - Number of days in the repository
_cleanup

echo
echo "DONE"

然后我在 Cloud Build 上为以下 cloudbuild.yaml 文件创建了一个预定触发器:

steps:

  - name: 'gcr.io/cloud-builders/gcloud'
    id: Clean up older versions
    entrypoint: 'bash'
    args: [ 'cleanup-old-images.sh', '$_LOCATION', '$PROJECT_ID','$_REPOSITORY_ID', '$_IMAGE_NAME', '$_OLDER_THAN_DAYS' ]

timeout: 1200s