先问一个问题:你是不是也遇到过这种情况——网上搜到的教程让你编辑 /etc/docker/daemon.json,添加 registry-mirrors,你也照做了,docker info 里面甚至能看到 Registry Mirrors 这一项,但 docker pull 该超时还是超时,该失败还是失败?
如果你用的恰好是 Docker Engine 26.x,同时又是 Ubuntu/Debian 系系统,那这个问题确实很典型。Docker 26 本身在镜像拉取链路上做了一些调整,再加上这两年公共镜像加速器的存活率大幅下降,导致很多老教程里的“换源三板斧”完全失灵。这篇文章我就把从现象到根因、从标准解法到自建方案、从排查命令到常见报错,一次性讲清楚,尽量让你照着操作就能把问题解决,而不是继续在各种过时教程里打转。
1. 先搞清楚:镜像源没生效到底卡在哪一步
先说个很反直觉的事:很多人所谓的“换源没生效”,并不是配置写错了,而是“配置对了,但加速器本身已经死了”。两者表现一模一样,都是 pull 卡半天,最后报超时。如果不先把这个问题分层,后面很容易白忙活。
1.1 三种“配置了但等于没配置”的典型状况
我帮人排查时,遇到的状况基本可以归成三类。
第一类是 daemon.json 根本没被 Docker 读取。常见原因是文件路径不对,比如写到了 ~/.docker/daemon.json,Docker daemon 根本不会看这个位置;或者权限不对,文件属主、权限过于开放,dockerd 启动时直接拒绝加载;再或者是 JSON 格式不合法,比如加了注释、多打了逗号,导致解析失败。这类问题有一个共性特征:docker info 里看不到 Registry Mirrors 项。
第二类是配置确实被加载了,docker info 也能看到镜像源列表,但源本身已经失效。这种情况尤其迷惑人,因为你从配置层面看一切正常。2024 年以来,大量第三方公共镜像加速器陆续关闭、限制访问或者只能拉取白名单仓库,老教程里那些“magic 域名”现在很多已经变成摆设,甚至有的会给你返回一个 404 或者直接 TLS 握手失败。你改了配置但不换源,效果等于零。
第三类是配置加载了、源也健康,但 Docker 26 在 pull 时没有真正走镜像源。比如你开着系统的 HTTP 代理,但代理对 docker 相关的域名做了奇怪的处理;再比如你同时配置了多个镜像源,而 Docker 会按顺序挨个尝试,排在第一个的源已经失联,它会在那里等很久,看起来就像是“加速没生效”。这种情况在镜像源列表特别长的机器上尤其明显。
1.2 为什么 Docker 26 上这个问题尤其普遍
不是 Docker 26 故意刁难人,而是几件事赶在一起了。
一是 Docker 26 这个版本在 daemon 配置校验上更严格。旧版本里,daemon.json 如果格式有问题,可能只是静默跳过,服务还能起来;到了 26 版本,配置解析失败时,服务可能直接起不来,或者在 systemd 里反复重启。你看到一个 Docker 服务状态异常,第一反应往往是“我是不是装坏了”,而不是“我写的 JSON 是不是有问题”。
二是 Docker 26 引入了更多的 containerd 集成逻辑。如果开启了 containerd image store 特性,镜像存储和拉取链路会发生变化,某些时候 daemon.json 里的 registry-mirrors 依然生效,但由于 containerd 那边也有自己的端点配置,两者叠加反而容易让人摸不着头脑。如果你同时改过 /etc/containerd/config.toml,那问题会更隐蔽。
三是现在很多用户是“换源教程”和“系统源教程”混着看。你在搜索引擎里搜 docker 换源,出来的结果可能一半是教你换 apt 源,一半是教你换 pip 源,真正针对 Docker daemon 镜像加速的反而是少数。有些人甚至把阿里云的 apt 源地址填进了 registry-mirrors,那自然是完全无效的。
所以,别急着怪 Docker 26,先把上面这几层问题逐个排除,才是正经路子。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 标准姿势:把镜像加速器正确写进 daemon.json
不管你是 Docker 26 还是更老的版本,这一步都是地基。我见过太多人在这里翻车,所以尽量把细节写透。
2.1 先写对文件:一个能通过校验的 daemon.json
先说路径:Linux 上 Docker Engine 的配置文件是 /etc/docker/daemon.json,不是用户目录,也不是 /etc/default/docker。Debian/Ubuntu 如果装了 docker.io 包,某些版本可能用默认配置跑,没有这个文件,需要自己创建。
一个最简配置长这样:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1
