认证失败核心是客户端、协议、证书、权限四者未对齐:需确保docker login地址与镜像标签完全一致(含端口/协议),HTTPS仓库须将ca.crt置于/etc/docker/certs.d/对应路径并重启docker,HTTP仓库需配置insecure-registries,K8s还需创建并引用imagePullSecret。
认证失败不是单纯输错密码,而是客户端、协议、证书、权限四者没对齐。只要逐项确认这四个环节,90%的问题都能定位。
检查 docker login 地址和镜像标签是否完全一致
登录地址必须和拉取/推送时用的 registry 前缀一模一样——包括端口、协议(有无 https://)、大小写、甚至斜杠结尾与否。
- 你执行了 docker login registry.internal:5000,那所有操作都得用这个格式:docker pull registry.internal:5000/app:latest、docker tag app:latest registry.internal:5000/app:latest
- 如果镜像名漏了端口(registry.internal/app)或多了协议(https://registry.internal:5000/app),都会触发 401
- 查看 ~/.docker/config.json 中 auths 字段,确认键名(key)和你实际使用的 registry 完全匹配
验证证书配置是否正确(HTTPS 仓库必做)
自签名或内网 CA 签发的证书,Docker 守护进程不会自动信任,必须手动放对位置。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 证书文件名必须是 ca.crt(全小写,不能叫 ca.pem 或 root.crt)
- 目录路径必须严格按访问地址生成:/etc/docker/certs.d/registry.internal:5000/ca.crt(IP + 端口也要带)
- 证书内容需为 PEM 格式,以 -----BEGIN CERTIFICATE----- 开头
- 改完后必须执行 sudo systemctl restart docker,否则不生效
- 验证方式:curl -v https://registry.internal:5000/v2/,看是否提示 “SSL certificate verify ok”
HTTP 仓库要显式启用不安全模式
如果私有仓库走的是 HTTP(比如本地跑的 registry:2 默认监听 :5000),Docker 默认拒绝通信。
- 编辑 /etc/docker/daemon.json,加入:
{"insecure-registries": ["registry.internal:5000"]} - 注意:只写地址+端口,不要加 http:// 或 https://
- 保存后同样要 sudo systemctl restart docker
- 此时 docker login 和 docker pull 都不能带协议前缀
Kubernetes 场景下必须单独创建 imagePullSecret
即使宿主机上 docker pull 成功,K8s Pod 拉镜像仍会失败——因为 Pod 不读取节点上的 ~/.docker/config.json。
- 用 docker login 登录后,从 ~/.docker/config.json 提取 auth 字段,base64 编码
- 通过 kubectl create secret docker-registry 创建 Secret
- 在 Pod 或 ServiceAccount 中引用该 Secret,否则拉取请求直接被拒绝
- Harbor 等平台还需确认:项目是否开启公开访问?用户是否有对应项目的 push/pull 权限?

















