GitLab CI/CD已配置证书仍无法登录Docker私有仓库报x509错误
问题根因
出现x509: certificate signed by unknown authority报错和证书签发方是Sectigo没有直接关系,核心问题出在配置逻辑和证书本身的完整性上:
- 最核心的配置错误:你使用了
docker:dind(Docker in Docker)服务作为CI环境的Docker守护进程,所有docker build/login/push操作实际是由dind容器内的dockerd进程执行,TLS证书校验也是dockerd完成。但你当前脚本是把证书拷贝到了运行CI脚本的docker客户端容器的/etc/docker/certs.d路径下,dind服务容器根本读不到这个证书,自然校验失败。 - 证书链不完整:如果你配置时只上传了仓库的站点叶子证书,没有附带Sectigo对应的中间CA证书,即使证书是正规CA签发,系统根库没有匹配的中间证书记录时,同样会判定为未知签发机构。
- 配置笔误:你脚本里打印证书的路径写的是
/etc/docker/certs.d/reg.booqall.com:80/ca.crt,和实际仓库域名reg.xxxx.com不一致,说明你可能存在路径拼写错误,证书根本没有放到正确的域名匹配目录下。 - 根证书库过旧:如果使用的是精简版docker镜像,内置的ca-certificates包版本较老,可能没有收录Sectigo近年更新的新根证书,也会导致校验失败。
修复方案
按优先级依次操作即可解决问题:
- 把证书直接挂载到dind服务容器内,不要在客户端脚本里拷贝证书。修改CI配置的services段,给dind配置卷挂载,确保证书能被dockerd进程读取,参考配置:
pack: image: docker:latest stage: pack services: - name: docker:dind command: ["sh", "-c", "apk add --no-cache ca-certificates && update-ca-certificates && dockerd --host=tcp://0.0.0.0:2376 --host=unix:///var/run/docker.sock"] volumes: - $CERT:/etc/docker/certs.d/reg.xxxx.com:80/ca.crt:ro script: # 删除原配置中在客户端容器内创建目录、拷贝证书的冗余步骤 - docker build -t xxxx/$NAME:latest build/$NAME/dist/. - docker login -u $REGISTRY_USER -p $REGISTRY_PASS reg.xxxx.com:80 - docker push xxxx/$NAME:latest - docker push xxxx/$NAME:$CI_COMMIT_TAG
- 校验证书完整性:确认
$CERT变量存储的是完整证书链,顺序为「站点叶子证书→Sectigo中间CA证书→Sectigo根证书」,不能只存单独的站点证书。本地可以执行openssl s_client -connect reg.xxxx.com:80 -showcerts检查返回的证书链是否有缺失段。 - 修正所有配置里的域名拼写错误,所有证书路径的域名、端口必须和实际访问的仓库地址完全一致,Docker对证书目录的匹配是精确字符串匹配,域名、端口写错都会导致证书无法被识别。
- 临时调试方案(禁止生产环境使用):如果需要快速跳过校验,可以给dind的启动命令添加参数
--insecure-registry reg.xxxx.com:80,该配置会关闭对应仓库的TLS证书校验,存在中间人攻击风险,仅可用于临时排错。
内容的提问来源于stack exchange,提问作者Arnold Zahrneinder
相关产品推荐
相关产品推荐

