Clean up Azure Container Registry

起因

打开项目上用了2-3年的Azure Container Registry,就像打开了一个尘封多年的仓库一般。使用者不停的往仓库里堆放物品,但从来不整理、打扫。仓库的容积足够大,不考虑成本的话,都不是问题。但本着“清道夫”的理念,本着清楚潜在问题的出发点(其实是不想后面打开仓库的人也口出“狂言”,而来责怪前面维护的人。)

方法

在个人电脑上,下载镜像过多且长期不删除也会面临磁盘不足的风险。或多或少都适用过类似 docker image rm的命令,但一个一个的清理难免麻烦耗时。这时候就需要一个一键搞定的命令,例如docker system prune

对于Azure Container Registry 这样一个成熟的产品服务,已经不建议个人去造轮子、写脚本了。搜索一番之后找到了一篇不错的文章,里面提到了两个具体的方法。

  • 1.Set a retention policy for untagged manifests (Microsoft Docs)
  • 2.Automatically purge images from an Azure Container Registry (Microsoft Docs)

具体的使用当然还是参照azure官方的文档为宜,毕竟具体实践因情况而异。

对于,需要注意一点,该policy并不能立刻对现有的镜像生效,原文描述如下:

! Important

The retention policy applies only to untagged manifests with timestamps after the policy is enabled. Untagged manifests in the registry with earlier timestamps aren’t subject to the policy. For other options to delete image data, see examples in Delete container images in Azure Container Registry.

运行了一些命令:

1
2
3
4
# 删除2021-04-01 之前的镜像, 有dry-run参数也可以提前测试一下
az acr repository show-manifests --name <YourACRName> --repository demo-web-app \
--orderby time_asc --query "[?timestamp < '2021-04-01'].digest" -o tsv \
| xargs -I% az acr repository delete --name <YourACRName> --image demo-web-app@% --yes
1
2
3
4
5
6
7
8
# 设置定时任务,以后就会自动按照时间来删除
PURGE_CMD="acr purge --filter 'service-one:.*' --ago 180d"

az acr task create --name purgeAppOneImage \
--cmd "$PURGE_CMD" \
--schedule "0 0 * * 2" \
--registry <YourACRName> \
--context /dev/null

意外收获

tag or digest

  • The “digest” is a hash of the manifest, introduced in Docker registry v2.
  • The image ID is a hash of the local image JSON configuration.

在使用 Dockerfile 构建镜像时,base image的使用也涉及这点。提出了一个解决方案 docker-lock ,有兴趣的可以使用看看,欢迎交流心得体会~

Link: https://developers.redhat.com/blog/2020/03/24/red-hat-universal-base-images-for-docker-users#

As you discovered, with docker, tags are mutable. This means that an update to a base image could be pushed that breaks your application code, even if you did not change any of your application code.

You could eliminate this class of bugs by referencing base images by digest rather than by tag. For instance, instead of ruby:2.6.3, use ruby:2.6.3@sha256:2afcffd1a8276d58ef7d2c6d440c83290831abc2d80772a7af720db9aca9cd2e. If you reference by digest, when a new update is pushed to ruby:2.6.3, your application will still use the base image referenced by the digest, and you won’t be affected by the update.

Specifying digests manually is a pain for a variety of reasons. Instead, consider using docker-lock https://github.com/michaelp.... docker-lock is a cli-plugin for docker that manages digests in a lockfile (think package-lock.json), so you can still reference base images by tag but receive the benefits of referencing them by digest.

docker-lock ships with 3 commands that take you from development to production:
docker lock generate finds base images in your docker and docker-compose files and generates a lockfile containing digests that correspond to their tags.
docker lock verify lets you know if there are more recent digests than those last recorded in the lockfile.
docker lock rewrite rewrites Dockerfiles and docker-compose files to include digests.

using-container-image-digests-in-kubernetes-manifests

https://cloud.google.com/architecture/using-container-image-digests-in-kubernetes-manifests)

Tag Count =? Mainfest Count

详解可见文章


Reference:

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2019-2024 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~