企业隔离网私有镜像拉取“认证失败”的核心是凭证、协议、信任链三者未对齐:需确保docker login与pull地址完全一致(含端口/协议),https仓库须将pem格式ca.crt置于/etc/docker/certs.d/对应目录并重启docker,http仓库需在daemon.json配置insecure-registries,k8s还需创建并引用imagepullsecret。

企业隔离网环境下拉取私有镜像仓库报“认证失败”,核心不是网络不通,而是凭证、协议和信任链三者没对齐。只要理清这三点,问题基本就解了一半。
确认 docker login 地址与拉取地址完全一致
隔离网中常因内部 DNS 或 hosts 配置导致访问域名与登录域名不一致。比如:
- 你在 docker login registry.internal:5000 登录了
- 但执行 docker pull registry.internal/myapp:latest(缺端口)——会失败
- 或 docker pull https://registry.internal:5000/myapp:latest(多 https://)——也可能失败
解决办法:拉取时的 registry 前缀必须和 login 时的完全相同(包括端口、协议、大小写)。建议统一用带端口的短域名,如 registry.internal:5000,并在 ~/.docker/config.json 中检查 auths 字段是否匹配。
私有仓库若启用 HTTPS,必须让 dockerd 信任证书
隔离网常用自签名 CA,Docker 守护进程默认不读系统证书,只认 /etc/docker/certs.d/ 下的专用证书。
- 证书文件名必须是 ca.crt(全小写,无 .pem 等后缀)
- 目录路径必须严格对应访问地址:
/etc/docker/certs.d/registry.internal:5000/ca.crt - 证书内容需为 PEM 格式,以
-----BEGIN CERTIFICATE-----开头 - 执行
sudo systemctl restart docker生效(不重启,配置不加载)
验证方式:运行 curl -k https://registry.internal:5000/v2/ 能返回 {},再试 curl -v https://registry.internal:5000/v2/ 看是否提示证书 OK。
HTTP 私有仓库需显式配置 insecure-registries
如果仓库确实走 HTTP(如内网测试 registry:2),Docker 默认拒绝连接,必须主动放开。
- 编辑
/etc/docker/daemon.json,加入:{"insecure-registries": ["registry.internal:5000"]} - 注意:不能写成
http://registry.internal:5000,只写地址+端口 - 保存后执行
sudo systemctl restart docker - 此时
docker login registry.internal:5000不加协议,docker pull也不加 http://
Kubernetes 场景下要额外生成 imagePullSecret
即使本地 docker pull 成功,K8s Pod 拉取仍可能失败——因为 Pod 不继承宿主机的 config.json。
- 用已登录凭证创建 Secret:
kubectl create secret docker-registry my-registry-secret \<br> --docker-server=registry.internal:5000 \<br> --docker-username=xxx \<br> --docker-password=yyy
- 在 Pod 或 ServiceAccount 中引用该 Secret:
imagePullSecrets: [{name: my-registry-secret}] - 注意:Secret 必须和 Pod 在同一 namespace











