王昭宁/ 高级客户经理

高级客户经理

  • 电话(微信)
    17669512663
  • QQ 号码
    3684528290

stage 自定义挂载卷使用说明

作者 :Gitfox 最后编辑:孟笑宇 于 2026-11-13 14:02:10 阅读:24

流水线卷挂载 YAML 配置说明(volumes / mount)

本文说明如何在流水线 YAML 中声明卷(volumes)以及在任务上挂载卷(mount),包括 plugin 任务的挂载合并规则、内置工作区注意事项和常见报错。

背景

流水线中每个 step 都运行在独立容器里,构建结束即销毁,默认只有内置的 _workspace 卷用于共享克隆下来的源码。用户无法声明自己的卷,也就无法在任务之间共享数据,或把依赖缓存保留到下一次构建。

为此引入两级声明:

  • 阶段级 volumes:声明卷的名称、类型和来源;
  • 任务级 mount:把已声明的卷挂载到当前容器目录。

同一个卷可以被多个任务挂到不同路径。运行时按声明顺序解析卷。

解决的问题

  1. 任务间数据不共享:每个 step 是独立容器,把同一卷挂到多个 step,即可传递构建产物或已下载的依赖。
  2. 依赖无法跨构建复用:使用 host 卷把依赖缓存留在宿主机,下次构建直接命中,省去重复下载。
  3. 配置/凭据注入:把配置文件挂进容器,无需写死在镜像里。
  4. 安全隔离:保留卷名和挂载路径校验,防止覆盖内置卷或工作区,避免错误挂载被静默忽略。

使用手册

1. 基本结构

卷在 CI stage 的 spec.volumes 中声明,然后在 step 的 spec.mount 中按名字引用:

stages:
  - type: ci
    spec:
      volumes:
        - name: cache          # 卷名,stage 内唯一
          type: temp           # host / temp
      steps:
        - name: 写入
          type: run
          spec:
            mount:
              - name: cache
                path: /cache
            script:
              - echo hello > /cache/hello.txt
        - name: 读取
          type: run
          spec:
            mount:
              - name: cache
                path: /cache
            script:
              - cat /cache/hello.txt

要点:

  • volumes 是 stage 级的,只能在 type: ci 的 stage 中声明;同一个 stage 的所有任务共享这些卷,跨 stage 不共享。
  • mount 是 step 级的,写在 step 的 spec 下。
  • 卷通过 name 关联,path 是容器内的挂载路径。

2. 卷定义:volumes

volumes:
  - name: <卷名>
    type: host | temp
    spec:
      ...
字段 必填 说明
name 是 卷名,stage 内唯一;不能使用保留名(见下)
type 是 当前运行器仅支持 host、temp
spec 视类型 host / temp 各自的配置
2.1 type: host

把宿主机目录挂进容器。

volumes:
  - name: m2
    type: host
    spec:
      path: /data/gitfox/m2      # 宿主机上的绝对路径
字段 说明
spec.path 宿主机目录路径
2.2 type: temp

由运行器创建临时卷,stage 结束后清理。

volumes:
  - name: tmp
    type: temp
2.3 保留卷名

以下名字由运行器内部使用,用户不能声明:

_workspace  _addons  _docker_socket  socketDir

声明后会报错:

stage volume name "_workspace" is reserved

3. 挂载:mount

steps:
  - name: 自定义脚本
    type: run | plugin
    spec:
      mount:
        - name: <卷名>
          path: <容器内绝对路径>
字段 必填 说明
name 是 引用的卷名,必须在本 stage 的 volumes 中声明
path 是 容器内挂载路径,必须以 / 开头

规则:

  • 同一个卷可以挂到多个任务、也可以在同一容器内挂到多个路径。
  • 同一任务内挂载路径不能重复;路径会先做规范化(path.Clean),因此 /data/、/a/../data 和 /data 视为同一个路径,重复会报错。

4. 跨任务共享示例

stages:
  - type: ci
    spec:
      volumes:
        - name: tmp
          type: temp
      steps:
        - name: git克隆
          type: plugin
          spec:
            name: scm_git_clone
            mount:
              - name: tmp
                path: /gitfox
            inputs:
              ...
        - name: 自定义脚本
          type: run
          spec:
            mount:
              - name: tmp
                path: /tmp
            script:
              - ls -l /tmp

第一步把内容写进 tmp 卷的 /gitfox,第二步在 /tmp 能看到同一份数据。


5. 内置工作区 /gitfox 与挂载冲突

每个任务默认会追加一个内置工作区挂载:

_workspace -> /gitfox

如果某个任务显式把用户卷挂到了 /gitfox:

  • 用户挂载优先,内置工作区挂载会被跳过,并输出一条 warn 日志;
  • 该任务里的 /gitfox 是用户卷,不再与其他任务共享工作区内容(除非其他任务也挂同一个卷);
  • GITFOX_WORKSPACE 环境变量仍然是 /gitfox,插件仍会往这个路径写;
  • stage 末尾的 clean 任务会操作用户挂载的工作区。

如果你希望多个任务共享同一目录,推荐显式声明一个 temp/host 卷,并在各任务挂载到同一路径:

stages:
  - type: ci
    spec:
      volumes:
        - name: shared
          type: temp
      steps:
        - name: 写入
          type: run
          spec:
            mount:
              - name: shared
                path: /data
            script:
              - echo hi > /data/a.txt
        - name: 读取
          type: run
          spec:
            mount:
              - name: shared
                path: /data
            script:
              - cat /data/a.txt

最佳实践: 编译缓存,构建提速

将编译过程中的依赖缓存在宿主机中,下次构建直接命中,省去重复下载时间,提高编译效率

golang 编译缓存

version: 1
kind: pipeline
spec:
  options:
    clone:
      disabled: true
  stages:
    - id: 0kjuhvvc
      name: 阶段
      desc: ''
      type: ci
      when: ${{ success() }}
      spec:
      # 1. 阶段层声明卷:宿主机目录,跨构建保留
        volumes:
          - name: cache
            type: host
            spec:
              path: /root/tmp/go-cache
        steps:
          - id: wnrv8ek5_scm_git_clone
            when: ${{ success() }}
            name: git克隆
            type: plugin
            spec:
              inputs:
                repository: http://example.com:3000/git/test/go-repo.git
                gitRef: ${{parameters.gitRef}}
                cloneDepth: 1
                cloneDir: ''
              name: scm_git_clone
          - id: r889y3o3_build_go
            when: ${{ success() }}
            name: Golang编译
            type: plugin
            spec:
            # 2. 编译任务挂到 Go 模块缓存目录
              mount:
                - name: cache
                  path: /root/.gvm/pkgsets/go1.26.2/global/pkg/mod # go modules存放目录,挂载至宿主机目录
              inputs:
                compileCommand: pwd && export GOPROXY=https://goproxy.cn,direct && go mod tidy
                workspace: .
                goVersion: 1.26.2
              name: build_go

6.2 编译提速效果

编译时长 是否有缓存 提速
20s 无  
3s 有 快6.7倍

6.3 其他语言缓存目录参考

语言 建议挂载路径 相关环境变量
Go $GOPATH/pkg/mod GOMODCACHE
NodeJs ~/.npm npm_config_cache
Python ~/.cache/pip PIP_CACHE_DIR
Maven ~/.m2/repository -

常见问题

挂载声明会在两处校验:

  1. 触发流水线时:解析、插件/模板展开之后校验,错误直接返回给触发方,不生成 stage/step 记录;
  2. 运行器编译时:CompilerImpl.Compile 开头再次校验,作为最终校验。

常见错误:

报错 原因
stage volume #1: name must not be empty volumes 项缺少 name
stage volume name "_workspace" is reserved 使用了保留卷名
stage volume "cache" is declared more than once 同 stage 内卷名重复
stage volume "cache": volume type "claim" is not supported 使用了不支持的卷类型
step "build": mount must not be empty mount 列表里有空项
step "build": mount path must be absolute: "data" 挂载路径不是绝对路径
step "build": duplicate mount path "/data" 同一任务内路径重复(规范化后)
step "build": mount path "/data" requires a volume name mount 缺少 name
step "build": mount volume "data" is not declared in stage volumes 引用了未声明的卷名
step "git克隆": resolved plugin step type "group" does not support mount 插件展开后的类型不支持挂载

触发阶段的错误会带上 stage 上下文,例如:

stage "stage-1": step "build": mount volume "data" is not declared in stage volumes

Site-Footer
王昭宁 高级客户经理
  • 17669512663
  • 3684528290