繁体   English   中英

如何自动从 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

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

我尝试在云 function 内部使用,但我认为这是不允许的。

  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}`);
  });

运行云 function 时出现此错误:

error: spawn gcloud ENOENT

我接受任何其他解决方案,例如在云构建上触发,terraform,只要它可以存在于谷歌云上。

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

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


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


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

  • 首先,使用 Google Cloud Developer Advocate (Seth Vargo) 已经为您完成的工作。 它被命名为GCR 清洁器并删除比某些东西更旧的图像
  • 或者,您可以通过调用Artifact 注册表 REST API直接使用 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* AND 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=$1
project_id=$2
repository_id=$3
image_name=$4 #In this case I just want to clean the old branchs for same image
older_than_days=$5 #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

##!/usr/bin/env bash

_cleanup() {
  image_path="$2-docker.pkg.dev/$project_id/$1"
  echo "Starting to filter: $image_path"
  images=$(gcloud artifacts docker images list $image_path \
          --filter="UPDATE_TIME.date('%Y-%m-%d', Z)<=$(date --date="-1 years" +'%Y-%m-%d')" \
          --format='value(IMAGE)')
  if [ -z "$images" ]; then
    echo "No images to clean"
  else
    echo "Images found: $images"
    for each in $images; do
      echo "Deleting image: $image_path:$each"
      gcloud artifacts docker images delete "$images" --quiet
    done
  fi
}

project_id=$1
gcloud artifacts repositories list --format="value(REPOSITORY,LOCATION)" --project=$project_id | tee -a repo.txt

while read p; do
    sentence=$p
    stringarray=($sentence)
    _cleanup  ${stringarray[0]}  ${stringarray[1]}
done < repo.txt

echo
echo "DONE"
rm -rf repo.txt
echo "Deleteing repo.txt file"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM