You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab Runner Kubernetes执行器中Docker-in-Docker卷挂载问题

问题描述

在采用特权模式Docker-in-Docker的GitLab Runner Kubernetes执行器运行CI流水线时,尝试将Runner文件系统中的卷挂载至Docker容器,发现文件在Runner容器内存在,但启动的Docker容器里无法访问。

环境信息

  • GitLab Runner:Kubernetes执行器(特权模式)
  • Docker:运行于特权容器,已挂载Docker套接字

GitLab Runner配置

config: |
    [[runners]]
      id = 0
      output_limit = 100000
      [runners.kubernetes]
        namespace = "{{.Release.Namespace}}"
        image_pull_secrets = ["my-registry-secret"]
        memory_request = "1048Mi"
        cpu_request = "500m"
        logs_section_max_size = 52428800  # 50 MB
        timeout = 3600
        privileged = true
        helper_cpu_request = "500m"
        helper_memory_request = "168Mi"
        helper_image = "docker.io/gitlab/gitlab-runner-helper:x86_64-v17.0.0"
        pull_policy = "if-not-present"
        image = "xxxxxxxxxxxxxx"
        # Enable shared storage for docker in docker
        builds_dir = "/builds"
        cache_dir = "/cache" 
        [runners.kubernetes.volumes]
          [[runners.kubernetes.volumes.host_path]]
            name = "docker"
            mount_path = "/var/run/docker.sock"
            read_only = false
            host_path = "/var/run/docker.sock"
          [[runners.kubernetes.volumes.host_path]]
            name = "cache"
            mount_path = "/cache"
            read_only = false
            host_path = "/tmp/cache"
          [[runners.kubernetes.volumes.host_path]]
            name = "builds"
            mount_path = "/builds"
            read_only = false
            host_path = "/tmp/gitlab-runner/builds"
          [[runners.kubernetes.volumes.host_path]]
            name = "runner-secrets"
            mount_path = "/etc/gitlab-runner/certs"
            read_only = true
            host_path = "/etc/ssl/certs"

当前代码

container_monorepo_path = "/workspace"
docker_command = (
    f'docker run --rm '
    f'-v {monorepo_root}:/workspace '
    f'-w /workspace/{relative_project_path} '
    f'--user root '
    f'private-registry.company.com/docker-adv-all/docker-agent-playwright '
    f'sh -c "'
    f'npm config set strict-ssl false && '
    f'npm install -g pnpm nx && '
    f'pnpm nx run {project_name}:{task}"'
)

实际错误输出

[2025-07-11 22:24:36] - [INFO]: running command => docker run --rm -v /builds/t3_zrKwM/0/550016304/cp-monorepo:/workspace -w /workspace/packages/frontend/actions --user root private-registry.company.com/docker-agent-playwright:latest sh -c "npm config set strict-ssl false && npm install -g pnpm nx && pnpm nx run actions:test-component"
[2025-07-11 22:24:46] - [INFO]: added 125 packages in 9s
[2025-07-11 22:24:46] - [INFO]: 28 packages are looking for funding
[2025-07-11 22:24:46] - [INFO]: run `npm fund` for details
[2025-07-11 22:24:46] - [ERROR]: npm notice
[2025-07-11 22:24:46] - [ERROR]: npm notice New major version of npm available! 9.5.1 -> 11.4.2
[2025-07-11 22:24:46] - [ERROR]: npm notice Changelog: <https://github.com/npm/cli/releases/tag/v11.4.2>
[2025-07-11 22:24:46] - [ERROR]: npm notice Run `npm install -g npm@11.4.2` to update!
[2025-07-11 22:24:46] - [ERROR]: npm notice
[2025-07-11 22:24:46] - [INFO]: ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND  No package.json (or package.yaml, or package.json5) was found in "/workspace/packages/frontend/actions".
[2025-07-11 22:24:47] - [ERROR]: ❌ test-component failed

问题分析与解决方案

核心原因

你采用的是挂载宿主机Docker套接字的方式实现Docker-in-Docker,而非真正的DinD容器。这种模式下,Runner容器内执行docker run命令时,实际调用的是宿主机的Docker引擎创建容器。此时你挂载的/builds/...是Runner容器内的路径,但宿主机上并没有这个路径,导致新启动的Docker容器无法找到对应文件。

解决方案

方案1:调整挂载路径映射

Runner容器的/builds目录是通过HostPath挂载自宿主机的/tmp/gitlab-runner/builds,因此需要将docker run中的挂载路径替换为宿主机的实际路径:

# 将Runner内路径替换为宿主机对应路径
host_monorepo_root = monorepo_root.replace("/builds", "/tmp/gitlab-runner/builds")
docker_command = (
    f'docker run --rm '
    f'-v {host_monorepo_root}:/workspace '
    f'-w /workspace/{relative_project_path} '
    f'--user root '
    f'private-registry.company.com/docker-adv-all/docker-agent-playwright '
    f'sh -c "'
    f'npm config set strict-ssl false && '
    f'npm install -g pnpm nx && '
    f'pnpm nx run {project_name}:{task}"'
)

方案2:改用真正的DinD模式(可选)

如果不想处理路径映射,可以配置GitLab Runner使用独立的DinD服务容器,此时Runner容器和DinD容器共享卷,挂载路径直接用Runner容器内的路径即可:

  1. 在GitLab CI配置中添加DinD服务:
services:
  - name: docker:dind
    command: ["--tls=false"]
variables:
  DOCKER_HOST: tcp://docker:2375
  DOCKER_DRIVER: overlay2
  1. 调整Runner配置,移除挂载宿主机Docker套接字的部分,确保Runner与DinD容器共享/builds卷。

验证步骤

修改后,在CI流水线中添加调试命令确认路径正确性:

echo "Runner内路径: $monorepo_root"
echo "宿主机对应路径: $host_monorepo_root"
ls -la $monorepo_root/packages/frontend/actions/

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:46:01