GitLab Runner并行运行DIND构建任务时证书及资源冲突问题求助
问题现象
单构建任务运行正常,但并行启动3个采用DIND的构建任务时出现证书相关错误,典型报错:
failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "docker:dind CA")
已尝试为每个Runner配置独立证书目录,但问题依旧;同时发现DOCKER_HOST="tcp://docker:2376"地址重复,任务存在资源复用情况。
核心问题分析
并行构建时的证书错误本质是多个DIND服务实例的证书链冲突,加上任务间资源复用导致的连接混乱:
- 单任务场景下,单个DIND实例生成的CA证书、客户端证书能被构建容器正确识别,验证链完整;
- 并行场景下,多个DIND实例的证书被加载到同一环境(或任务误连其他DIND实例),导致证书验证时出现“未知授权机构”错误。
排查方向
- DIND服务隔离性验证:检查并行任务的DIND容器ID是否唯一,若重复则说明资源未实现任务级隔离;
- 证书加载正确性检查:进入构建容器,查看
/etc/docker/certs.d目录下的证书是否与当前DIND实例生成的一致,若不一致则存在证书覆盖或加载错误; - 网络命名空间确认:确认Runner是否为每个任务分配独立网络,避免
docker服务别名被多个任务复用,导致DOCKER_HOST指向错误实例。
解决建议
为DIND服务添加唯一标识
在.gitlab-ci.yml中利用CI_JOB_ID为每个任务的DIND服务设置唯一别名与地址,避免资源复用:services: - name: docker:dind alias: docker-${CI_JOB_ID} variables: DOCKER_HOST: "tcp://docker-${CI_JOB_ID}:2376" DOCKER_TLS_CERTDIR: "/certs"启用Runner任务级网络隔离
修改Runner的config.toml配置,确保每个任务使用独立网络:[[runners]] executor = "docker" [runners.docker] privileged = true network_mode = "bridge" disable_cache = false volumes = ["/cache", "/certs/client"]注意:
privileged模式是DIND运行的必要条件,/certs/client用于共享DIND生成的证书。动态控制证书生成逻辑
若不需要TLS加密,可临时禁用证书生成简化配置(生产环境不建议):variables: DOCKER_TLS_CERTDIR: "" DOCKER_HOST: "tcp://docker:2375"如需保留TLS,可在构建脚本中手动复制对应DIND实例的证书:
cp /certs/client/ca.pem /etc/docker/certs.d/${DOCKER_HOST##*/}/ca.crt cp /certs/client/cert.pem /etc/docker/certs.d/${DOCKER_HOST##*/}/cert.crt cp /certs/client/key.pem /etc/docker/certs.d/${DOCKER_HOST##*/}/key.key更新DIND镜像版本
旧版DIND镜像的证书生成逻辑存在并行冲突问题,建议升级到最新稳定版(如docker:dind:24),新版优化了隔离机制,减少证书冲突概率。调整Runner并发配置
确保Runner的concurrent值与可用Runner数量匹配(如设置为3),避免任务排队导致的资源竞争:concurrent = 3 check_interval = 0
内容的提问来源于stack exchange,提问作者Enissay

