跳转至

ghcr.io 慢速排查交接 & 内网镜像方案(Harbor)

用途:把「旁路代理为何只有 ~11 KiB/s」的排查移交到专门处理代理的对话执行; 本文件同时给出内网镜像仓库(Harbor)方案的改动面评估。 生成时间:2026-10-01 | 主题目录:ghcr-slow-20261001/


一、已经确认的事实(请勿重复取证)

2026-10-01 在 4 台 k8s 节点(.10/.13/.14/.15)实测,取值一致:

观察点 结果
默认网关 192.168.31.2(即旁路路由,在生效)
DNS 192.168.31.2;ghcr.io → 198.18.0.107(Clash fake-ip 段)
curl https://ghcr.io/v2/ http=401(未认证的正常响应 → TLS/HTTP 全通)
ctr -n k8s.io images pull ghcr.io/jkroepke/kube-webhook-certgen:1.8.8 成功,但 1.0 MiB / 89.8 s ≈ 11.5 KiB/s
存量镜像 节点上已有 cnpg / headlamp / mariadb-operator 等 ghcr 镜像,Pod 全 Running

结论:不是「不可达」,是极慢。慢到把 helm --timeout 撞死,导致历史上被记成 「集群侧 ghcr.io 不可达」,并固化成 helm upgrade 必须加 --no-hooks 的永久约束。

已排除:节点路由、DNS 解析、TLS 握手、ghcr.io 侧可用性(换节点取值完全一致)。

未查:为什么只有 11.5 KiB/s —— 这就是本文档第一节要移交的内容。


二、移交给「代理排查对话」的待查清单

排查对象主机:192.168.31.2(OpenWrt,旁挂香港 129.226.138.204,同时承担 4 台 k8s 节点的网关与 DNS)。

# 要查什么 建议命令 / 做法 判据与可能的结论
1 代理软件与版本 ps w \| grep -iE "clash\|mihomo\|sing-box\|openclash\|passwall\|ssrplus" ;OpenWrt 常见为 OpenClash 插件 确定是哪一个,决定后续查配置的路径
2 ghcr.io 命中的规则与出口节点 在代理面板/config.yaml 的 rules 里查 ghcr.io、github、geosite:github 命中哪个 proxy-group,再看该 group 当前选中节点 最可疑:可能命中了「慢节点」或「漏网直连」。换节点后重测是首要动作
3 出口实测带宽(不依赖 ghcr) 在 .2 上 curl -sS -o /dev/null -w "%{speed_download}\n" "https://speed.cloudflare.com/__down?bytes=10000000" 若通用测速也只有十几 KiB/s → 链路/节点整体问题;若很快 → 是 ghcr 这条规则或 fake-ip 路径的问题
4 是否有限速 / 流量整形 查 OpenWrt 的 SQM/QoS、tc qdisc show;查订阅节点是否有速率限制 区分「链路上限」与「人为限速」
5 fake-ip 段与过滤规则 确认 198.18.0.0/15 的分配方式;确认内网域名(.rainchen.top 等)是否排除在 fake-ip 之外 排除解析层干扰(目前看解析正常,属低优先级)
6 多节点对比 若有多个出口节点,逐个切换后各测一次第 3 项 给出「换节点能否解决」这一可执行结论
7 入向 vs 出向链路 确认 frps/frpc(香港 129.226.138.204)只做内网穿透入向,出向走的是哪条链路 明确拓扑,避免误把 frp 当正向代理

目标判据:把 ghcr.io 拉取速率提升到可用水平(建议目标 ≥ 500 KiB/s); 若确认已是物理上限,则明确写「不可修」,方案转向内网缓存(见第三节)。


三、结果回填契约(请在代理对话里按此产出)

结果写入路径:

/home/rain/Documents/k8s_ins/ghcr-slow-20261001/PROXY-FINDINGS.md

必备小节(顺序固定,便于本对话直接读取,不必我再全目录搜索):

  1. ## 1. 代理软件与版本
  2. ## 2. ghcr.io 命中规则与出口节点
  3. ## 3. 实测速率对比(改前 / 改后,注明测速方法与时间)
  4. ## 4. 是否存在限速或链路瓶颈
  5. ## 5. 结论(可修复 / 物理上限,二选一并给证据)
  6. ## 6. 已做的改动与回滚方式(若动过 .2 的配置)

约定: - 只写结论与关键证据,不要粘贴大段配置或日志全文; - 订阅链接、密码、UUID 等凭据一律脱敏,不得写入该文件; - 写完后把路径告诉我,我来读取并据此更新 HANDOFF / BASELINE。


四、内网镜像方案:Harbor 评估(改动面)

4.1 实测到的现状(2026-10-01)

项 现状 对方案的意义
containerd v2.3.5,config_path = "/etc/containerd/certs.d" 接入点已预留
/etc/containerd/certs.d/ 不存在 只需新建目录 + hosts.toml,不用改 config.toml、不用重启 containerd
k8s 节点 4 台(1 master + 3 node),containerd 均 active 改动落在 4 台上
StorageClass nfs-csi(默认) / nfs-csi-hdd / local-ssd Harbor 存储有现成落点
现有 Harbor 无 全新部署
现有镜像引用 多个工程硬编码 ghcr.io/...(deploy.yaml、helm values 等) 决定了能否「镜像名不变」

4.2 推荐形态:Harbor 代理缓存(proxy cache)

  • Harbor 建一个 project,名为 ghcr.io,类型选「代理缓存」,上游填 https://ghcr.io;
  • 各节点放一个 /etc/containerd/certs.d/ghcr.io/hosts.toml:
server = "https://192.168.31.x"        # Harbor 主机

[host."https://192.168.31.x"]
  capabilities = ["pull", "resolve"]
  skip_verify = false                   # 用自签 CA 时改为挂 CA 目录
  • 这样 ghcr.io/xxx 的镜像名完全不变,containerd 自动把请求打到 Harbor, 首次由 Harbor 代拉并缓存,之后内网直供。

4.3 改动面结论:对现有 k8s 工作负载零改动

层面 改动 量级
k8s 工作负载 / Pod 无(镜像名不变,不触发任何重建) 0
各部署工程的 values / deploy.yaml 无(沿用 ghcr.io/...) 0
4 台节点 各加 1 个目录 + 1 个 hosts.toml(+ 自签 CA,如用) 4 个文件
containerd 服务 不需重启(certs.d 按拉取时读取) 0
新建 Harbor 主机 1 台 VM:建议 2~4 vCPU / 4~8 GB / 100 GB+ 盘(Harbor 本体 + 缓存) 1 台
证书 内网可用自签 CA,或复用现有域名体系走内网 DNS 一次性
首次镜像入仓 用 skopeo copy 或 Harbor 自动代拉,无需逐台预热 一次性

4.4 必须提前知道的两条限制

  1. Harbor 不解决「首次拉取慢」:Harbor 自己也要经同一条链路出网。 若第二节排查结论是「物理上限、不可修」,则首次入库仍慢(但只需一次, 之后所有节点、所有重建都走内网,收益仍然很大)。
  2. Harbor 是新的单点:它挂了会影响新镜像拉取;已缓存的镜像在节点本地不受影响, 可用「节点 + Harbor」两级缓存缓解。

4.5 与「逐台预热镜像」的对比

逐台预热 Harbor 代理缓存
首次投入 小(现有节点各拉一次) 中(1 台 VM + 部署 + 证书)
新增镜像时 每台都要重来一遍 Harbor 自动代拉,节点无感
节点重建(如 k8s_136_cluster_deploy 重跑) 全部重来,且撞慢链路 内网直供,无外部依赖
对现有环境改动 0 4 个节点配置文件,工作负载 0
长期收益 一次性 持续

建议:两者不冲突。短期可先预热眼下要用的镜像解燃眉之急; 长期走 Harbor 代理缓存,把「海外拉取」变成一次性事件。


五、待决策

  • [ ] 代理排查结论是「可修」还是「物理上限」(等 PROXY-FINDINGS.md)
  • [ ] 若走 Harbor:主机放哪(新建 VM / 复用宿主 R620)?用什么域名与证书?
  • [ ] Harbor 与「预热」是否并行推进

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