报错是这么冒出来的。内网 Harbor 2.8 换域名后,docker push registry.corp.local 报 500 并提示 x509 certificate relies on legacy Common Name,客户端日志里是 certificate is valid for other names。
中间走过弯路,把「客户端把 CA 装进了系统信任库,但 docker 只读 /etc/docker/certs.d 下的证书」当成主因,改完现象没变。
真正麻烦的地方在于,几个原因的现象几乎一样。证书只签了 Common Name 没写 SAN,新版 Go 客户端已经忽略 CN 字段。另一种情况是证书签发的域名与客户端访问的域名大小写或后缀不一致。
少数情况下是registry 容器里挂的还是旧证书文件,服务没重载。
第一件事是用 openssl 看证书里到底有哪些名字
openssl x509 -in /etc/docker/certs.d/registry.corp.local/ca.crt -noout -text | grep -A2 'Subject Alternative Name'
接着重新签发带 SAN 的证书
openssl req -new -addext 'subjectAltName=DNS:registry.corp.local' -key registry.key -out registry.csr
随后把 CA 放到客户端的 certs.d 目录
mkdir -p /etc/docker/certs.d/registry.corp.local && cp ca.crt /etc/docker/certs.d/registry.corp.local/
剩下的就是重启 docker 后用 curl 验证握手
systemctl restart docker && curl -I https://registry.corp.local/v2/
怎么算真的好了,看的是同一批现象。curl 返回 200 且没有证书告警,docker login 成功,push 一个测试镜像能正常完成并出现在仓库里。
提醒一点。只有 CN 没有 SAN 的证书在老客户端能过,新版本直接拒;换域名时客户端 certs.d 目录名也要跟着改,否则照样不信任。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
