「拉镜像慢 / 总超时」常见长什么样?
在本地开发、CI 与边缘节点上,Docker 与 containerd 拉取镜像时,很多人遇到过:进度条卡在某一层、TLS handshake timeout、unexpected EOF,或长时间重试后仍失败。
这类问题很容易被简单归因成「网络太差」或「节点挂了」,于是不断换机场、换 DNS,却收效甚微。更常见的原因是拉镜像的流量没有走对出口:要么该走代理的境外仓库仍在直连,要么不该走代理的内网或国内镜像站被误送进隧道,延迟与路径都被打乱。
本文从 Clash / mihomo 的分流规则与策略组出发,给镜像仓库相关域名单独一条「车道」,与「AI 网站分流」同为开发者向场景,但聚焦容器镜像与 Registry 主机名,落地步骤与《AI 网站分流》并列参考。字段级 YAML 仍以《YAML 配置深度解析》为准。
为什么「全局代理」常常不适合拉镜像
把系统代理或 TUN 设成「所有 TCP 都走一个节点」时,最容易出问题的是两类误伤。
第一类是内网与公司私有 Registry。若镜像地址解析在公司内网或专线网段,却被全局策略送去境外节点,轻则极慢,重则完全不可达。第二类是国内镜像加速站。若本应直连的镜像站被错误代理,可能绕远路、增加握手失败概率,或触发与节点地区不一致的访问策略。
反过来,若你只有「全局直连」或「仅浏览器走代理」,而 Docker 客户端并不走系统代理,那么访问 Docker Hub 等境外仓库时,仍可能表现为直连超时——这时需要分流规则与客户端如何接入代理两件事一起解决,而不是只改一个开关。
若你已在 /etc/docker/daemon.json 配置了 registry-mirrors,请把「镜像站域名」一并纳入分流思路:Clash 决定的是连接走哪条出口,镜像站配置决定的是向哪个主机拉取,两者互补。
常见镜像仓库域名:别只写 docker.io
一次完整的 docker pull 往往涉及多个主机名:认证、清单层、Blob 存储、CDN 边缘都可能不同。只写 docker.io 有时仍会被其它子域命中宽泛规则。
实务上建议在维护配置时,至少覆盖以下常见目标(按你实际使用的仓库增删):docker.io、registry-1.docker.io、auth.docker.io、production.cloudflare.docker.com、hub.docker.com;GitHub 容器镜像常用 ghcr.io;Google 常用 gcr.io、*.gcr.io、k8s.gcr.io(历史场景)、registry.k8s.io;微软常用 mcr.microsoft.com;Red Hat 生态常见 quay.io。
若你使用国内镜像站或云厂商提供的加速域名,请把这些域名显式放在直连或国内策略组,并放在「过于宽泛的 GEOIP / MATCH」之前,避免被提前截走。具体写法仍遵循 rules 自上而下匹配,第一条命中的规则胜出。顺序与优先级详见YAML 篇中的规则章节。
策略组与规则示例:DOCKER-REGISTRY
建议为镜像仓库单独建一个策略组(例如命名为 DOCKER-REGISTRY),在组内固定你验证过稳定的节点,或放在 fallback 组里做故障转移。下面是一段示意性片段,组名与域名需按你的订阅与地区替换:
proxy-groups:
- name: DOCKER-REGISTRY
type: select
proxies:
- YOUR-STABLE-NODE
- PROXY
rules:
- DOMAIN-SUFFIX,docker.io,DOCKER-REGISTRY
- DOMAIN-SUFFIX,docker.com,DOCKER-REGISTRY
- DOMAIN-SUFFIX,ghcr.io,DOCKER-REGISTRY
- DOMAIN-SUFFIX,gcr.io,DOCKER-REGISTRY
- DOMAIN-SUFFIX,mcr.microsoft.com,DOCKER-REGISTRY
- DOMAIN-SUFFIX,quay.io,DOCKER-REGISTRY
- DOMAIN-SUFFIX,registry.k8s.io,DOCKER-REGISTRY
- DOMAIN-SUFFIX,your-internal-registry.corp,DIRECT
注意:DOMAIN-KEYWORD 容易过宽,误伤无关站点,除非你很清楚范围。更稳妥的是用 DOMAIN-SUFFIX 与 rule-providers 维护列表。若使用远程规则集,请确认其中镜像相关域名是否已覆盖,否则仍可能被 MATCH 提前导向错误组。
Docker 客户端如何「吃到」Clash 的代理
仅有分流规则是不够的:若 Docker 引擎发出的连接根本不经过 Clash,规则不会生效。常见接入方式有三类。
第一类是系统代理 / TUN。在 TUN 模式下,若路由与 DNS 正确接管,容器引擎流量通常更容易被规则命中;若仍异常,可对照《Windows TUN 路由与防火墙排查》检查是否与本机其它 VPN、防火墙或跃点冲突。
第二类是为 Docker 显式设置 HTTP(S) 代理。在 Linux 上可通过 systemd drop-in 或环境变量为 dockerd 或客户端工具设置 HTTP_PROXY / HTTPS_PROXY,并配合 NO_PROXY 排除内网段与公司私有 Registry。请避免把内网地址写进必须走代理的列表。
第三类是Docker Desktop(Windows / macOS)。图形界面里可配置代理指向本机 Clash 的混合端口;同时仍建议在 Clash 侧用分流规则与直连把国内镜像与内网域名排除在外,避免「双重绕路」。
DNS 与 Fake-IP:和「半代理」同样相关
镜像拉取失败有时表现为「DNS 解析到了错误地区」或「解析与连接路径不一致」。在 mihomo 系内核下,常见做法是通过 Fake-IP 与 nameserver-policy 等机制,让需要代理的域名在内核侧一致处理。字段清单与防泄漏步骤请直接对照YAML 教程中的 DNS 章节与文档中的 YAML 与 DNS 说明。
若你在改完规则后仍遇到偶发超时,可优先检查:镜像相关域名是否误进 fake-ip-filter、是否与本地其它 DNS 工具链冲突,以及切换 TUN 与系统代理后是否残留旧缓存。
CI、内网与「开发者代理」场景
在 GitHub Actions、GitLab CI 或自建 Runner 上,拉镜像往往比桌面环境更「脆」:超时阈值更短、并发更高、且常混用公网与私有镜像。此时分流规则的价值在于:让公网仓库走稳定出口,让私有 Registry 与内网依赖保持直连,避免全局代理干扰构建链路。
若 Runner 在内网,请把内网网段、私有域名与镜像站放在 DIRECT 或专用策略组,并在 NO_PROXY 中同步维护。与 AI 编程工具链类似,开发者代理的目标始终是让每一类流量走它该走的那条路,而不是把一切都塞进同一个节点。
如何验证「拉镜像真的走对了组」
不要用「能 ping 通」作为唯一标准。更可靠的方式是在复现问题时打开客户端连接日志,观察:与镜像层下载相关的请求是否命中 DOCKER-REGISTRY(或你命名的组),是否出现意外的 DIRECT 或错误组。
同时请避免在同一台机器上混用多套代理工具争抢系统代理;若浏览器扩展只改写部分请求,也会与 Clash 的规则命中打架,让你误以为是配置文件写错。
合规与镜像站条款
各镜像站与 Registry 服务商对访问来源、带宽与用途可能有明确规定。本文仅讨论本地网络路径与代理配置的技术思路,不构成对任何服务条款的规避建议。请在你有权使用的网络环境与账号前提下操作,并自行承担合规风险。
结语
Docker 拉镜像慢或总超时,很多时候不是单一节点问题,而是镜像仓库域名、出口策略与客户端接入方式没有同时对齐。为 Registry 单独建策略组、把相关域名规则放在合适顺序、再与 TUN / 环境变量 / 镜像站配置形成闭环,通常比盲目堆节点更有效。
相比在论坛零散搜报错文案,用一款能看清规则命中与连接日志的客户端会省大量时间。若你尚未安装或希望与教程保持同一套界面习惯,可从客户端下载页获取当前系统对应版本;更多主题见博客索引。→ 立即免费下载 Clash,开启流畅上网新体验