← yygy1976笔记
Self-hosted

Docker 拉取慢,最后靠什么解决

2026 · 10Docker · NAS

拉一个镜像要等十分钟,还经常中途 unexpected EOF。第一反应是换镜像源——但这条路这两年越走越窄。

公共加速源的问题

能用的越来越少,能用的也不稳:有些只代理部分仓库,有些对大镜像限速,还有些今天能拉明天 404。挨个试一圈,等于把不确定性搬进依赖链里。

更麻烦的是:失效是静默的。镜像源挂了不会报"源已挂",只会一直超时,让人以为是网络问题。

换个思路:本地缓存一层

在 NAS 上跑一个 pull-through cache(registry:2 的 proxy 模式),所有拉取先过它:

docker pull 镜像
   ↓
本地 registry(缓存命中就直接给)
   ↓ 未命中才回源
上游 registry

第一次拉还是慢,但同一个镜像第二次、第三次就是本地速度。多台机器共用一份缓存,收益更大。

四个坑

  1. proxy 模式不是"自动把所有域名都代理" —— 一个实例只绑定一个上游(Docker Hub / ghcr / quay 各要一个)。
  2. 要开 delete 才能清理 —— 缓存只增不减,磁盘迟早满。删 blob 和删 manifest 是两回事,顺序错了会留下孤儿。
  3. HTTP 与 HTTPS 的信任链 —— 内网走明文要配 insecure-registries,公网走自签要导 CA,否则 docker 直接拒绝。
  4. 看门狗比缓存本身重要 —— 缓存进程挂了,所有拉取一起挂。必须有个自愈,且自愈脚本要能在缓存不可用时让客户端回落到直连,而不是一起死。

结果

重复拉取从分钟级降到秒级,跨机器共享同一份层。代价是多了一个要维护的组件——所以要配自愈,不然它就成了新的单点。

这类改造的判断标准很简单:它坏了会不会让原来能用的东西不能用? 会的话,必须先有回退路径再上线。