跳转至

Harbor 内网镜像仓库 — 专项交接(需求规格书)

用途:把「内网镜像仓库」这件事整体移交到专门的 Harbor 对话执行;本文档是需求规格与 验收标准,不是操作步骤。执行方按此落地,结果回填到第 8 节约定路径。 生成时间:2026-10-01 | 主题目录:ghcr-slow-20261001/ 关联文档:PROXY-CHECK-AND-HARBOR.md(代理速率排查,另一条线,互不阻塞) 前提更新(2026-10-01):代理专项已复测并回填 PROXY-FINDINGS.md —— 4 台节点拉取 1.2–1.8 MiB/s(9 MiB 镜像 5–8 s),未复现历史卡住;本文档中「首次入库慢」的 相关表述以该文件为准。


1. 目标

一次彻底解决:让 k8s 集群拉取镜像不再依赖海外链路。 落地后应满足:新增镜像、节点重建、Pod 重调度都从内网 Harbor 取像,海外源只承担「首次入库」。

衡量成功的两条:① 镜像引用名零改动;② 节点重建不再受慢链路与 ghcr.io 超时影响。


2. 已确认的环境事实(2026-10-01 实测,请勿重复取证)

2.1 接入点已预留(这是改动量小的根本原因)

项 现状
containerd v2.3.5,4 台节点均 active
registry 配置 config_path = "/etc/containerd/certs.d"([config.toml 第 30-31 行])
/etc/containerd/certs.d/ 目录不存在 → 只需新建,不必改 config.toml、不必重启 containerd
sandbox 镜像 pinned_images.sandbox = registry.k8s.io/pause:3.10.2(同样走该 registry 配置)
节点 4 台:k8s-master-01(.10) + k8s-node-01~03(.13/.14/.15)
StorageClass nfs-csi(默认) / nfs-csi-hdd / local-ssd
现有 Harbor 无

2.2 镜像源分布(集群在跑容器的实际来源)

registry 容器数 性质 是否需纳管
registry.k8s.io 15 海外 是
quay.io 15 海外 是
registry.gitlab.com 11 海外(gitlab-org/build/cng/* 官方镜像) 是
docker.io 6 + 3 隐式 海外 是
ghcr.io 4 海外 是

合计约 49 个去重镜像条目;单节点 containerd 存储占用实测 15 GB(.13)。

2.3 宿主资源(R620,192.168.31.249)

项 现状 含义
CPU / 内存 32 核 / 117 GB(可用 68 GB) 资源充足
系统盘 /dev/sda3 220 G → /,余 53 GB 只放系统,不放 Harbor 数据
数据盘 /dev/sdb 1.8 T → /data,余 1.2 T Harbor 数据落这里(另有 /srv/nfs/k8s-hdd 余 482 G 可用作 NFS 后端)
磁盘类型 全机机械盘(HDD) 顺序读写百 MB/s 量级,对镜像缓存足够(远高于外网 1.8 MiB/s)
Docker 29.1.3,active 可承载 Harbor 的 compose 部署
KVM 13 台虚机在跑 宿主机负载可观

3. 需求规格(逐条可验收)

# 要求 说明
R1 镜像引用名零改动 各工程的 values / deploy.yaml / manifests 中的 ghcr.io/... 等一律不动,改由节点侧 mirror 完成
R2 覆盖 5 个上游源 ghcr.io、registry.k8s.io、quay.io、registry.gitlab.com、docker.io
R3 每个源一个代理缓存 project,project 名与 registry 域名完全一致 如 project 名 ghcr.io,使 containerd 请求路径 /v2/ghcr.io/<repo>/... 天然对齐,这是 R1 成立的前提
R4 节点接入不改 config.toml、不重启 containerd,不影响运行中 Pod 只新增 /etc/containerd/certs.d/<registry>/hosts.toml
R5 证书可用即可,且方案明确 内网自签 CA(需分发到 4 台节点)或复用现有域名体系;必须写明轮换方式
R6 幂等 重复执行零变更、零报错、全跳过
R7 可回滚 删除 hosts.toml 即回到直连;回滚步骤需实测过并写入 SOP
R8 Harbor 可观测 至少覆盖存活与缓存命中;可按现有 textfile → node_exporter:9100 路线接入(该路线不新增端口)
R9 交付 SOP.md + RUNBOOK.md 按工程规范八章结构;含备份台账(backup/README.md)
R10 存量镜像一次性入库 按第 2.2 节的 49 条清单预热;必须包含 helm hook 类镜像(如 ghcr.io/jkroepke/kube-webhook-certgen)—— 「按需代拉」不覆盖这个场景,不预热则 hook 首次仍会撞 --timeout
R11 凭据管理 Harbor admin 口令入 ~/.secrets/(600),不入交付物、不入文档、不打终端

4. 已知坑(务必先读,多数会直接影响成败)

# 坑 应对
K1 fake-ip 劫持内网域名:4 台节点 DNS 均为 192.168.31.2(OpenWrt/Clash),Harbor 若用域名访问,域名会被解析成 198.18.x.x fake-ip 而被代理劫持 → 内网不通 直接用 IP 访问最稳;若必须用域名,需在 Clash 的 fake-ip-filter 中排除该域名,并在节点 /etc/hosts 兜底
K2 ~~磁盘不足~~ 已澄清,不构成阻碍:系统盘虽仅余 53 GB,但数据盘 /dev/sdb(1.8 T)挂在 /data,余 1.2 T;/srv/nfs/k8s-hdd 另余 482 G Harbor 数据落 /data(VM 的 qcow2 放这里)。注意区分系统盘与数据盘,不要只看 /
K3 docker.io 路径不一致:镜像写作 redis:7.4-alpine(隐式 docker.io/library/),但实际 endpoint 是 registry-1.docker.io hosts.toml 建在 docker.io,Harbor project 名用 docker.io;另需处理 library/ 前缀差异
K4 registry.gitlab.com 是公网源(非集群内自建 GitLab),已确认镜像形如 gitlab-org/build/cng/* 纳入代理缓存,不要误判为内部源而排除
K5 首次入库需经海外链路,速率取决于代理链路质量(2026-10-01 复测正常:1.2–1.8 MiB/s;但曾观测到一次卡住,根因未证实) 仍建议一次做完(R10);若入库期间再次卡住,按 PROXY-FINDINGS.md 建议②冻结出口节点做单变量对比,不要凭单次样本下结论
K6 helm release 的 values 基线红线 若验证过程需要 helm upgrade,必须 -f <现场> -f <overlay>,只传 overlay 会触发全栈重建(已出过事故)
K7 集群内 GitLab Container Registry 是自建服务 不要把「拉 GitLab registry」绕进 Harbor 形成环;本次不涉及自建 registry 的改造

5. 部署形态(二选一,推荐 A)

方案 A:独立 VM(推荐) 方案 B:k8s 内 Helm 部署
与集群 解耦,Harbor 存活不依赖 k8s 耦合
存储/入口/证书 需自备(可挂 NFS) 复用 nfs-csi-hdd + Traefik + 现有证书体系
鸡生蛋风险 无 有(Harbor 镜像需先有;可用节点本地镜像导入)
建议 新建 KVM 虚机(如 4 vCPU / 8 GB / ≥150 GB 盘) 仅在磁盘确实解决不了时选

磁盘已不构成阻碍(见 K2):Harbor 数据落 /data(余 1.2 T)即可开工。


6. 实施要求(工程纪律)

  • 幂等 + 备份 + 回滚:按全局变更规范,改动前备份登记 backup/README.md;
  • 三态判定:节点探测区分 done / pending / unknown,unknown 一律中止(「查不到」≠「没有」);
  • 高危标记:修改 containerd 配置目录、重启服务、删除镜像均属高危,须醒目记录;
  • 失败阈值:同一逻辑连续失败 2 次即停,不得换参数重试绕过;
  • 分批:4 台节点分批推进,达阈值即停并回滚本批;
  • 验证走 stdin 不落盘:分发脚本优先 ssh <host> 'python3 -' < script.py。

7. 验收标准(必须逐条实测并记录证据)

# 验收项 判据
A1 缓存命中后的拉取速度 任一节点 ctr -n k8s.io images pull <某 ghcr 镜像>:≥ 1 MiB/s、耗时 ≤ 60 s
A2 确实走 Harbor(而非直连) Harbor 访问日志/缓存命中计数增长,或临时阻断出网后仍能拉
A3 现有负载无扰动 全部 Pod 无重建、无 ImagePullBackOff;kubectl get pods -A 前后一致
A4 hook 镜像可从 Harbor 快速取用 对 hook 镜像验证:Harbor 命中后拉取 ≤ 5 s。注意:--no-hooks 是否去掉是独立决策,当前决定保留(见 BASELINE:代理按延迟选路,首次/新版本拉取仍可能遇低带宽节点)。不要因本项而擅自修改部署工程的 helm 调用
A5 幂等 二次执行:零变更、全跳过
A6 回滚可用 删除 hosts.toml 后确认回到直连(curl 验证),再恢复
A7 5 个源全覆盖 每个 registry 各拉 1 个镜像验证命中

8. 结果回填契约

结果写入路径:

/home/rain/Documents/k8s_ins/ghcr-slow-20261001/HARBOR-RESULT.md

必备小节(顺序固定):

  1. ## 1. 部署形态与主机(含 IP、资源、存储方案)
  2. ## 2. 实际改动清单(逐文件、逐节点,含含 K1/K3 的处理方式)
  3. ## 3. 证书方案与轮换方式
  4. ## 4. registry → Harbor project 映射表(5 个源)
  5. ## 5. 存量镜像入库清单与容量占用(实际 GB)
  6. ## 6. 验收结果(逐条对 A1~A7,附证据)
  7. ## 7. 遇到的问题与绕过方式
  8. ## 8. 回滚方式(已实测)
  9. ## 9. 遗留项与后续建议

约定:只写结论与关键证据;Harbor 口令、CA 私钥等凭据一律脱敏,只写存放路径; 写完后把路径告知,本对话据此更新 HANDOFF.md / BASELINE.md。


9. 边界(本次不做)

  • ❌ 不改任何业务工程的镜像引用与 helm values(R1 的意义就在于此)
  • ❌ 不动现有 helm release(除非 A4 验证,且必须带现场 values 基线)
  • ❌ 不删除节点上现有镜像(保留作回滚与降级)
  • ❌ 不改造集群内自建的 GitLab Container Registry
  • ❌ 不把凭据写入交付物目录
  • ⏸ 代理速率排查是另一条线(见 PROXY-CHECK-AND-HARBOR.md),本次不阻塞、不代办

10. 与另一条线的关系

代理速率排查 Harbor 专项
解决什么 首次入库慢(以及所有海外依赖的通用问题) 重复拉取与外部依赖的运行时风险
谁做 专门的代理对话 专门的 Harbor 对话
关系 互不阻塞;Harbor 在代理未修好时也能落地(只是首次慢一次) —

来源:/home/rain/Documents/k8s_ins/ghcr-slow-20261001/HARBOR-HANDOFF.md | 最后更新:2026-10-01 02:32(由 build/sync.py 同步,请勿在站点侧修改)