在上一篇写过,如何定期清理Docker集群下每个节点的过期无用的镜像 Docker定期清除无用镜像
实现思路
编写Python脚本,调用Registry开放的API接口。 获取镜像列表 -> 获取标签列表 -> 获取镜像详情 -> 调用删除接口。
前期准备
Registry默认是不允许删除镜像的,需要修改一下配置参数,在安装Registry 这篇文章写过,如何配置删除权限。
Python脚本
好久没有写Python代码了,重新捡起来试试。
import requests
import time
import os
class Docker(object):
def restart(self):
# 执行arbage-collect命令,删除未被引用的layer
os.system("docker exec `docker ps | grep registry | awk '{print $1}'` registry garbage-collect /etc/docker/registry/config.yml")
# 重启registry容器
os.system("docker restart `docker ps | grep registry | awk '{print $1}'`")
def get_repos(self,hub):
get_repos_url = '%s/v2/_catalog' % (hub)
res = requests.get(get_repos_url).json()
return res['repositories']
def __init__(self, hub):
self.hub = hub
@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):
hub = self.hub
repos = self.get_repos(hub=hub)
for repo in repos:
self.delete_images(hub=hub, repo=repo)
self.restart()
def is_valid_date(self,str):
'''判断是否是一个有效的日期字符串'''
try:
time.strptime(str, "%Y%m%d%H%M%S")
return True
except:
return False
"""
下面删除镜像的处理逻辑,可自定义编写
我是根据时间戳作为镜像的标签,实现的思路是按照时间排序,保留最新的2个版本
"""
def delete_images(self, hub, repo):
tag_list = self.get_tag_list(hub=hub, repo=repo)
print('开始处理 %s : %s' % (repo, tag_list))
num = 0
try:
# 比如我所有服务的标签有三种:latest、SNAPSHOT、YYYYMMddHHmmss(时间戳)
del_tag_list = []
for tag in tag_list:
# 标签是latest或者含有SNAPSHOT忽略删除
if tag == 'latest' or 'SNAPSHOT' in tag :
print('%s 忽略 %s 删除' % (repo, tag))
elif self.is_valid_date(str=tag):
print('%s 符合时间戳标签' % (tag))
del_tag_list.append(tag)
# 按照时间排序
del_tag_list.sort()
# 保存最新2个版本
for item in del_tag_list[:-2]:
print('%s 删除 %s' % (repo, item))
# 获取image digest摘要信息
get_info_url = '{}/v2/{}/manifests/{}'.format(hub, repo, item)
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))
print('------------------------------------------------------------')
if __name__ == '__main__':
hub = 'http://192.168.1.200:5000'
d = Docker(hub=hub)
d.main()
上面Python脚本,参考了下面的博客,主要编写了需要删除的镜像过滤逻辑。
docker registry定期清理_mofei12138的博客-CSDN博客_docker registry 清理
Docker registry仓库历史镜像批量清理_ywq935的博客-CSDN博客
配置Crontab
# 进入任务编辑
crontab -e
# 添加定时任务,每天23:30 执行 "python /app/clear.py" 命令
30 23 * * * python /app/clear.py >>/app/logs/clear.log 2>&1