国内直接从 Docker Hub 拉取镜像,常见情况是下载速度只有几十 KB/s,稍大一点的镜像走到一半就超时。CI 流水线、批量部署和本地开发都会被拖慢,有时重试两三次才能成功。

加速器的思路是在国内放一层缓存。Docker 客户端先请求离你近的节点,节点没有这个镜像时再回源拉取,并把结果存下来。同一个镜像第二次拉取,速度通常明显快很多。阿里云容器镜像服务(ACR)提供的就是这类加速器,个人账号一般可以直接使用。
二、获取专属加速地址
加速地址和阿里云账号绑定,格式大致是 https://<你的ID>.mirror.aliyuncs.com。在控制台里找它的路径如下:
- 登录阿里云控制台,进入“容器镜像服务 ACR”。
- 左侧菜单选择“镜像工具”,点击“镜像加速器”。
- 页面会给出专属地址,以及不同操作系统的配置命令。
这个地址属于你的账号资源,只保存在服务器本地配置里就行。别写进代码仓库或公开文章,它和你的账号绑定。
三、写入 daemon.json
Linux 上 Docker 的全局配置读取自 /etc/docker/daemon.json。文件不存在时,先建目录再写入。下面的命令里把 ID 换成你自己的地址:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<‘EOF’
{
“registry-mirrors”: [“https://<你的ID>.mirror.aliyuncs.com”]
}
EOF
配置生效需要重新加载并重启服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
有两个地方容易出错。一是 daemon.json 必须是合法 JSON,多一个逗号或少一个引号,Docker 就起不来。二是机器上如果已经有 log-driver、insecure-registries 之类的配置,要把 registry-mirrors 加进同一个 JSON 对象里。整份文件覆盖掉,原来的设置也会一起丢失。
四、验证加速是否生效
执行 docker info,在输出末尾找 Registry Mirrors,应该能看到你的加速地址。如果没有,先回头检查 daemon.json 和服务是否重启,再怀疑网络。
再拉一个常用镜像试试,比如:
docker pull nginx:alpine
第一次如果很慢,可以删掉本地镜像(docker rmi nginx:alpine)再拉一次。第二次明显变快,说明缓存已经在起作用。
五、案例:CI 流水线拉取超时
某团队的 GitLab Runner 部署在国内云主机上,每次构建都要拉 node:18、python:3.11 这类基础镜像。流水线常在 pull 阶段报 net/http: TLS handshake timeout,同一个任务要重试两三次才能通过,发布节奏被拖得很难受。
他们主要做了三件事:
- 在 Runner 宿主机的 daemon.json 中配置 ACR 加速地址,然后重启 Docker。
- 基础镜像固定版本号。latest 标签变动频繁,容易让缓存失效,固定版本后缓存更稳定。
- 调整 Dockerfile 的层顺序,把变动少的依赖安装放在前面,改业务代码时就不必每次重装依赖。
之后基础镜像拉取失败的情况基本没再出现。团队没有做严格的前后对比,提速多少要看网络、镜像大小和缓存命中情况,这里不给具体数字。这个案例也说明,加速器解决的是拉取这一步的网络问题,构建缓存和版本管理同样影响整条流水线的速度。
六、常见问题
1. 加速器对哪些镜像生效
registry-mirrors 只作用于 Docker Hub。拉取 gcr.io、quay.io 之类的镜像时,加速器不会介入,要么直连原站,要么使用对应仓库自己的加速方案。镜像名里写了完整的仓库域名,Docker 同样不会经过加速器。
2. 配置改了还是慢
先确认 docker info 里确实有加速地址。没有的话,多半是 daemon.json 格式有问题,或者服务没有重启。启动日志可以用 sudo journalctl -u docker -n 50 查看,报错信息一般比较具体。
3. 私有镜像怎么拉
加速器只负责公共镜像。拉取或推送你在 ACR 里创建的私有镜像,需要先登录,例如 docker login registry.cn-hangzhou.aliyuncs.com,并使用完整的仓库地址。
4. 服务条款可能变化
域名、地址格式和免费额度都可能调整。正式上线前,以阿里云官方文档和控制台的说明为准,不要只照着博客里的截图操作。
配置本身三步就能完成:拿到地址,写入 daemon.json,重启后验证。流水线里更常卡住的,是加速范围没搞清楚,镜像版本没有固定,构建缓存也没有规划。