【转载】Docker registry仓库历史镜像批量清理
前言
在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仓库历史镜像批量清理的更多相关文章
- Docker——Registry搭建私有镜像仓库
		
前言 在 Docker 中,当我们执行 docker pull xxx 的时候,它实际上是从 registry.hub.docker.com 这个地址去查找,这就是Docker公司为我们提供的公共仓库 ...
 - Docker 国内仓库和镜像
		
Docker 国内仓库和镜像 由于网络原因,我们在pull Image 的时候,从Docker Hub上下载会很慢...所以,国内的Docker爱好者们就添加了一些国内的镜像(mirror),方便大家 ...
 - docker 私有仓库 删除镜像
		
1.查找官方删除法 https://github.com/burnettk/delete-docker-registry-image 2.民用删除法 https://segmentfault.com/ ...
 - Docker | 使用dockerfile生成镜像,清理docker空间
		
用dockerfile生成镜像并挂载数据卷 编写dockerfile文件 创建dockerfile01 文件 # 基础镜像 FROM centos VOLUME ["volume01&quo ...
 - Docker国内仓库和镜像
		
由于网络原因,我们在pull Image 的时候,从Docker Hub上下载会很慢...所以,国内的Docker爱好者们就添加了一些国内的镜像(mirror),方便大家使用. 一.国内Docker仓 ...
 - docker官方仓库下载镜像
		
官方仓库镜像地址:https://hub.docker.com/search/ 以下载mysql为例 进入到详情页后我们看到有很多Tags 我们选择5.7.25版本进行下载 # docker pull ...
 - docker的容器和镜像的清理
		
Docker用户会在使用docker一段时间后发现宿主机的磁盘很容易就快被占满,并且手动docker rmi [imgName]似乎并不能释放磁盘,貌似想删掉的镜像依然在宿主机中,下面针对这一问题提出 ...
 - Docker 私有仓库下载镜像
		
1.添加私有仓库路径 vim /etc/sysconfig/docker --insecure-registry 192.168.105.30:5000 注:版本差异 2.下载镜像 docker pu ...
 - (转载)Docker的boot2docker.iso镜像使用
		
原文路径:https://blog.csdn.net/jiangjingxuan/article/details/54908272#commentsedit 在Docker首次启动时需要下载的一个bo ...
 
随机推荐
- c# 窗体开发1  基本控件的使用
			
namespace firstly #当前命名空间控件 { public partial class Form1 : Form { public Form1() #第一个窗体 { Initiali ...
 - Hyperledger Fabric手动生成CA证书搭建Fabric网络
			
之前介绍了使用官方脚本自动化启动一个Fabric网络,并且所有的证书都是通过官方的命令行工具cryptogen直接生成网络中的所有节点的证书.在开发环境可以这么简单进行,但是生成环境下还是需要我们自定 ...
 - 【经验分享】linux交叉编译 - openssl动态库
			
一.准备工作 1.到openssl官网下载最新版本openssl(如openssl-1.1.1d.tar.gz),上传到linux编译机上(如上传到目录/home/test下),并使用tar -xvf ...
 - nginx的部署及配置文件的介绍  域名  用户认证   SSL加密模块
			
步骤一:构建Nginx服务器 yum -y install gcc pcre-devel openssl-devel #安装依赖包 wget http://nginx.org/dow ...
 - iOS 音频开发之CoreAudio
			
转自:http://www.cnblogs.com/javawebsoa/archive/2013/05/20/3089511.html 接 触过IOS音频开发的同学都知道,Core Audio 是I ...
 - react-native中更改android/ios的入口文件
			
android 1.android /app/build.gradle project.ext.react = [ entryFile: "index.android.js" ] ...
 - Rest微服务案例
			
数据库 数据库名称为Product; 创建api子工程,项目名为springcloud_api Product实体类 public class Product implements Serializa ...
 - Vue&Cesium&Ribbon界面: 将桌面GIS搬进浏览器
			
上一篇文章在这里:vue集成cesium,webgis平台第一步 把界面改了一下,开始实际填充功能. Ribbon是一种以面板及标签页为架构的用户界面(User Interface),原先出现在Mic ...
 - 2019CCPC秦皇岛D题 Decimal
			
Decimal Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total S ...
 - telnet远程登陆
			
这篇文章是第二次更新,内容为telnet远程登陆路由器,非常简单.直接进入正题,在网络配通的情况下,为路由器设置登陆密码和管理员密码,就可以通过pc机远程管理路由器或交换机. 目的: 网络拓扑图如下, ...