4. CI/CD 变量类型:分类与优先级

在 GitLab CI 流水线中,变量是驱动参数化配置的核心。理解变量的分类体系与优先级规则,是构建可复用、可维护服务目录的基础。本章将系统梳理 GitLab CI 变量的四种主要类型,并解析其覆盖与合并机制。

4.1 变量分类全景

GitLab CI 变量按作用域与存储方式可分为以下四类:

变量类型 作用域 存储位置 典型用途
项目变量 单个项目 项目设置 → CI/CD → 变量 数据库连接串、部署令牌、环境专属配置
组变量 组内所有项目 组设置 → CI/CD → 变量 共享凭证、通用构建参数、合规性标记
实例变量 整个 GitLab 实例 管理员 → 设置 → CI/CD → 变量 全局代理、镜像仓库地址、许可证密钥
文件变量 按项目/组/实例 与上述相同,类型选 "File" 证书文件、SSH 私钥、Kubeconfig
实践建议:在服务目录中,优先将环境无关的通用参数(如镜像仓库域名)定义为组变量或实例变量,将环境敏感参数(如数据库密码)定义为项目变量,实现职责分离。

4.2 变量优先级规则

当多个作用域定义了同名变量时,GitLab 按照以下优先级从高到低进行覆盖:

  1. 触发变量(手动流水线、API 触发时传入)
  2. 作业级变量(variables 关键字在 job 内定义)
  3. 流水线级变量(variables 关键字在 .gitlab-ci.yml 顶层定义)
  4. 项目变量(UI 或 API 设置)
  5. 组变量(父组优先于子组)
  6. 实例变量
  7. 预定义变量(如 CI_COMMIT_REF_NAME)
常见陷阱:组变量与项目变量同名时,项目变量始终覆盖组变量,无论组层级高低。若需强制组变量生效,应使用 environment_scope 或避免在项目层定义同名变量。

4.3 变量优先级与覆盖流程

下图展示了变量从定义到最终生效的完整解析路径:

GitLab CI 变量优先级解析流程 ① 触发变量(最高优先级) ② 作业级变量 ③ 流水线级变量 ④ 项目变量 ⑤ 组变量 ⑥ 实例变量 优先级规则 高优先级覆盖低优先级 同名变量仅生效最高层 文件变量遵循同优先级 文件变量说明 以文件形式注入变量值 路径:$CI_PROJECT_DIR/变量名 适用于证书、密钥等二进制

4.4 文件变量的特殊处理

文件变量(Type: File)在存储与引用方式上与普通变量有显著差异:

  • 存储方式:变量值被写入一个临时文件,而非直接作为字符串注入。
  • 引用方式:通过 $变量名 获取的是文件路径,而非文件内容。
  • 读取内容:需使用 cat $变量名 或 $(cat $变量名) 获取实际值。
  • 典型场景:SSH 私钥、Kubernetes kubeconfig、TLS 证书、GPG 密钥。
服务目录最佳实践:在服务目录模板中,将证书类参数统一声明为文件变量,并在 before_script 中通过 cat 写入标准路径,避免硬编码。

4.5 变量作用域与可见性对比

特性 项目变量 组变量 实例变量 文件变量
可见范围 单个项目 组及子组所有项目 整个实例 同左(按设置范围)
是否可被覆盖 是(仅被更高优先级覆盖) 是(被项目变量覆盖) 是(被组/项目覆盖) 是(遵循同优先级规则)
是否支持掩码 是 是 是 否(文件内容不掩码)
环境作用域 支持 支持 不支持 支持
API 管理 支持 支持 支持 支持

4.6 变量优先级在服务目录中的应用

在服务目录参数配置中,合理利用变量优先级可实现灵活的配置覆盖:

# .gitlab-ci.yml 服务目录模板示例
variables:
  DEPLOY_ENV: "staging"          # 流水线级默认值
  IMAGE_TAG: "latest"

deploy-job:
  variables:
    DEPLOY_ENV: "production"     # 作业级覆盖流水线级
  script:
    - echo "Deploying to $DEPLOY_ENV"
    - echo "Image tag: $IMAGE_TAG"
  environment:
    name: $DEPLOY_ENV
层级覆盖策略:在服务目录中,建议将全局默认值定义为组变量,项目定制值定义为项目变量,临时覆盖值通过流水线触发变量传入。这样既保证了基线一致性,又保留了灵活覆盖的能力。

4.7 变量优先级与合并行为

理解变量优先级后,还需掌握同名变量的合并行为:

  • 完全覆盖:高优先级变量直接替换低优先级同名变量,不会合并。
  • 数组变量:若变量值为数组(如 VAR: ["a", "b"]),高优先级数组会整体替换低优先级数组。
  • 环境作用域:当变量设置了 environment_scope,仅匹配该环境的作业才会使用该变量,优先级规则在匹配范围内生效。

下图展示了不同作用域变量在流水线中的合并与覆盖关系:

变量作用域合并与覆盖关系 实例变量层(全局默认值) GLOBAL_PROXY=http://proxy.company.com | DEFAULT_REGISTRY=registry.company.com 组变量层(团队共享值) TEAM_NAMESPACE=backend-team | CI_IMAGE=python:3.11-slim 项目变量层(项目定制值) DB_HOST=prod-db.internal | =${PROJECT_} 流水线级变量层(YAML 定义) DEPLOY_ENV=staging | IMAGE_TAG=${CI_COMMIT_SHORT_SHA} 覆盖 覆盖 覆盖
关键提醒:当组变量与项目变量同名时,项目变量会完全覆盖组变量,不会进行值合并。若需要组变量作为后备值,应在项目层不定义该变量,或使用 environment_scope 进行环境隔离。