如果你用过 Docker,一定遇到过这种场景:一条docker pull nginx:latest敲下去,进度条在Waiting和Retrying
之间来回跳,甚至卡在 “pull access denied” 或 “i/o timeout” 上半天没反应。这不是你机器的问题,也不是 Docker 没装好,而是默认的 Docker Hub 镜像仓库在国内网络环境下访问确实不稳定。国内镜像源加速列表就是为了解决这个痛点,把下载请求从跨境链路迁移到国内节点,让镜像能在正常速度下拉下来。
这篇文章整理了一份截至 2026 年 9 月 8 日仍值得尝试的 Docker 国内镜像源清单,并给出从配置到验证、排错的完整流程。适合正准备摆脱docker pull
超时折磨的开发者、运维,也适合刚接触 Docker、想知道怎么配镜像加速的新手。看完你不仅知道该填哪个地址,还能明白它背后是怎么工作的,遇到失效时也知道怎么快速切源。
1. 为什么你需要一份国内镜像源加速列表
1.1 Docker Hub 直连到底慢在哪
1.1 Docker Hub 直连到底慢在哪
Docker 拉取镜像并不是简单地从一个文件服务器下载一个压缩包。它的镜像由一层一层的只读层组成,Docker 客户端先去 Registry 获取 manifest 文件,再根据 manifest 里的指引去下载各个层(blob)。层数量少则几个,多则几十个,每个层的大小也从几 MB 到几个 GB 不等。
Docker Hub 的实际仓库地址是registry-1.docker.io
,后面的对象存储和加速分发还依赖海外 CDN。问题在于,这些 CDN 节点大多不在国内,跨境链路的丢包和延迟会直接体现在下载过程里。拉一个几十 MB 的 Alpine 镜像可能只是慢一点,但要拉包含多个大层的 MySQL、GitLab、深度学习镜像时,基本就是反复断流、超时重试。
另一个容易被忽略的因素是限流。Docker Hub 对匿名用户和免费账号都有拉取次数限制,通常按 IP 地址计算。同一个出口 IP 下如果有很多机器在拉镜像,很容易触发TOOMANYREQUESTS
,直接拒绝服务。这种情况不是你换个网络就能解决的,而是得换一条“容器镜像下载专用通道”。
1.2 镜像加速器的工作原理
很多第一次配加速器的人会把它理解成一个代理,其实不太准确。Docker 镜像加速器本质上是一个pull-through cache(拉取型缓存仓库) ,它自己就是一个 Registry 服务,同时知道怎么回源到 Docker Hub。 当你给 Docker 配置了 registry mirror 后,执行 时,Docker 会先把请求发给加速器地址。加速器如果已经有 nginx 这个镜像的缓存,就直接把 manifest 和层返回给你;如果没有,它会自己去 Docker Hub 拉取一份,存到自己的存储里,再传给你。看起来是“让 Docker Hub 变快了”,实际上是下载链路被改道到了国内节点。 这也解释了为什么配置多个加速器没有坏处:第一个源没有缓存或挂了,Docker 会尝试下一个。对同一个镜像来说,只要任何一个源命中,后面的拉取速度都远快于直连海外。 想清楚加速器的边界,比记住几个地址更重要。它只对Docker Hub 官方镜像仓库(docker.io) 的拉取生效,对于你自建的 Harbor、GitLab Registry、云厂商的私有仓库,配置这个列表没有任何作用。加速器也不会替你处理 Docker Hub 的账号认证,想拉取私有仓库镜像,必须登录 Docker Hub,而加速器的缓存机制对私有镜像通常是失效的。 另外,镜像加速器只管 。你要推送自己的镜像到 Docker Hub,还是直接走 Docker Hub 本身的链路,这部分没有捷径。理解这些边界,后面踩坑时才知道问题出在配置还是出在方案本身。 如果追求稳定,优先考虑云服务商提供的镜像加速地址。这类源背后有云厂商的带宽资源、分布式节点和运维团队,不会因为某个社区维护者没空就突然停服。 云厂商源普遍要求注册账号,但配置过程只花几分钟,换来的是长期稳定的拉取体验。公司内部如果有条件,我更推荐直接搭建一个局域网内的 Registry 或 Harbor 作为统一中转,配合定期同步,效果比任何公网加速器都稳。 公共镜像站不需要账号,适合个人开发机、临时环境、测试服务器。缺点是稳定性参差不齐,可能今天能用明天就挂,所以我把它们放在第二梯队。 公共源就像社区里搭的顺风车站,方便但不保证准时。把它们当作备选或兜底可以,别把生产环境押在一个无人兜底的公共源上。 下面这张表汇总了截止到 9 月 8 日我重新过滤后还值得尝试的镜像源,按推荐优先级排列。标“专属”的地址需要去对应云控制台获取,标“公共”的可以直接用。 在 Linux 机器上,Docker 守护进程的配置放在 数组里: 改完执行: 这里有个特别容易翻车的点: 。 另外,如果机器上已经配置过 Docker Desktop 在 Windows 上默认跑在 WSL2 里,它的配置文件最终也会作用到 WSL2 的 Docker 引擎。但如果你是在 WSL2 发行版内部手动安装了 docker-ce,而不是通过 Docker Desktop 管理,那就需要按 Linux 的方式改 。这两条路子不要混着改,否则可能出现重启后配置被覆盖的情况。 macOS 上同样通过 Settings 改。如果你更习惯命令行,也可以直接编辑 ,不过图形界面始终是最稳妥的方式,改完留意 Docker Desktop 右下角弹出的重启提示。 如果你的环境用的是 containerd,而不是 Docker 引擎,配置方式和上面的 daemon.json 完全不同。很多 Kubernetes 节点默认使用 containerd 作为容器运行时,需要修改 的 endpoint: 修改后重启 containerd: containerd 和 Docker 的镜像源配置不互通。很多人在 K8s 节点上改了 确认节点运行时,再决定改哪个配置。 有些场景下你不想动任何配置文件,比如只是临时在一台机器上拉一个镜像应急,这时可以直接把镜像地址写全:在镜像名前面加上加速器地址。 注意官方镜像名前面要带上 。拉下来之后如果想让它看起来像普通镜像,再打个 tag: 这个方法很适合测试某个镜像源是否可用,或者解决“只拉一次,不想全局配置”的临时需求。缺点是每次都要敲一长串地址,手快容易拼错,适合应急,不适合日常。 配置完成后,第一件事不是急着拉镜像,而是确认 Docker 是不是真的读到了新配置。执行: 输出里应该能看到你填进去的镜像源地址。也可以直接看: 如果这段是空的,说明配置没被读到,多半是 daemon.json 路径不对或者 JSON 解析失败。这时要注意看 ,确认当前存在一个正常运行的 Docker 引擎。 另外补充一个小技巧:用 之类的信息,看到这个就说明走了镜像源,而不是直连 Docker Hub。 想知道加速器到底快了多少,最简单的方法就是记录拉取同一镜像的耗时。清掉本地已有的镜像: 然后执行: 记录 时间。之后切回直连或用另一个源再拉一次,对比结果。要保证测试公平,得先确认本地确实没有对应的镜像层缓存,否则第二次拉取会被本机层缓存影响,测出的数字没意义。 我在实际测试中,公共源首次拉取 Alpine 大概在 10 到 30 秒之间,云厂商专属源通常能压缩到 5 秒内。如果是几百 MB 的大镜像,差别会更明显。直连经常拉不动,而走加速器基本能保持在几 MB 每秒以上。如果你测完发现速度还是几十 KB,那大概率是源选得不好,按后面排查方法换一个。 镜像源不是配上去就一劳永逸的,地址变化、服务停摆、网络波动都可能导致拉取失败。常见的报错有这几种,我整理成了速查表: 快速判断一个镜像源是否存活,可以直接用 curl 探测它的 registry 接口: 正常返回 HTTP 200 或 401 都说明服务在线。401 是正常的,因为没带认证信息;如果返回 502、503 或连接超时,这源大概率已经不能用了。 我在 9 月 8 日重新整理这份清单之前,其实踩过一个挺大的坑。之前一度只配置了一个社区公共源作为默认镜像源,结果某个工作日下午这个源突然大面积超时,线上服务发布全部卡在拉镜像这一步。事后排查发现不是代码问题,也不是服务器问题,单纯就是镜像源挂了。 从那以后我的原则就变成了:至少配置两个不同运营方的源,一个云厂商专属源作为主力,一个公共源作为兜底。在 数组里按优先级从高到低排列,Docker 会按顺序尝试。公共源可以做备胎,但别做唯一选择。 镜像加速器只对公开镜像有效。如果你要拉取的是 Docker Hub 上的私有仓库镜像,比如 ,光配加速器是不够的。需要先执行: 但登录信息是发给 Docker Hub 的,加速器本身并不拥有你的认证凭据。更麻烦的是,即使你登录了,部分加速器在回源拉取私有镜像时也可能因为认证机制不兼容而失败。所以私有镜像拉取的正确姿势是:要么直连 Docker Hub,要么把私有镜像同步到自己的私有 Registry,再让所有机器从私有 Registry 拉取。 加速器本质上是第三方中转,理论上存在镜像内容被替换的风险。我并不是说所有源都不可信,但在生产环境里,任何镜像在部署前都应该做校验。最可靠的方式是使用 digest 而不是 tag 来固定版本: 拉取完成后,可以用以下命令确认镜像的 digest: 如果和仓库官方公布的 digest 不一致,说明镜像内容有问题,要立刻停止使用。日常开发可能不需要每次都查,但涉及生产环境、涉及敏感数据的应用,这一步不能省。 网上很多教程和文章里的镜像源地址是过时的,甚至有人故意放夹带私货的地址。拿不准的时候就遵循两条简单规则:优先用云厂商官方控制台生成的地址,其次用社区知名度高、维护时间长的项目地址。对于来路不明的镜像源,至少先用 curl 探测一下返回头,再手动拉一个小镜像测试内容是否正常。 另一个容易忽略的点是 。 配置了新的镜像源,不要只盯着 ,才能真正暴露问题。 换源之后如果本地已经存在同名镜像的旧版本,Docker 可能不会重新下载,导致你以为新源没生效。这时候用 参数强制拉取: 最后再分享一个小技巧:把测试过程写成一条命令,方便每次换源后快速验证。比如: 我在实际维护机器时,会定期跑一遍这个命令,同时检查 里的镜像源列表。镜像源这种事,平时不觉得它重要,一旦失效就是全局性的故障。备份一条能用的源,相当于给发布流程买了份保险。docker pull nginx:latest1.3 加速器的边界:能加速什么,不能加速什么
docker pull方向,不管docker push2. 2026 年 9 月更新的 Docker 国内镜像源清单
2.1 第一梯队:云厂商专属加速地址
https://<你的ID>.mirror.aliyuncs.com。这个地址是绑定账号的,别人用不了,配置到你自己的机器上即可。https://mirror.ccs.tencentyun.com这个公共地址,部分地域的机器可以直接使用。如果是在腾讯云 CVM 上,效果尤其好;本地开发机也可以先拿这个地址试试连通性。https://<你的ID>.mirror.swr.myhuaweicloud.com。2.2 第二梯队:无需注册的公共镜像站
https://docker.m.daocloud.io,DaoCloud 是国内长期维护 Docker 公共服务的团队,这个地址在社区里口碑不错,无需注册,直接配置。http://hub-mirror.c.163.com,老牌镜像站,注意地址是http,不是https。Docker 默认走 HTTPS,配置后可能遇到证书相关报错,需要额外处理。https://docker.mirrors.sjtug.sjtu.edu.cn,高校镜像站,带宽和资源依赖校园网,适合华东地区网络环境。https://docker.mirrors.ustc.edu.cn,历史上很出名,但曾经长时间停止 Docker 服务。近期可用性需要自己验证,不建议作为主力源。2.3 镜像源地址速查表
提供方 加速地址 类型 备注 阿里云 https://<你的ID>.mirror.aliyuncs.com专属 需注册账号,控制台获取专属地址,稳定优先 腾讯云 https://mirror.ccs.tencentyun.com公共 部分地域连通性更好,实测速度中上 华为云 https://<你的ID>.mirror.swr.myhuaweicloud.com专属 需注册账号,控制台获取专属地址 DaoCloud https://docker.m.daocloud.io公共 无需注册,公共源里维护比较积极 网易 http://hub-mirror.c.163.com公共 注意是 http,Docker 默认 https 会有问题 上海交大 https://docker.mirrors.sjtug.sjtu.edu.cn公共 高校源,连通性视网络环境而定 中科大 https://docker.mirrors.ustc.edu.cn公共 历史老牌,稳定性波动大,需自测 3. Docker 配置国内镜像源的三套姿势
3.1 Linux 下通过 daemon.json 配置
/etc/docker/daemon.json。没有这个文件就新建一个,然后把镜像源地址写进registry-mirrors{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://mirror.ccs.tencentyun.com", "https://<你的阿里云专属ID>.mirror.aliyuncs.com" ] }sudo systemctl daemon-reload sudo systemctl restart dockerdaemon.json必须是一个合法 JSON。很多人习惯在文件末尾多写一个逗号,Docker 启动直接失败,还会报一个含糊的failed to start daemon。改完文件可以先看一眼 JSON 格式,再重启服务。如果是二进制方式安装的 Docker,比如自己解压的dockerd,配置文件路径可能不同,最常见的还是在/etc/docker/daemon.jsoninsecure-registries、>{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://mirror.ccs.tencentyun.com" ] }/etc/docker/daemon.json~/Library/Group Containers/group.com.docker/settings.json或~/.docker/daemon.json3.3 containerd 与 Kubernetes 节点如何配置
/etc/containerd/config.toml,在 registry mirrors 部分增加针对docker.ioversion = 2 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://docker.m.daocloud.io", "https://mirror.ccs.tencentyun.com"]sudo systemctl restart containerd/etc/docker/daemon.json,却发现kubelet拉镜像还是走直连,原因就在于实际用的运行时是 containerd,Docker 引擎根本没参与镜像拉取。先用kubectl get nodes或crictl info3.4 不改配置也能用的“前缀拉取”技巧
docker pull docker.m.daocloud.io/library/nginx:latestlibrary/,因为nginx实际上等价于docker.io/library/nginx:latestdocker tag docker.m.daocloud.io/library/nginx:latest nginx:latest4. 配置后的验证与速度测试
4.1 确认加速器有没有生效
docker info --format '{{json .RegistryConfig.Mirrors}}'docker info | grep -A 10 "Registry Mirrors"docker info里的Server Version和Storage Driverdocker pull拉镜像时,通过docker pull的日志可以看到实际请求的域名。Docker 在拉取镜像过程中会打印Pulling from docker.m.daocloud.io/library/nginx4.2 拉取时间对比测试怎么做
docker rmi alpine:3.20time docker pull alpine:3.20real4.3 失效或异常时的排查路线
报错或现象 可能原因 解决思路 http: server gave HTTP response to HTTPS client镜像源是 http,Docker 默认走 https 换成支持 https 的源,或确认该源是否需要额外配置 TLS handshake timeout镜像源节点不稳定或不通 换源,多试几个地址 TOOMANYREQUESTSDocker Hub 对当前 IP 限流 错峰拉取,或换镜像源 manifest unknown镜像 tag 不存在,或镜像源未同步该 tag 检查 tag 写法,换完整镜像地址 dial tcp: i/o timeout到该镜像源节点的网络不通 用 curl 探测地址,换网络环境 配置后 Docker 启动失败 daemon.json 格式错误 检查 JSON 语法,特别是逗号 curl -I https://docker.m.daocloud.io/v2/5. 常见坑与避坑建议
5.1 公共源并不总是稳定的
registry-mirrors5.2 别用加速器解决私有镜像认证
yourname/private-app:latestdocker login5.3 注意镜像来源一致性问题
docker pull nginx:latest@sha256:3e5d1c9d4f0b1d3e1f2c4a1b9c3d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2ddocker inspect --format='{{index .RepoDigests 0}}' nginx:latest5.4 镜像源地址别随便从网上复制粘贴
insecure-registries。如果某个镜像源只支持 http,你可能会想直接把它加进insecure-registries来绕过 HTTPS 限制。这个配置会把该地址下所有通信都变成明文传输,你的拉取请求、镜像层内容都可能被中间人截获。除非是内网自建 Registry,否则不建议对公网镜像源使用insecure-registries5.5 换源之后记得重新拉取测试
hello-world一个镜像测试。hello-world实在太小了,根本体现不出镜像源的稳定性和带宽。我习惯用alpine:3.20和nginx:latest各拉一次,一个看基础镜像的下载速度,一个看多层的拉取稳定性。有条件的话,再拉一个几百 MB 的镜像,比如mysql:8.0或python:3.12-slimdocker rmi删掉旧镜像再拉,或者加--pull=alwaysdocker pull --pull=always python:3.12-slimdocker rmi alpine:3.20 2>/dev/null; time docker pull alpine:3.20docker info