ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Docker国内镜像加速源最新实测:配置、验证与失效排查指南

Docker国内镜像加速源最新实测:配置、验证与失效排查指南 前几天一个做运维的朋友跟我吐槽他们测试环境一直用的那个 Docker 镜像加速域名突然超时几十台机器拉镜像全部卡住。他翻出去年收藏的“国内镜像源加速列表”挨个试结果一大半不是解析失败就是证书过期。我在电话里听他报完那串地址心里大概就有数了这个列表又该重新验证了。9月12日我花了将近两个小时把市面上能想到、能找到的镜像源全部拉了一遍整理成下面这份更新顺带把配置步骤、验证方法、失效排查完整过了一遍。这篇内容适合谁刚装完 Docker 但每次 pull 镜像都像断网的新手可以照着配置完直接上手已经配置过加速列表、但被镜像源失效坑过不止一次的老手重点看第五节的自测脚本和第六节的兜底方案。顺便说一句加速列表这种内容不是写一次就能用一年的公共镜像源受链路、成本、运营方策略影响失效速度远比想象中快所以我才会在标题里强调“9月12日更新”。1. 镜像加速源为什么每年都要重新验证1.1 加速源的本质给 Docker Hub 做一层国内分发缓存Docker 默认是从registry-1.docker.io也就是 Docker Hub 拉取镜像的。这个地址不在国内直连质量长期以来都不稳定高峰期经常出现连接超时、下载到一半断流、报 TLS 握手失败之类的问题。为了解决这个问题才有了“镜像加速器”这个角色。往深一层说镜像加速器本身也是一个容器镜像仓库宿主机上的 Docker daemon 配置了registry-mirrors之后拉镜像时不会直接找 Docker Hub而是先找配置好的加速源。加速源如果已经缓存了你需要的镜像层就直接分发给你速度很快如果没缓存它会向后端的 Docker Hub 回源拉取拉完再传给你同时自己留一份缓存供后续请求使用。这个过程和 CDN 的逻辑高度相似它并没有在协议层做任何“特殊处理”就是标准的 Docker Registry v2 行为。理解了这一点就能想明白很多现象为什么同一个加速源拉热门镜像飞快拉一个冷门 tag 却很慢甚至直接失败大概率就是冷门镜像没有被缓存过回源链路又没通。1.2 你去年收藏的列表是怎么一步步失效的这些年我观察下来镜像加速源失效基本离不开三件事。第一是成本。镜像流量非常夸张一个大厂级别的加速源如果对全网免费开放每天流量成本是普通人难以承受的。很多早期公益项目做着做着就发现钱包撑不住只能关停或者转入内网。第二是运营方策略调整。一些云厂商过去开放个人免费加速地址后来逐步收敛为企业服务老地址就悄无声息地终止解析还有一部分高校镜像源出于负载压力和运维成本考虑不再向校外用户开放 Docker Hub 加速能力。第三是证书和域名问题。镜像加速依赖 HTTPS证书过期没人续、域名到期没人管、源站 IP 被攻击后临时下线这些情况我都实际遇到过。所以我对加速列表的态度是它是一份“当前时刻的体检报告”不是“永久保险”。你可以把这份列表当作起点但千万不要把它当成一劳永逸的答案。2. 9月12日实测的可用镜像源参考表2.1 我的筛选标准这次验证我没有把所有听说过的地址都塞进列表而是按下面几个原则筛能用 HTTPS 访问的优先于 HTTP除非那个 HTTP 源是云厂商明确提供的内部地址。直接访问/v2/接口能返回有效响应说明 Registry 服务本身在线。不只测连通性还要真的拉一个 100MB 左右的镜像因为有些源虽然网页能访问但 Docker 客户端一拉就重置连接。第三方公益地址单独归一类不推荐作为生产环境唯一依赖。2.2 当前实测能用的地址列表先说明这批地址只代表我发稿当天的测试结果任何一条都可能在未来某个时间失效。你使用之前强烈建议先跑一遍第五节给出的自测脚本。类别提供方地址实测情况与备注云厂商专属阿里云登录控制台获取专属地址类似https://xxxx.mirror.aliyuncs.com稳定个人账号可开通推荐作为主力源云厂商内网腾讯云http://mirror.ccs.tencentyun.com只在腾讯云机器内网环境测试过效果很好但公网基本不通公共服务DaoCloudhttps://docker.m.daocloud.io实测可拉取 nginx、mysql 等常见镜像偶发限流公共服务百度智能云https://mirror.baidubce.com连通性和拉取速度都算稳定可作为备用公共服务网易数帆http://hub-mirror.c.163.com老牌源HTTPS 支持一般我这边实测偶发超时社区公益1Panelhttps://docker.1panel.live作为应急源测试可用建议自行验证后使用社区公益1mshttps://docker.1ms.run同上速度浮动较大适合备用2.3 第三方公共源和“自己账号专属源”怎么取舍如果你有阿里云账号我强烈建议把阿里云控制台分配的专属地址作为第一优先级。道理很简单专属地址的可用性比公共地址可控即使哪天公共公共服务收紧至少账号内的配置大概率能保持兼容。第三方公益地址不是不能用而是你要有一个清醒的认知它可能随时停止服务而且你无法控制它内部的缓存策略。之前有同事在容器环境里用了某个小型公益源拉一个内部小团队上传的私有镜像直接报manifest unknown后来才知道那个源根本没有回源能力只能分发预先缓存过的公共镜像。这类问题不是个例所以后面我会专门讲如何配置“多源容灾”和“自建仓库”。3. Linux 上配置镜像加速列表的完整操作3.1 找对 daemon.json 的位置再动手Linux 下 Docker daemon 的配置文件一般在/etc/docker/daemon.json不存在就自己创建一个。如果你是 rootless 模式运行 Docker路径会变成~/.config/docker/daemon.json别改错地方否则docker info里永远看不到你配置的加速源。标准配置如下{ registry-mirrors: [ https://docker.m.daocloud.io, https://mirror.baidubce.com, https://docker.1panel.live ] }这里有个很重要的细节数组里的顺序就是 Docker daemon 尝试的优先级。它并不是“第一个不行自动换第二个”的负载均衡而是一个失败转移到下一个的机制。如果第一个源本身能连上但返回数据很慢Docker 不会因为速度慢就自动切换只会一直等等到超时失败才轮到下一个。所以平时应该把网络里速度最快、最稳定的源放在最前面。3.2 重启 Docker 并验证别忽略生产环境风险改完配置后执行sudo systemctl daemon-reload sudo systemctl restart docker docker infodocker info输出中会看到类似下面的内容说明配置已经生效Registry Mirrors: https://docker.m.daocloud.io/ https://mirror.baidubce.com/再顺手拉一个镜像测试docker pull nginx:1.27-alpine这里我想重点提醒一下生产环境的坑systemctl restart docker会把当前机器上的所有容器全部停掉再拉起。如果很多容器没有设置restart: always或--restartunless-stopped重启后这些容器不会自动恢复业务直接中断。所以真正线上机器要动 Docker 之前先docker ps看一眼有哪些容器在跑评估一下重启影响最好提前排出维护窗口再执行这段命令。3.3 Rootless 模式和 Kubernetes 场景下的注意点Rootless 模式下配置路径是~/.config/docker/daemon.json修改后同样重载 daemon。如果重启遇到没生效先确认docker context ls当前用的是哪个 context然后再检查对应的 daemon 配置在哪。Kubernetes 节点上用 containerd 比较多和 Docker 的配置不是一回事。containerd 的镜像加速需要改/etc/containerd/config.toml在[plugins.io.containerd.grpc.v1.cri.registry.mirrors]下面配置 endpoint。标题虽然是“Docker 国内镜像源”但实际工作中很多人是在 K8s 集群里遇到拉镜像问题所以顺手提一句如果你的节点是 containerd别照抄 Docker 的 daemon.json。4. Docker Desktop / Windows / macOS 的图形化配置与避坑4.1 用 Docker Desktop 的 Settings 编辑别跟 WSL2 里的配置混淆Windows 或 macOS 上使用 Docker Desktop 时最简单的做法是打开 Settings找到 Docker Engine 页面在右侧 JSON 编辑框里加入registry-mirrors字段{ registry-mirrors: [ https://docker.m.daocloud.io, https://mirror.baidubce.com, https://docker.1panel.live ] }点 Apply RestartDocker Desktop 会自动重启引擎。这里要单独说一个常见混淆场景。很多人电脑上同时装了 Docker Desktop 和 WSL2又在 WSL2 的 Linux 发行版里手动安装了 Docker Engine。结果 Docker Desktop 接管了基于 WSL2 的docker-desktop发行版你在普通发行版里改的/etc/docker/daemon.json实际管的是另一个 Docker daemon两边根本不是一套体系。判断方法很简单终端执行docker context ls docker context show如果当前 context 是desktop-linux那就以 Docker Desktop 里的设置为准不要在 WSL2 里瞎改。如果你就是想用 WSL2 里自己安装的 Docker Engine那需要先把当前 context 切到对应引擎配置否则改了也白改。4.2 保存后立刻验证JSON 写错会导致引擎启动失败Docker Desktop 里保存配置后如果 JSON 格式写错引擎会启动失败图形界面会直接报错。这种时候别慌点开 Docker Engine 页面把 JSON 修复回去就行。我这里给一个排查小技巧保存前先把 JSON 内容复制到任何在线校验工具或本地编辑器里检查一下逗号、引号、括号多一个少一个都会出问题。验证是否生效同样用docker info。如果你在图形界面里已经看到了 Registry Mirrors 列表但命令行里执行docker info没有显示大概率是当前 shell 连接的 context 不是 desktop-linux切一下 context 或者重开终端。4.3 软件源缓存残留导致的“假失败”Windows 和 macOS 用户还容易遇到一个现象之前用某个加速源拉了一半失败留下了一堆未完成的镜像层缓存。换新源之后再拉同一个镜像有时会莫名报错但又不像是源的问题。解决办法是先清理孤立的缓存层docker system prune -af docker builder prune -af然后再拉镜像。这个方法能排除很多“假失败”比反复换源更管用。5. 五分钟自测脚本找到最适合你网络的源5.1 连通性检测脚本不同运营商、不同地域访问同一个镜像源速度差异可能非常大。北京联通访问快的源深圳电信访问不一定快。所以最好的方式不是照抄别人的优先级而是自己跑一遍下面的脚本#!/usr/bin/env bash mirrors( https://docker.m.daocloud.io https://mirror.baidubce.com https://docker.1panel.live https://docker.1ms.run http://hub-mirror.c.163.com ) for m in ${mirrors[]}; do start$(date %s) code$(curl -o /dev/null -s -m 10 -w %{http_code} $m/v2/) end$(date %s) echo $code $((end - start))s $m done这个脚本的原理很直接Registry v2 协议规定访问/v2/接口时无论服务是否需要认证只要返回码是200或者401都说明这个服务是活的。401并不代表不可用而是代表它要求认证但服务进程本身在线。返回000基本就是连接失败或者超时。5.2 用真实镜像做拉取压测连通性不等于实际拉取速度。有些源能返回200但一拉大镜像就断流。所以我还会做一轮真实拉取测试time docker pull nginx:1.27-alpine docker rmi nginx:1.27-alpine time docker pull mysql:8.0time会输出整个拉取过程消耗的时间通过时间长短能直观比较不同源的表现。也可以直接指定镜像源前缀测试某一个源的回源能力例如time docker pull docker.m.daocloud.io/library/nginx:1.27-alpine这种方式能跳过全局镜像配置单独验证某一个源的吞吐量。从“能用”到“好用”的判断标准我给一个参考拉一个 100MB 左右的镜像总耗时在 10 秒以内基本算好源20 秒以上说明链路一般可以留着当备用超过 1 分钟还没拉完就别指望它能扛住生产环境流量了。5.3 同一套配置在不同网络的差异实例我这边做完这轮测试后主用源和备用源并不是同一个。公司在北方某机房的物理机上DaoCloud 源速度明显快而我在本地家里的电信宽带环境里百度源速度更好。所以我最后的做法是不同环境各自跑一遍脚本按照输出结果重新排列registry-mirrors数组顺序。有些人可能会说“我测出来最快的源到了生产环境未必快”这是对的。网络路径、运营商互通、源站负载都是变量。所以我才特意强调“五分钟自测”而不是“抄完就完”目的就是让你掌握根据结果快速调整配置的能力。6. 失效排查、自建私有仓库与供应链安全提醒6.1 常见报错信息对照表镜像源出问题时Docker 报错五花八门但归纳下来主要就这几类报错特征可能原因处理思路connection refused/timeout源站下线或本地网络无法到达运行第五节脚本换一个可用源403/429被源站限流或拒绝访问暂停片刻换备用源或改用账号专属源manifest unknown源没有缓存该镜像且无法回源换有完整回源能力的源或直接拉 Docker Hubx509: certificate signed by unknown authority地址是 HTTP或源站证书异常确认地址是否建议用 HTTP不要盲目加 insecureTLS handshake timeout链路上 TLS 被重置或源站性能不足换 HTTPS 源或换时间段重试特别提醒manifest unknown是最容易误判的。很多人以为是加速源挂了其实是加速源本身只支持缓存不支持回源而你要拉的那个冷门镜像在它那里没有缓存。这种时候再去测连通性毫无意义直接换一个支持完整回源的源或者改用云厂商专属加速器。另外不要看到x509错误就顺手把地址加到insecure-registries。这个配置等于告诉 Docker 跳过 TLS 证书校验非加密链路下镜像内容存在被篡改的风险。除非你自己搭的私有仓库明确跑在 HTTP 上否则不建议为公共镜像源开这个口子。6.2 生产环境别全押公共源自建仓库是更稳的后手公共镜像源再稳定终究是别人的服务。如果你所在的公司或团队经常批量部署容器我更建议花点时间搭一套私有镜像仓库比如 Harbor。做法是选一台内网机器安装 Harbor日常部署时统一从内网仓库拉镜像只有构建镜像时才从外网同步数据。同步工具有很多我用得比较多的是 skopeo。一条命令就能从 Docker Hub 把镜像复制到私有仓库skopeo copy \ --dest-creds admin:your-password \ --src-creds dockerhub-user:dockerhub-passwd \ docker://docker.io/library/nginx:1.27-alpine \ docker://registry.example.com/library/nginx:1.27-alpine内网环境拉镜像的速度远高于任何公网加速源而且完全不受外部源失效影响。配合定时任务周期同步常用镜像就可以把“依赖公共镜像源”变成“依赖自己的基础设施”。如果你暂时没有精力和资源自建仓库至少要做到关键环境不把某一个第三方公益源作为唯一依赖配置里留两个备用源同时定期跑一遍自测脚本提前发现失效苗头。6.3 从公共源拉镜像别忘了做完整性校验用公共镜像源最大的隐患不是慢而是你无法确定这个源分发给你的镜像是原封不动的官方镜像。社区公益源的管理水平参差不齐理论上存在镜像被替换或篡改的可能。一个最基本的校验手段是比对镜像 digest。先从 Docker Hub 官方页面查到该 tag 的 digest再从加速源拉下来后执行docker inspect --format {{index .RepoDigests 0}} nginx:1.27-alpine输出结果中会包含一个sha256:...摘要和官方 digest 对得上说明镜像内容一致对不上说明这个源提供的镜像和官方版本有差异这时候宁可不用这个源也不要冒险继续用。我现在的习惯是常用镜像尽量固定 tag 并按 digest 记录在部署脚本里而不是盲目写:latest。这样即使哪天源被污染、或者 Docker Hub 上的 tag 被强制覆盖部署时也能第一时间感知到版本差异不会在无意识状态下把不安全的镜像推上生产环境。说实话镜像加速这件事看着简单但最近一两年变化非常多公共免费源少了一批又一批企业级和不求人方案之间的选择越来越多。我自己的习惯是每个环境固定一个主要源再放两三个备用源平时备用源完全不干扰主流程但每隔一段时间就主动测一次确保关键时刻顶得上。如果你也被拉镜像卡得焦头烂额别急着到处复制粘贴别人的配置先跑一遍第五节的脚本把你当前网络环境里真正可用的源选出来再照着配置改大概率一次就能解决问题。
返回列表