GitLab跨虚拟机Docker-in-Docker(DIND)流水线故障求助
GitLab Docker-in-Docker(DIND)流水线连接问题排查
环境与问题概述
GitLab部署在一台虚拟机,GitLab Runner(Docker执行器)部署在另一台虚拟机,尝试搭建DIND流水线时,始终无法连接到Docker守护进程,测试多种配置均无效。
当前使用的流水线配置
完整配置
image: docker:23.0.1 workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: never - when: always services: - name: docker:23.0.1-dind alias: docker variables: DOCKER_HOST: tcp://docker:2375/ DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 stages: - build - test - cleanup include: # Static - template: Jobs/Container-Scanning.gitlab-ci.yml - template: Jobs/Dependency-Scanning.gitlab-ci.yml - template: Jobs/SAST.gitlab-ci.yml - template: Jobs/Secret-Detection.gitlab-ci.yml - template: Jobs/Code-Quality.gitlab-ci.yml # Start Application Build and Test build-XRecorder: stage: build variables: IMAGE: technologyresearcher/test:$CI_COMMIT_SHA before_script: - docker login -u technologyresearcher -p $Registery_Password script: - docker build -t $IMAGE . - docker push $IMAGE test-XRecorder: stage: test script: - dotnet test # Start Security Scanner Configurations semgrep-sast: variables: SAST_EXPERIMENTAL_FEATURES: "true" SCAN_KUBERNETES_MANIFESTS: "false" SAST_EXCLUDED_PATHS: ".gitlab, chart, docs, network-policies, scripts, terraform, tests" cache: {} secret_detection: variables: SECRET_DETECTION_EXCLUDED_PATHS: "docs, tests, scripts, network-policies, terraform" GIT_DEPTH: 100 code_quality: rules: - if: $CODE_QUALITY_DISABLED when: never - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: never - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH code_quality_html: extends: code_quality variables: REPORT_FORMAT: html artifacts: paths: [gl-code-quality-report.html] # End Security Scanner Configurations
简化测试配置
image: docker:latest workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: never - when: always services: - name: docker:dind alias: docker variables: DOCKER_HOST: tcp://docker:2375/ DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 stages: - build - test - cleanup # Start Application Build and Test build-XRecorder: stage: build variables: IMAGE: technologyresearcher/test:$CI_COMMIT_SHA before_script: - docker login -u technologyresearcher -p $Registery_Password script: - docker build -t $IMAGE . - docker push $IMAGE test-XRecorder: stage: test script: - dotnet test
已测试的场景
- 镜像版本:试过
docker:latest/dind:latest,也指定过匹配的固定版本(如23.0.1) - DIND服务别名:测试过带
alias: docker和不带别名的配置 - DOCKER_HOST地址:
- 用
docker域名:提示无法解析该域名 - 用Runner虚拟机本地IP:出现I/O超时
- 用
localhost:提示“docker守护进程是否在运行”
- 用
已确认的前置条件
- GitLab Runner已加入正确用户组,具备Docker访问权限
- Runner所在虚拟机上的Docker服务正常运行(通过
docker info验证)
可能的原因及排查方向
1. GitLab Runner的特权模式配置
DIND容器需要特权模式才能启动Docker守护进程,检查Runner的config.toml文件:
- 确保
privileged = true(在[[runners.docker]]配置块下) - 如果未开启特权模式,dind容器内的docker daemon会启动失败,导致无法连接
2. 容器间网络连通性
- 在job的
before_script中添加ping docker,测试是否能解析到dind服务的IP,若解析失败,说明Docker的服务DNS存在问题,或Runner配置了自定义网络导致job容器与dind容器不在同一网络 - 测试端口连通性:在job中执行
telnet docker 2375或nc -zv docker 2375,确认2375端口是否能正常访问 - 检查Runner所在虚拟机的防火墙/安全组,是否允许容器内部网络的2375端口通信
3. DIND服务启动状态
- 在Runner所在虚拟机上,找到dind服务对应的容器(用
docker ps -a),查看容器日志:docker logs <dind-container-id>,检查是否有启动失败的错误(如权限不足、存储驱动不兼容) - 尝试给dind服务添加启动命令,强制指定存储驱动:
services: - name: docker:23.0.1-dind alias: docker command: ["--storage-driver=overlay2"]
4. TLS配置验证
确认DOCKER_TLS_CERTDIR=""变量已正确生效:
- 在job中执行
env | grep DOCKER_TLS_CERTDIR,检查变量是否为空 - 如果dind容器启用了TLS,会监听2376端口而非2375,此时需要调整DOCKER_HOST为
tcp://docker:2376/并配置证书,但用户已设置禁用TLS,需确认dind容器内的docker daemon确实在2375端口监听(可在dind容器内执行ss -tulpn查看)
5. Runner网络模式配置
检查Runner的config.toml中的network_mode:
- 若配置了
network_mode = "host"或其他自定义网络,可能导致job容器与dind服务容器不在同一网络,无法解析别名 - 默认应为
network_mode = "bridge",确保两者在同一网络环境
内容的提问来源于stack exchange,提问作者technologyresearcher
相关产品推荐
相关产品推荐

