前言

在jenkins CI/CD流水线中以自动打包并push镜像的方式运行了一段时间之后,

docker registry中堆积的历史镜像数量极多,磁盘空间告急,为此,有必要定期做镜像的清理,并释放镜像占用的存储空间。

清除原理

Docker registry提供有restful api进行镜像管理,参考官方文档:
https://docs.docker.com/registry/spec/api/

Docker存储使用的aufs文件系统分层存储结构,将容器文件以读写分层的形式存储在宿主机中.在registry容器中,

存放镜像的分层数据在宿主机上的挂载路径为:

/var/lib/docker/volumes/{container_id}/_data/docker/registry/v2/blobs

关于docker aufs的存储模式,这篇文章写得非常通俗易懂,可以参考:
https://www.cnblogs.com/sammyliu/p/5931383.html

一图简介上层镜像生成及删除过程中的分层文件处理原理:

如图中文字解释,仅仅是调用api删除镜像是不够的,在删除了镜像之后,镜像的非共享分层文件还是会存放在磁盘中继续占用存储空间,

因此,需要在删除镜像之后,使用docker registry自带的GC工具来进行垃圾分层(即无绑定镜像的分层)数据清除.

镜像分析

在了解以上前提后,开始排查哪些registry repo的历史镜像较多(分层数量多)
1.从宿主机进入docker registry容器内部,使用registry GC分析命令查看分层情况:

registry garbage-collect --dry-run /etc/docker/registry/config.yml  # --dry-run选项为layer层级分析,并不实际进行GC

2.可以便捷使用以下命令对分层数较多的镜像做一个排序:

registry garbage-collect --dry-run /etc/docker/registry/config.yml >> res.txt
6ac03183e197:~# cat res.txt | awk -F : '{print $1}' | sort | uniq -c | sort -rn -k1 | head -10
134161 zdtest
56101 ordertest
42691 bjdev
35881 zhqtest
13801 systemtest
9601 zddev
9361 bjtest
7411 dsystemtest
505 tooltest

可以看到,如上10个repo历史镜像数量大,需要清理。

删除镜像

注意:

无论是delete方法调用restful接口,还是registry 自带工具的GC清理,都需要registry的配置文件中开启允许删除功能:

vim /etc/docker/registry/config.yml

storage:
  delete:
    enabled: true

由于数量较多,因此使用python多线程来调用registry restful api进行删除操作,脚本内容如下,可根据自己的场景修改registry url:

import requests
from concurrent.futures import ThreadPoolExecutor class Docker(object):
def __init__(self, hub, repos):
self.hub = hub
self.repos = repos @staticmethod
def get_tag_list(hub, repo):
# 获取这个repo的所有tags
tag_list_url = '%s/v2/%s/tags/list' % (hub, repo)
r1 = requests.get(url=tag_list_url)
tag_list = r1.json().get('tags')
return tag_list def main(self):
thpool = ThreadPoolExecutor(10)
for repo in self.repos:
thpool.submit(self.delete_images, repo) thpool.shutdown(wait=True) def delete_images(self, repo):
hub = self.hub
tag_list = self.get_tag_list(hub=hub, repo=repo)
num = 0
try:
# 保留最后两个版本的镜像
for tag in tag_list[:-2]:
# 获取image digest摘要信息
get_info_url = '{}/v2/{}/manifests/{}'.format(hub, repo, tag)
header = {"Accept": "application/vnd.docker.distribution.manifest.v2+json"}
r2 = requests.get(url=get_info_url, headers=header, timeout=10)
digest = r2.headers.get('Docker-Content-Digest') # 删除镜像
delete_url = '%s/v2/%s/manifests/%s' % (hub, repo, digest)
r3 = requests.delete(url=delete_url)
if r3.status_code == 202:
num += 1 except Exception as e:
print(str(e)) print('仓库%s 共删除了%i个历史镜像' % (repo, num)) if __name__ == '__main__':
hub = 'http://registry.xxx.com:5000'
repos = ['zdtest', 'ordertest', 'bjdev', 'zhqtest', 'systemtest', 'zddev', 'bjtest', 'dsystemtest', 'tooltest']
d = Docker(hub=hub, repos=repos)
d.main()

运行结果:

仓库tooltest 共删除了17个历史镜像
仓库dsystemtest 共删除了245个历史镜像
仓库bjtest 共删除了310个历史镜像
仓库zddev 共删除了318个历史镜像
仓库systemtest 共删除了463个历史镜像
仓库zdtest 共删除了1574个历史镜像
仓库zhqtest 共删除了300个历史镜像
仓库bjdev 共删除了1421个历史镜像
仓库ordertest 共删除了1868个历史镜像

空间清理

回到docker registry容器内,直接运行GC命令,这次不再加 --dry-run选项

registry garbage-collect /etc/docker/registry/config.yml

查看磁盘,可以发现磁盘容量已经空闲出许多了,镜像清理及存储空间释放完成!

———————————————————————————————————

原文链接:https://blog.csdn.net/ywq935/article/details/83828888

【转载】Docker registry仓库历史镜像批量清理的更多相关文章

  1. Docker——Registry搭建私有镜像仓库

    前言 在 Docker 中,当我们执行 docker pull xxx 的时候,它实际上是从 registry.hub.docker.com 这个地址去查找,这就是Docker公司为我们提供的公共仓库 ...

  2. Docker 国内仓库和镜像

    Docker 国内仓库和镜像 由于网络原因,我们在pull Image 的时候,从Docker Hub上下载会很慢...所以,国内的Docker爱好者们就添加了一些国内的镜像(mirror),方便大家 ...

  3. docker 私有仓库 删除镜像

    1.查找官方删除法 https://github.com/burnettk/delete-docker-registry-image 2.民用删除法 https://segmentfault.com/ ...

  4. Docker | 使用dockerfile生成镜像,清理docker空间

    用dockerfile生成镜像并挂载数据卷 编写dockerfile文件 创建dockerfile01 文件 # 基础镜像 FROM centos VOLUME ["volume01&quo ...

  5. Docker国内仓库和镜像

    由于网络原因,我们在pull Image 的时候,从Docker Hub上下载会很慢...所以,国内的Docker爱好者们就添加了一些国内的镜像(mirror),方便大家使用. 一.国内Docker仓 ...

  6. docker官方仓库下载镜像

    官方仓库镜像地址:https://hub.docker.com/search/ 以下载mysql为例 进入到详情页后我们看到有很多Tags 我们选择5.7.25版本进行下载 # docker pull ...

  7. docker的容器和镜像的清理

    Docker用户会在使用docker一段时间后发现宿主机的磁盘很容易就快被占满,并且手动docker rmi [imgName]似乎并不能释放磁盘,貌似想删掉的镜像依然在宿主机中,下面针对这一问题提出 ...

  8. Docker 私有仓库下载镜像

    1.添加私有仓库路径 vim /etc/sysconfig/docker --insecure-registry 192.168.105.30:5000 注:版本差异 2.下载镜像 docker pu ...

  9. (转载)Docker的boot2docker.iso镜像使用

    原文路径:https://blog.csdn.net/jiangjingxuan/article/details/54908272#commentsedit 在Docker首次启动时需要下载的一个bo ...

随机推荐

  1. Android触摸反馈

    事件分发 当点击事件发生时,事件最先传递给Activity,Activity会首先将事件将被所属的Window进行处理,即调用 superDispatchTouchEvent() 方法.通过观察sup ...

  2. Linux下设置mysql不区分大小写

    一.通过命令查看mysql是否是区分大小写的 show variables like '%case_table%'; lower_case_table_names=1(说明是不区分大小写的) lowe ...

  3. 移动端开发语言的未来的猜想#华为云·寻找黑马程序员#【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  4. Python高级学习笔记

    Python高级学习笔记,此笔记中包含Linux操作系统.Html+CSS+JS.网络协议等. 所有思维导图为本人亲手所画,请勿用于商用. 大哥们,求点赞哦. 第一天笔记:链接 第二天笔记:链接 第三 ...

  5. 转:IK分词原理

    IKAnalyzer是一个开源的,基于Java语言开发的轻量级的中文分词语言包,它是以Lucene为应用主体,结合词典分词和文法分析算法的中文词组组件.从3.0版本开始,IK发展为面向java的公用分 ...

  6. SpringBoot-了解微服务(二)

    什么是微服务? 微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合: 可以通过http的方式进行互通. 要说微服务架构,先了解一下以前的单体应用架构 单体应用架 ...

  7. Chrome快捷键吐血整理

    Chrom是平时开发过程中最常用到的浏览器,使用快捷键操作Chrome能提高我们的使用效率,而且可以脱离鼠标进行操作.本篇博客就对平时我们常用的Chrome快捷键做一个整理总结.大家拿走不谢,哈哈~~ ...

  8. HashMap踩坑实录——谁动了我的奶酪

    说到HashMap,hashCode 和 equals ,想必绝大多数人都不会陌生,然而你真的了解这它们的机制么?本文将通过一个简单的Demo还原我自己前不久在 HashMap 上导致的线上问题,看看 ...

  9. CodeForces 607B zuma

    Genos recently installed the game Zuma on his phone. In Zuma there exists a line of n gemstones, the ...

  10. (全国多校重现赛一) J-Two strings

    Giving two strings and you should judge if they are matched.  The first string contains lowercase le ...