一文掌握Harbor的配额管理和GC机制

目录

1. 原理概述

1.1 项目配额管理解析

1.1.1 Harbor配额管理架构原理
1.1.2 配额执行机制详解
1.1.3 配额存储空间计算算法

1.2 GC机制过程详解

1.2.1 清理的存储组件
1.2.2 GC对存储层的优化影响

1.3 GC的触发方式

1.3.1 GC工作机制详解

2. 项目配额管理实验

2.1 配额策略配置

2.1.1 通过Web UI方式配置
2.1.2 通过API方式修改配额

2.2 存储配额实验

2.2.1 实验1:测试存储配额限制
2.2.2 实验2:配额监控与告警

2.2.2.1 故障排除:sendemail TLS支持问题

3. 垃圾回收机制实验

3.1 手动触发垃圾回收实验

3.1.1 准备测试数据
3.1.2 手动触发垃圾回收

3.1.2.1 dry-run模式测试
3.1.2.2 立即执行垃圾回收

3.1.3 自动垃圾回收配置

4. 总结

关键要点回顾

5.参考资料

📚 博客主页: StevenZeng学堂

🎉 博客专栏:

一文读懂Kubernetes
一文读懂Harbor
云原生安全实战指南
云原生存储实践指南



❤️ 摘要: 本文深度解析Harbor的配额管理和垃圾回收机制,就像给Harbor装上了”智能管家”和”清洁工”。通过详细的实验案例,紧接上文《一文掌握Harbor的存储引擎-Docker Distribution Registry v2深度解析》,继续介绍项目配额控制和垃圾回收机制。文章包含丰富的代码示例和实操指南,适合容器化运维工程师、云原生架构师以及对Harbor管理感兴趣的技术人员学习参考。


💯 本文关联好文:

《一文读懂Harbor以及部署实践攻略》
《【云原生安全篇】Trivy助力离线Harbor漏洞扫描实践》
《一文学会Harbor的存储引擎-Docker Distribution Registry v2深度解析》


✍🏻本文知识点:

🎯 Harbor项目配额管理机制与实战
🧹 垃圾回收(GC)原理与自动化配置
📊 存储空间监控与告警实践
🔧 API操作与故障排除技巧


1. 原理概述

想象一下,Harbor就像一个巨大的仓库,而配额管理就是仓库的”门卫”,垃圾回收则是勤劳的”清洁工”。让我们来看看这两位”员工”是如何协同工作的。

1.1 项目配额管理解析

1.1.1 Harbor配额管理架构原理

Harbor的配额管理系统就像一个精明的会计师,基于Docker Distribution Registry v2的存储架构,在以下层面实现精确的资源控制:

1.1.2 配额执行机制详解

Harbor的配额执行就像三道安检门,确保每个”乘客”(镜像)都符合规定:

🚪 第一道门:Blob级配额检查

执行时机: 在Docker push过程中,每个blob上传前进行检查
检查逻辑: 计算当前项目已使用存储 + 待上传blob大小是否超过配额
智能去重: 利用内容寻址存储(CAS),相同blob只计算一次存储空间(就像同一个人不会被重复计费)

🚪 第二道门:Manifest级配额检查

执行时机: 在镜像manifest推送时进行最终检查
检查内容: 验证manifest引用的所有blob总大小,确保manifest引用的blob都在配额范围内

🚪 第三道门:Repository计数配额

执行时机: 创建新repository时检查
计数逻辑: 统计项目下的repository目录数量

1.1.3 配额存储空间计算算法

Harbor采用智能的存储计算算法,其中unique_blob_sizes考虑了跨项目的blob去重:

project_storage_usage = Σ(unique_blob_sizes_in_project)

💡 小贴士: 这就像统计图书馆的藏书,同一本书不管被多少人借阅,都只算一本的存储空间。

1.2 GC机制过程详解

Harbor的垃圾回收就像一个勤劳的清洁工,专门清理Docker Distribution Registry v2存储中的”垃圾”:

1.2.1 清理的存储组件

Harbor GC会清理以下”垃圾”:

🗑️ Blob数据文件: /data/registry/docker/registry/v2/blobs/sha256/{prefix}/{digest}/data
📁 Upload临时文件: /data/registry/docker/registry/v2/uploads/{uuid}/
📂 空的存储目录: 清理后的空目录结构
🔗 孤立的链接文件: 不再被引用的link文件

不会清理的组件(重要文件)

📋 Manifest文件: 保留在repositories目录中
🏷️ Tag链接: 保留标签到manifest的映射
📊 Repository元数据: 保留项目和仓库结构

1.2.2 GC对存储层的优化影响

🔄 存储空间回收

直接回收: 删除未引用的blob文件,立即释放磁盘空间
间接回收: 清理空目录,优化文件系统结构
缓存清理: 清理上传临时文件,释放临时存储

⚡ 存储性能优化

减少inode使用: 删除不必要的文件和目录
提升查找效率: 减少文件系统扫描开销

🛡️ 存储一致性保证

原子性操作: 确保清理过程的原子性
引用完整性: 保证被引用的blob不被误删
并发安全: 在清理过程中保护正在进行的上传操作

1.3 GC的触发方式

Harbor GC就像一个智能的清洁机器人,有多种启动方式:

🖱️ 手动触发: 通过Web UI或API手动启动(适合临时清理)
⏰ 定时触发: 配置定时任务自动执行(适合定期维护)
📊 存储阈值触发: 当存储使用率达到设定阈值时自动触发(智能清理)

1.3.1 GC工作机制详解

Harbor的垃圾回收基于Docker Distribution的GC机制,采用标记-清除(Mark and Sweep)算法:

2. 项目配额管理实验

Harbor提供了强大的项目配额管理功能,就像给每个项目分配一个”存储钱包”,可以限制项目的存储使用量和仓库数量。

2.1 配额策略配置

2.1.1 通过Web UI方式配置

通过Web UI创建一个新的项目project3,并配置项目配额100M:

💡 注意: 创建完成项目后,无法在项目页面直接修改配额,需要通过 系统管理 → 项目定额 来修改。

例如,将project3的配额修改为200M:

2.1.2 通过API方式修改配额

对于喜欢命令行的朋友,Harbor也提供了强大的API接口。首先查询项目ID:

# 查询项目信息,获取项目ID
curl -s -k -X GET "https://harbor.zx/api/v2.0/projects/project3" 
  -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" | jq

从返回结果可以看到项目ID是4:

{
            
  "creation_time": "2025-07-11T06:07:20.482Z",
  "current_user_role_id": 1,
  "current_user_role_ids": [
    1
  ],
  "cve_allowlist": {
            
    "creation_time": "0001-01-01T00:00:00.000Z",
    "id": 4,
    "items": [],
    "project_id": 4,
    "update_time": "0001-01-01T00:00:00.000Z"
  },
  "metadata": {
            
    "public": "false"
  },
  "name": "project3",
  "owner_id": 1,
  "owner_name": "admin",
  "project_id": 4,
  "repo_count": 0,
  "update_time": "2025-07-11T06:07:20.482Z"
}

现在通过API动态调整配额限制,比如设置成2GB:

# 更新项目配额为2GB
curl -k -X PUT 
  "https://harbor.zx/api/v2.0/quotas/4" 
  -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" 
  -H "Content-Type: application/json" 
  -d '{
        "hard": {
            "storage": 2147483648
        }
  }'

查看项目配额信息:

# 获取项目配额详情
curl -s -k -X GET "https://harbor.zx/api/v2.0/quotas/4" 
  -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" | jq

API返回的配额信息:

{
            
  "creation_time": "2025-07-11T06:07:20.542Z",
  "hard": {
            
    "storage": 2147483648
  },
  "id": 4,
  "ref": {
            
    "id": 4,
    "name": "project3",
    "owner_name": ""
  },
  "update_time": "0001-01-01T00:00:00.000Z",
  "used": {
            
    "storage": 0
  }
}

通过Web UI查看配额设置效果:

2.2 存储配额实验

2.2.1 实验1:测试存储配额限制

我们可以通过脚本精确计算项目底层存储空间,创建 calc_project_space.sh

#!/bin/bash
# Harbor配额计算脚本 - 考虑blob去重机制
# 使用方法: ./calc_project_space.sh project_name

project=${1:-"project1"}

echo "计算项目 ${project} 的存储使用情况..."

# 1. 提取项目所有引用的blob digest(去重)
echo "提取项目引用的blob列表..."
unique_digests=$(for link_file in $(find /data/registry/docker/registry/v2/repositories/${
             project}/ -name "link" 2>/dev/null); do
  cat $link_file | cut -d: -f2
done | sort | uniq)

# 2. 计算去重后的blob总大小
echo "计算存储空间使用..."
total_size=0
for digest in ${unique_digests}; do
  blob_path="/data/registry/docker/registry/v2/blobs/sha256/${digest:0:2}/${digest}/data"
  if [ -f "$blob_path" ]; then
    size=$(stat -c%s "$blob_path")
    total_size=$((total_size + size))
  fi
done

# 3. 输出结果
echo "计算完成!"
echo "项目存储使用: $(echo "scale=4; $total_size / 1024 / 1024" | bc)MB"

执行脚本,输出是91.2828MB,与Web UI显示一致:

现在将配额设置为100MB进行测试:

下载测试镜像并尝试上传:

# 下载测试镜像
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/debian:bullseye-slim

# 重新标记镜像
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/debian:bullseye-slim 
  harbor.zx/project1/debian:bullseye-slim

# 尝试推送镜像
docker push harbor.zx/project1/debian:bullseye-slim

🚫 上传失败! Harbor配额机制生效,提示超过配额:

The push refers to repository [harbor.zx/project1/debian]
b99d01c6daf9: Pushing  84.21MB
denied: adding 30.0 MiB of storage resource, which when updated to current usage of 91.3 MiB will exceed the configured upper limit of 100.0 MiB.

💡 配额机制验证成功! Harbor精确计算出当前使用91.3MB + 新增30MB = 121.3MB,超过了100MB的配额限制。

现在将配额调整到200MB再测试上传:

这次正常上传成功! 配额管理机制工作正常。

The push refers to repository [harbor.zx/project1/debian]
b99d01c6daf9: Pushed
bullseye-slim: digest: sha256:d1650e8fd5a2677475d4328103df7c1a7b35040c4434316c4e3897efda30e460 size: 528

通过脚本计算,得出结果也是一直的。

root@rke2 # ./calc_project_space.sh project1
121.278Mib

2.2.2 实验2: 配额监控与告警

实验环境: ubuntu22.04

安装依赖工具

sudo apt-get update && sudo apt-get install -y sendemail libssl-dev libnet-ssleay-perl

设置自动化配额告警脚本: 脚本已上传gitcode仓库,包括 harbor_quota_alert.sh

以及python版 harbor_quota_alert.py,config_loader.py, .env(.env.template复制并修改参数即可)

2.2.2.1 ⚠️注意 : 如果sendemail命令报错No TLS support
Jul 11 16:06:57 rke2-rancher sendemail[16026]: ERROR => No TLS support!  SendEmail can't load required libraries. (try installing Net::SSLeay and IO::Socket::SSL)

通过以下步骤解决

curl -L https://cpanmin.us | perl - App::cpanminus

cpanm IO::Socket::SSL

输出

OK
Successfully installed IO-Socket-SSL-2.095

通过命令验证

perl -MIO::Socket::SSL -e1
perl -MNet::SSLeay -e1

在上传一个测试镜像

docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/valkey/valkey:alpine
docker tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/valkey/valkey:alpine  harbor.zx/project1/valkey:alpine
docker push harbor.zx/project1/valkey:alpine

执行脚本,发送告警邮件:

💡 小贴士: 可以设置定时任务(crontab)来定期监控配额使用情况,实现自动化运维。


3. 垃圾回收机制实验

Harbor的垃圾回收(Garbage Collection, GC)机制就像一个勤劳的清洁工,专门清理不再被引用的镜像层和blob,释放存储空间。

3.1 手动触发垃圾回收实验

3.1.1 准备测试数据

为了演示GC机制,我们需要准备一些测试镜像数据:

# 下载多个debian镜像版本
echo " 下载测试镜像..."
docker pull debian:trixie
docker pull debian:sid
docker pull debian:bullseye
docker pull debian:bookworm

重新标记并上传到project3项目:

# 重新标记镜像
echo "重新标记镜像..."
docker tag debian:trixie harbor.zx/project3/debian:trixie
docker tag debian:sid harbor.zx/project3/debian:sid
docker tag debian:bullseye harbor.zx/project3/debian:bullseye
docker tag debian:bookworm harbor.zx/project3/debian:bookworm

# 推送镜像到Harbor
echo "推送镜像到Harbor..."
docker push harbor.zx/project3/debian:trixie
docker push harbor.zx/project3/debian:sid
docker push harbor.zx/project3/debian:bullseye
docker push harbor.zx/project3/debian:bookworm

echo "测试数据准备完成!"

3.1.2 手动触发垃圾回收

检查项目当前使用空间,通过Web和API都可以查看, 上文已经说明用法,这里不再赘述。

查看项目配额信息:

通过api查询项目中的镜像

HARBOR_URL="harbor.zx"
PROJECT="project3"
curl -s -k "https://${HARBOR_URL}/api/v2.0/projects/${PROJECT}/repositories/debian/artifacts" 
    -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" |jq

输出如下:

通过api删除镜像

HARBOR_URL="harbor.zx"
PROJECT="project3"
curl -s -k -X DELETE "https://${HARBOR_URL}/api/v2.0/projects/${PROJECT}/repositories/debian/artifacts/trixie" 
    -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"
curl -s -k -X DELETE "https://${HARBOR_URL}/api/v2.0/projects/${PROJECT}/repositories/debian/artifacts/sid" 
    -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"
curl -s -k -X DELETE "https://${HARBOR_URL}/api/v2.0/projects/${PROJECT}/repositories/debian/artifacts/bullseye" 
    -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"
curl -s -k -X DELETE "https://${HARBOR_URL}/api/v2.0/projects/${PROJECT}/repositories/debian/artifacts/bookworm" 
    -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"

再查看项目

root@rke2# curl -s -k "https://${HARBOR_URL}/api/v2.0/projects/${PROJECT}/repositories/debian/artifacts"     -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"
[]  # 项目镜像已经清空

在web查看配额使用也是显示为0

❔ 思考: 那是不是证明Harbor已经把镜像数据删除了呢?

再通过上述的计算脚本检查下数据目录/data/registery

./calc_project_space.sh project3
196.072Mib

检查发现好像并没有立刻删除底层数据。

3.1.2.1 dry-run模式测试

dry-run会检查项目中被删除的镜像的blob和tag记录,但并不会真正执行删除操作。

输出日志:

显示没有需要删除的镜像,也没有未引用的对象,因此无需执行垃圾回收。

❔ 思考:明面上面删除了镜像,为什么gc检测没有需要删除的镜像?

❔ 思考:会不会因为project1有之前上传的debian镜像呢?

手动删除project1的测试镜像

重新执行模拟运行,这次确实显示有数据被回收成功。

3.1.2.2 立即执行垃圾回收

勾选”允许回收无tag的artifacts”并点击“立刻清理垃圾”

成功清理了空间

查看日志,看到project1和project3的空间都成功回收了。

补充:通过API查看gc的执行任务状态

curl -s -u admin:Harbor12345 -k "https://${HARBOR_URL}/api/v2.0/system/gc" |jq

输出

[
  {
            
    "creation_time": "2025-07-14T03:48:06.393Z",
    "id": 7,
    "job_kind": "MANUAL",
    "job_name": "GARBAGE_COLLECTION",
    "job_parameters": "{"delete_untagged":true,"dry_run":false,"freed_space":0,"purged_blobs":0,"purged_manifests":0,"redis_url_reg":"redis://redis:6379/1?idle_timeout_seconds=30","time_window":2,"workers":1}",
    "job_status": "Success",
    "schedule": {
            
      "next_scheduled_time": "0001-01-01T00:00:00.000Z",
      "type": "Manual"
    },
    "update_time": "2025-07-14T03:48:17.000Z"
  },

3.1.3 自动垃圾回收配置

GC还可以设置定时任务,

或者自定义任务,与crond的表述一致。

例如:实验设置为每小时执行一次,那么就会在每小时0分开始执行。

也可以通过脚本修改定时GC配置,同时也上传到gitcode仓库

#!/bin/bash
# 配置自动垃圾回收

HARBOR_URL="harbor.zx"

# 1. 配置每日凌晨2点执行GC
configure_scheduled_gc() {
            
  echo "配置定时垃圾回收..."

  curl -s -k -X PUT "https://${HARBOR_URL}/api/v2.0/system/gc/schedule" 
    -H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" 
    -H "Content-Type: application/json" 
    -d '{
      "schedule": {
        "type": "Daily",
        "cron": "0 0 2 * * *"
      },
      "delete_untagged": true,
      "dry_run": false
    }'

  echo "已配置每日凌晨2点执行垃圾回收"
}

configure_scheduled_gc

4 总结

通过本文的深度解析和实验,我们全面掌握了Harbor的配额管理和垃圾回收机制。这两个功能就像Harbor的”智能管家”和”清洁工”,确保存储资源的高效利用和自动化管理。

💡 最佳实践建议

配额设置策略:

根据项目实际需求合理设置配额
预留20-30%缓冲空间避免频繁告警
定期监控使用情况,及时调整

GC执行策略:

建议在业务低峰期执行GC
先使用dry-run模式验证清理范围
配置定时任务实现自动化维护

监控告警机制:

设置配额使用率告警(建议80%阈值)
监控GC执行结果和清理效果
建立存储使用趋势分析


5.参考资料

[1] Harbor官方文档-configure-project-quotas
[2] Harbor官方文档-garbage-collection

[3] Harbor API参考
[4] Docker Distribution Registry v2规范


📝 作者说明: 本文基于Harbor 2.x版本编写,部分API和功能在不同版本间可能存在差异。建议读者根据实际使用的Harbor版本查阅对应的官方文档。

💬 交流反馈: 如果您在实践过程中遇到问题或有改进建议,欢迎在评论区交流讨论!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容