Docker报x509证书错误本质是守护进程不信任私有仓库TLS证书,需将PEM格式ca.crt置于/etc/docker/certs.d/对应地址+端口目录并重启docker,严禁混用HTTPS登录与HTTP配置,同时校验证书域名、时间及链完整性。

遇到 x509: certificate signed by unknown authority 错误,说明 Docker 守护进程拒绝信任私有仓库的 TLS 证书。这不是网络不通或镜像不存在的问题,而是证书链未被识别导致的连接中断。核心思路是让 dockerd 明确知道该信任谁,而不是跳过验证。
确认证书访问地址与配置路径严格一致
Docker 守护进程按“完整访问地址(含端口)”查找对应证书文件。哪怕只差一个端口、协议或域名格式,都会失败。
- 如果你执行
docker pull registry.example.com:443/myapp,证书目录必须是/etc/docker/certs.d/registry.example.com:443/ - 若用 IP 访问(如
192.168.1.100:5000),目录名也必须带端口:/etc/docker/certs.d/192.168.1.100:5000/,不能省略:5000或写成/etc/docker/certs.d/192.168.1.100/ - 目录下文件名必须为
ca.crt(小写,无扩展名变体),且内容为 PEM 格式(以-----BEGIN CERTIFICATE-----开头)
正确安装 CA 证书到 Docker 信任目录
自签名证书或内网 CA 签发的证书,需手动导入。不要改系统级 CA 存储,Docker 守护进程不读取它。
- 创建目标目录:
sudo mkdir -p /etc/docker/certs.d/your-registry:port - 复制证书(确保是根 CA 或完整信任链):
sudo cp ca.crt /etc/docker/certs.d/your-registry:port/ca.crt - 检查权限:
sudo chmod 644 /etc/docker/certs.d/your-registry:port/ca.crt - 重启守护进程生效:
sudo systemctl restart docker
区分 HTTPS 登录与 HTTP 仓库的处理方式
不是所有私有仓库都走 HTTPS;协议不匹配会引发双重错误。
- 若仓库启用了 HTTPS(如 Harbor 默认),
docker login必须带https://前缀:docker login https://registry.example.com - 若仓库是 HTTP 模式(如本地
registry:2镜像,默认监听:5000),docker login不能加协议:docker login localhost:5000,同时需在/etc/docker/daemon.json中配置:"insecure-registries": ["localhost:5000"],再重启 dockerd - 混用会导致:登录成功但拉取失败,或提示
server gave HTTP response to HTTPS client
排查证书链与系统时间等隐性因素
即使放对了证书,仍可能因细节问题失败。
- 用
openssl s_client -connect your-registry:port -showcerts查看实际返回的证书,确认 Subject、SAN 域名与你访问地址完全一致 - 检查系统时间是否准确(误差超过几分钟会导致证书“未生效”或“已过期”):
timedatectl status - 若证书由中间 CA 签发,
ca.crt文件中应合并根证书 + 中间证书(根在前,中间在后),否则验证会断链 - CI/CD 环境中,Docker daemon 和 client 往往隔离,
~/.docker/config.json不自动共享,需显式挂载或每次 job 执行docker login











