Harbor存储回收

Harbor简介

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源的Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。现在Harbour已成为由Cloud Native Computing Foundation(CNCF)托管的项目。

Harbor存储回收

在使用Harbor很长一段时间后镜像所占存储空间越来越大,我们就需要对不再会使用到的镜像进行删除回收它所占用到的空间以免浪费资源。删除镜像的操作显然是一个非常有重复性的操作,那么我们就可以定制一些规则调用Harbor的API进行删除。这些操作我们将会使用到Harbor的以下API:

Method URL Remarks
GET /projects List projects
GET /repositories Get repositories accompany with relevant project and repo name.
GET /repositories/{repo_name}/tags Get tags of a relevant repository.
DELETE /repositories/{repo_name}/tags/{tag} Delete a tag in a repository.

首先获取所有项目列表,依次遍历项目下所有的仓库,将仓库下的镜像tag逐一列出进行规则比对,若包含定义的关键字或匹配的正则表达式进行删除,不具备条件的则略过。此操作只是进行软删除,不回收镜像实际所占物理存储。比对tag是否满足删除规则的代码如下:

func needDeleteTag(tag harbor.TagResp, count *int) bool {
    baseTime, _ := time.ParseDuration("1h")
    if time.Now().Sub(tag.Created) < deletePolicy.IntervalHour*baseTime || *count < deletePolicy.MixCount {
        *count += 1
        return false
    }
    match, err := regexp.MatchString(deletePolicy.Tags.Exclude.Regex, tag.Name)
    checkErr(err)
    if match {
        return false
    }
    match, err = regexp.MatchString(deletePolicy.Tags.Exclude.KeysRegex, tag.Name)
    checkErr(err)
    if match {
        return false
    }
    match, err = regexp.MatchString(deletePolicy.Tags.Include.Regex, tag.Name)
    checkErr(err)
    if match {
        glog.V(2).Infof("%s match Tags.Regex: %s", tag.Name, deletePolicy.Tags.Include.Regex)
        return true
    }
    match, err = regexp.MatchString(deletePolicy.Tags.Include.KeysRegex, tag.Name)
    checkErr(err)
    if match {
        glog.V(2).Infof("%s match Tags.KeysRegex: %s", tag.Name, deletePolicy.Tags.Include.KeysRegex)
        return true
    }
    return false
}

项目代码已上传至Github,可使用go get进行安装或直接下载编译好的可执行文件

go get -u github.com/TimeBye/harbor-cleaner

使用harbor-cleaner进行软删除

  • 编写配置文件delete_policy.yml
# 仓库相关信息
registry_url: https://registry.example.com/
username: admin
password: password

# 仅模拟运行,不真实删除,默认启用
dry_run: true
# 删除以现在时间为基础以前的镜像,单位为小时,默认72
interval_hour: 72
# 至少保留镜像个数,默认10
mix_count: 10
# 忽略这个项目下所有镜像
ignore_projects:
# 项目删除策略
projects:
  # 是否删除空项目
  delete_empty: false
  # 需删除的关键字
  include:
    # 按关键字进行删除
    keys:
    # 按正则表达式删除
    regex:
  # 排除策略,删除策略与排除策略都匹配,以排除策略为准
  exclude:
    # 按关键字进行排除
    keys:
    # 按正则表达式排除
    regex:

# 镜像tag删除策略
tags:
  # 删除策略
  include:
    # 按关键字进行删除
    keys: dev,test
    # 按正则表达式删除
    regex:
  # 排除策略,删除策略与排除策略都匹配,以排除策略为准
  exclude:
    # 按关键字进行排除
    keys:
    # 按正则表达式排除
    regex: latest|master|^[Vv]?(\d+(\.\d+){1,2})$
  • 运行并指定配置文件位置
harbor-cleaner -f delete_policy.yml

存储回收

Harbor v1.7.0及以上版本

Harbor从v1.7.0版本开始支持不停机进行在线存储回收。在调用本程序进行软删除后,系统管理员可以通过单击“管理”下“配置”部分的“垃圾回收”选项卡来配置或触发存储回收。

image.png

👋 注意 👋在执行存储回收时,Harbor将进入只读模式,并且禁止对 docker registry 进行任何修改。换而言之就是此时只能拉镜像不能推镜像。

Harbor 1.7.0以前版本

Harbor从v1.7.0以前版本进行存储回收时需要手动切断外部访问以达到禁止对 docker registry 进行任何修改的目的。回收镜像所占存储参考文档

  • 切断外部访问入口

  • 进入到registry容器中执行存储回收命令

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

不理想的地方

不论是哪个版本的Harbor进行存储回收都是使用docker registry官方的命令进行回收,但回收空间太少,很多manifests仍没删除。那就只有扫描镜像仓库存储文件,通过docker registry api删除无用的manifests。这里可参考使用mortensrasmussendocker-registry-manifest-cleanup项目。

  • 使用docker-registry-manifest-cleanup当前最新版本进行存储回收
    # 执行以下脚本尝试通过api模拟删除manifests
    $ docker run -it \
        -v /home/someuser/registry:/registry \
        -e REGISTRY_URL=https://registry.example.com \
        -e DRY_RUN="true" \
        -e SELF_SIGNED_CERT="true" \
        -e REGISTRY_AUTH="myuser:sickpassword" \
        mortensrasmussen/docker-registry-manifest-cleanup:1.1.1
    # 如上一步没有报错,执行以下脚本,真正删除
    $ docker run -it \
        -v /home/someuser/registry:/registry \
        -e REGISTRY_URL=https://registry.example.com \
        -e SELF_SIGNED_CERT="true" \
        -e REGISTRY_AUTH="myuser:sickpassword" \
        mortensrasmussen/docker-registry-manifest-cleanup:1.1.1
    

若使用上面命令执行报错找不到目录的错误可切换docker-registry-manifest-cleanup的版本至1.0.5进行尝试

  • 使用docker-registry-manifest-cleanup 1.0.5进行存储回收。
    # 由于以前的版本不支持提权,故将 /etc/registry/config.yml 中的鉴权配置部分先暂时注释掉,重启registry容器
        # auth:
          # token:
            # issuer: harbor-token-issuer
            # realm: https://registry.example.com/service/token
            # rootcertbundle: /etc/registry/root.crt
            # service: harbor-registry
    
    # 执行以下脚本尝试通过api模拟删除manifests
    $ docker run -it --rm \
        -v /home/someuser/registry:/registry \
        -e REGISTRY_URL=https://registry.example.com \
        -e CURL_INSECURE=true \
        -e DRY_RUN=true \
        mortensrasmussen/docker-registry-manifest-cleanup:1.0.5
        
    # 如上一步没有报错,执行以下脚本,真正删除
    $ docker run -it --rm \
        -v /home/someuser/registry:/registry \
        -e REGISTRY_URL=https://registry.example.com \
        -e CURL_INSECURE=true \
        mortensrasmussen/docker-registry-manifest-cleanup:1.0.5
    
    # 执行完成后将授权配置改回来,取消注释
        auth:
          token:
            issuer: harbor-token-issuer
            realm: https://registry.example.com/service/token
            rootcertbundle: /etc/registry/root.crt
            service: harbor-registry
    

参考文档:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容