这个方法肯定不是最好的,但我目前还没有找到过更好的,在此抛砖引玉。
首先在开工前,你得把 Registry 的目录挂进去。也就是这个仓库容器在 run 的伊始,必须要 [ -v /transfer/registry:/var/lib/registry ],挂载目录你可以随便定义,我定义的是 [ /transfer/registry ]
耳熟能详的 [ registry garbage-collect /etc/docker/registry/config.yml ] 命令,实际上流程是:先检查 [ /repositories/${项目名}/_manifests/revisions/sha256 ] 有哪些 sha256,然后跟 Blobs 中的 sha256 进行匹配,如果两者有差异,那么删除 blobs 中多余的部分。
也就是说使用垃圾回收命令的核心在于必须先在对应项目的 [ _manifests/revisions ] 中删除对应的 sha256。
要知道每一个 Layer 在仓库中都是以 sha256 的形式被标记,每一个 tags 文件夹中都存在一个 link 文件,里面记录这个 tags (俗称版本) 对应的 sha256。那么按照随手能 Google 到的各种清理教程所述,清理废弃镜像的方法应该是:记录 <要被删除> 的 tags 的 sha256,删除 tags,根据获得的 sha256,去 [ /repositories/${项目名}/_manifests/revisions/sha256 ] 中删除对应的文件夹,然后执行 garbage-collect 命令。
看起来很繁琐对吧?少废话,先看东西,上懒人脚本。
#!/bin/bash
shopt -s extglob
AbandonImg=`ls -l /transfer/registry/docker/registry/v2/repositories/ | awk '{print $9}'| tail -n +3`
for i in $AbandonImg
do
cd /transfer/registry/docker/registry/v2/repositories/$i/_manifests/revisions/sha256 && rm -rf !($(cat ../../tags/*/current/link | sed 's/sha256:/|/g'))
done
docker exec -it ${仓库容器名} sh -c 'registry garbage-collect /etc/docker/registry/config.yml'
核心命令只有一个,rm !():获取目前所有项目的 tags 文件夹中的 sha256 信息,然后在 revisions 文件夹中反选删除这些 sha256.也就是说在 “ revisions 文件夹” 中,删除任何 “ tags 文件夹” 中不存在的 sha256.
这也就是为什么说要把目录挂进去。registry 镜像所用基础 OS Alpine 只有 sh,没有 bash,而 sh 是不支持 shopt 命令的,也就不能实现反选。
那么删 sha256 的实现了,tags 过多成百个,删得手累怎么办?
这里就要用到我们神奇的 ncdu 文件管理工具了,能在命令行下实现仅次于 [rm -rf * ] 命令的超高效率的删除。也就是说,使用 ncdu 工具,进入到 [ /_manifests/tags/ ]文件夹中,删除不需要的版本号,然后执行一次上面的脚本,整个清理流程就结束了。推荐在删除完成后重启一下仓库(精神洁癖)
注:脚本请在充分测试后使用;部分参数与路径需要根据实际情况替换; tail 与 awk 命令可能会因为不同的系统打印不同的结果,此脚本在 CentOS 7.6.1810 中编写。
V2 不支持单双反引号的高亮格式,emmmm 为了版面,只好改成括号了。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.