解释 Harbor GC 的“软删除”与“硬删除”流程

解读

Harbor 作为企业级镜像仓库,在每天高频推送、覆盖、删除镜像的场景下,存储层(filesystem 或对象存储) 并不会立即释放空间,而是依赖 Garbage Collector(GC) 完成真正清理。面试官问“软删除”与“硬删除”,实质想考察两点:

  1. 你是否理解 Harbor 的“标记-清理”两阶段模型;
  2. 你是否能把“Registry API 删除 → Harbor 元数据软删除 → GC 硬删除”这条链路讲清楚,并给出生产可落地的注意事项(停机窗口、只读模式、并发安全、回滚方案)。
    回答时务必结合国内主流部署方式(Kubernetes Helm 安装、外接 Ceph S3、阿里 OSS、腾讯 COS),并强调 “软删除”只是元数据打标,“硬删除”才是物理块回收,否则会被追问“为什么删除镜像后磁盘不降”。

知识点

  • OCI Distribution Spec:DELETE /v2/<name>/manifests/<digest> 仅删除 manifest,blob 仍存。
  • Harbor 元数据模型:project→repository→artifact→tag→manifest→blob,artifact 表有字段“delete=true”即软删除
  • 只读模式:GC 前必须 coreConfig.readOnly=true,防止并发推送导致 “误删刚上传未引用 blob” 的 race condition。
  • 标记阶段:GC 扫描 PostgreSQL,列出所有仍被 tag 指向的 manifest digest,再递归收集 blob 列表,得到 白名单
  • 清理阶段:遍历 Registry 存储,不在白名单的 blob 被物理删除;若使用 S3,底层调用 s3:DeleteObject;若使用 filesystem,则 os.Remove
  • 非阻塞 GC:Harbor 2.5+ 支持 “无停机 GC”,通过 Redis 分布式锁保证同一时刻仅单实例 GC,且推送请求会被短暂重试,无需全站停服
  • 回滚能力:GC 默认 dryRun=true,可先观察待删 blob 列表;生产建议先 harbor-gc-job --dry-run,确认无误后关闭只读再真正执行。
  • 国内云厂商差异
    – 阿里云 OSS 开启版本控制后,GC 删除的是 “当前版本”,历史版本仍占空间,需在桶生命周期规则里再清“过期删除标记”。
    – 腾讯 COS 如启用多 AZ,删除后 存储量延迟 24h 更新,需向面试官说明“账单未立即下降属正常现象”。

答案

Harbor 的 GC 流程严格区分为 软删除硬删除 两个阶段,目的在保证 数据一致性与空间最终回收 之间取得平衡。

  1. 软删除(Soft Deletion)
    a. 用户通过 Portal、CLI 或 CI 调用 DELETE /v2/<repo>/manifests/<digest>
    b. Harbor core 服务把 artifact 表对应记录的 “delete=true” 字段置位,同时删除 tag 记录,但 Registry 侧的 manifest 与 blob 文件原封不动
    c. 此时镜像在 UI 消失,磁盘占用不变;若用户立即重新推送同名 tag,Harbor 会新建 artifact 记录并复用已存 blob(内容寻址),实现 秒级回滚

  2. 硬删除(Hard Deletion)
    a. 管理员触发 GC(手动 Job 或定时 Cron),Harbor 会:
    – 将系统切为 只读模式(老版本需停机,2.5+ 通过分布式锁实现无中断)。
    – 扫描 PostgreSQL,汇总所有仍被 tag 指向的 manifest digest,再递归收集其引用的 blob,形成 “存活白名单”
    b. 进入清理阶段:
    – 遍历 Registry 存储(filesystem 或 S3 接口),凡 blob 不在白名单即物理删除
    – 若启用镜像复制,GC 会跳过 “复制策略仍引用的 blob”,防止 异地节点同步失败
    c. 清理完成后,Harbor 生成 GC 报告:已删 blob 数、释放空间大小、耗时、失败项;管理员可下载日志并关闭只读模式。

一句话总结:软删除只改 Harbor 元数据,硬删除才真正释放底层存储块;生产环境务必先 dry-run、确认无异常后再执行,避免 “误删共享层” 导致其他镜像损坏。

拓展思考

  • 并发安全:国内大厂镜像量常达 PB 级,GC 耗时数小时;若推送与 GC 并行,可能出现 “blob 上传完成但 manifest 未写” 的中间态,导致 GC 误删。Harbor 2.5+ 通过 Redis 分布式锁 + 上传会话标记 解决,面试可补充“分布式锁键值:harbor:gc:lock,TTL=gc_timeout+grace_period”。
  • 增量 GC 与全量 GC:Harbor 默认全量扫描,O(n) 耗时;社区已提出 “增量 GC” 方案,仅扫描 delete=true 的 artifact,降低 80% 耗时,适合 晚高峰不停服 的国内互联网场景。
  • 跨云一致性:若 Harbor 后端使用 Ceph RGW 双活,GC 需保证 “同一时刻仅单集群清理”,否则可能出现 “一边删一边被另一个集群复写” 的冲突;可借助 Ceph 的 bi-directional bucket replication + gc 锁表 实现。
  • 合规审计:金融客户要求 “删除可回溯”,可在 GC 前将待删 blob 列表写入 Kafka 审计队列,由合规系统归档至 Hive 表,实现 “已清理但可审计” 的国内监管需求。