利用脚本对Docker Registry进行清理

565 阅读1分钟

docker registry非常轻量级,当时时间用的久了就会产生大量的历史镜像占用磁盘的问题,所以需要定期清理和回收磁盘空间。我们可以通过使用python脚本的方式进行处理。首选需要配置registry支持删除API,然后运行脚本,然后进入容器执行回收操作。

开启删除

进入容器内,修改配置文件/etc/docker/registry/config.yml

version: 0.1
log:
  fields:
    service: registry
storage:
    delete:
        enabled: true #修改这里
    cache:
        blobdescriptor: inmemory
    filesystem:
        rootdirectory: /var/lib/registry
http:
    addr: :5000
    headers:
        X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

执行删除脚本

通过调用Registry的API进行删除,只保留最近的2个镜像

import requests
from concurrent.futures import ThreadPoolExecutor


class Docker(object):
    def __init__(self, hub, repos):
        self.hub = hub
        self.repos = repos

    @staticmethod
    def get_repo_list(hub):
        # 获取所有repo
        repo_list_url = '%s/v2/_catalog' % (hub)
        r1 = requests.get(url=repo_list_url)
        repo_list = r1.json().get('repositories')
        return repo_list

    @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://root:123456@10.10.0.14:5000'
    repos = Docker.get_repo_list(hub)
    d = Docker(hub=hub, repos=repos)
    d.main()

回收磁盘空间

# 容器内执行该命令进行最后的磁盘回收
registry garbage-collect /etc/docker/registry/config.yml