在开发测试环境,因为频繁触发 CICD 构建流程,私有镜像仓库 Harbor 会出现存储用满的情况。这个时候,一般加存储扩容就可以解决。但是镜像的存储也不能无限加大,删除无人使用的冗余镜像是个可行的办法。本文提供删除镜像的一个办法。

准备registry-manager

registry-manager是一款第三方工具 https://github.com/TimeBye/registry-manager

目前存放在神兵 cloud-map-native 仓库的 1.16 分支下。

它是 Go 语言实现的命令行工具,调用 Registry API 进行进行软删除。

下载可执行文件 registry-manager,编写 registry-manager.yml 文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 仓库相关信息
server: https://30.23.17.121/
username: admin
password: Harbor12345
# 自签名证书请设置为true
insecure-skip-tls-verify: false

delete-policy:
  # 仅模拟运行,不真实删除,默认启用
  dry-run: false
  # 删除以现在时间为基础以前的镜像,单位为小时,默认72
  interval-hour: 72
  # 至少保留镜像个数,默认10
  mix-count: 10
  # 镜像tag删除策略
  tags:
    # 删除策略
    include:
      # 按关键字进行删除
      keys: 
      # 按正则表达式删除
      regex:
    # 排除策略,删除策略与排除策略都匹配,以排除策略为准
    exclude:
      # 按关键字进行排除
      keys:
      # 按正则表达式排除
      regex: 

上图的配置中其含义如下,删除 tag 数大于 10 的且创建时间在 72 小时之前的镜像。

执行删除

执行下面的命令开始进行软删除

registry-manager delete -c registry-manager.yml

界面会不停输出信息,报告当前的处理进度。具体耗时随镜像仓库的大小会有所不同,建议在避开开发测试人员使用镜像的高峰期来执行删除操作。

软删除成功后,去到 Harbor 所在的节点,以 harbor 用户身份进入 registryctl 容器:

docker exec -it --user harbor registryctl /bin/bash

执行删除命令,

# 测试执行,不会真回收,可在日志中看到要回收的镜像
$ registry garbage-collect --dry-run /etc/registry/config.yml
# 执行回收
$ registry garbage-collect /etc/registry/config.yml

执行完成后,可以看到存储明显下降了。

异常处理

关于异常的处理:

在执行的过程中遇到了这个问题:failed to mark: invalid checksum digest format

这有可能是镜像同步过程,被强行中断造成的结果。导致实际的后端存储和 harbordb 的数据不一致。处理流程如下:

  1. 根据 garbage-collect 中报出错误,定位是哪个 repo 形成了空链接。

  2. 去 harbor 节点对应的宿主机挂载路径,定位 repo 目录,以删除 library/nginx repo 为例。

    切换到repo
    # cd /data/registry/docker/registry/v2/repositories/
       
    查看project,这一层对应了harbor下的项目
    # ls 
       
    # cd library
       
    删除
    # rm -fr nginx
    
  3. 删除后再次进入 harbordb 容器,执行硬删除操作。

删除过程可能耗时较长,完成后在 Harbor 界面上,可以看到剩余容量又回来了。