Docker 拉取镜像部分成功部分失败?

Docker 拉取镜像部分成功部分失败?一次代理配置踩坑记录!

最近在部署 Zitadel 身份认证平台的过程中,遇到一个看似“随机”的问题:Docker 有些镜像可以拉取,有些却一直超时失败。最终通过配置 Docker 守护进程级别的代理 才解决。文章记录整个问题分析和解决过程,便于自己和大家后期参考。


问题背景

部署 Zitadel 时,使用官方提供的 getting-started-with-zitadel.sh 脚本,脚本会拉取多个 Docker 镜像,比如:

  • ghcr.io/zitadel/zitadel
  • docker.io/library/caddy
  • netbirdio/**

❗️问题表现

在执行过程中,有些镜像可以拉取成功,有些会报如下错误:

Error response from daemon: Get "https://registry-1.docker.io/v2/": 
net/http: request canceled while waiting for connection 
(Client.Timeout exceeded while awaiting headers)

观察结果是:

镜像 是否拉取成功
ghcr.io/zitadel/zitadel ✅ 成功
docker.io/library/caddy ✅ 成功
netbirdio/management / netbirdio/signal ❌ 超时失败

Docker 拉取镜像部分成功部分失败?_第1张图片

同时,我们很早就配置了一些 Docker Hub 镜像加速器(如阿里云,腾讯云,DaoCloud 等),这也是为什么有些镜像能顺利拉取,有些却不能的原因之一。

因为镜像加速器仅能加速“Docker Hub 官方镜像”,如 library/nginxdocker.io/library/caddy,而像 netbirdio/* 这种非官方项目的镜像并不在加速器白名单内,因此仍然会拉取失败。


初步排查

✅ 网络本身没有问题

  • ping registry-1.docker.io 正常
  • curl https://registry-1.docker.io/v2/ 正常
  • docker login 也没有任何异常

❌ 但 Docker 拉取仍旧失败

通过多次测试发现,Docker 有些镜像拉得飞快,有些镜像卡死或超时,尤其是 docker.io/netbirdio 相关的镜像。

这时开始怀疑:
➡️ 可能和代理有关


解决思路:配置 Docker 的守护进程代理

平时我们习惯配置终端代理,例如:

export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890

但实际上:

⚠️ Docker 守护进程(dockerd)是独立运行的,它不会继承当前 shell 的代理环境变量!


解决方案:配置 Docker 的 systemd 代理

  1. 创建代理配置目录(如不存在):
sudo mkdir -p /etc/systemd/system/docker.service.d
  1. 创建代理配置文件:
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
  1. 写入以下内容(根据你实际代理修改):
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.corp"
  1. 应用配置并重启 Docker:
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart docker
  1. 验证代理是否生效:
sudo systemctl show --property=Environment docker

输出应该包含你刚才设置的代理环境变量。


✅ 最终结果

重启 Docker 后再次运行部署脚本:

  • 所有镜像(包括 netbirdio)都能成功拉取
  • 部署流程顺利走完

总结

问题 结论
Docker 部分镜像拉取失败 是由于 Docker 守护进程未配置代理,而不是网络本身问题
解决方案 配置 systemd 层面的 http-proxy.conf,让 dockerd 使用代理
验证方式 systemctl show --property=Environment docker 查看生效状态

经验教训

  • Docker CLI 和 Docker 守护进程环境是 两套东西,网络设置互不影响
  • 如果你使用代理加速访问 Docker Hub,务必同步设置到 系统服务级别
  • 部署复杂服务时,像 Zitadel 这类一键脚本可能集成很多镜像,尽早配置好代理 可避免不必要的卡顿
  • 配置镜像加速器虽然有用,但仅限于部分镜像。像 netbirdioghcr.io 上的镜像,加速器是无法覆盖的,因此守护进程代理是更通用的做法
  • Docker 官方解决文档

如果你也踩过类似的坑,欢迎留言交流~
如果需要,我还可以分享 Docker Compose 加速配置、一键安装脚本等!

你可能感兴趣的:(个人经验,docker,eureka,容器)