2. GitLab CI 流水线架构:Pipeline、Job、Stage 的基本概念、流水线执行流程、常见触发方式(Push/MR/Schedule)
2.1 核心概念:Pipeline、Stage、Job
GitLab CI 流水线由三个层级构成:Pipeline(流水线)、Stage(阶段) 和 Job(作业)。理解这三者的关系是配置 CI 的基础。
| 层级 | 定义 | 关键特征 |
|---|---|---|
| Pipeline | 一次完整的 CI/CD 执行过程,包含多个 Stage 和 Job。 | 由触发事件(如 Push、MR)创建;拥有唯一 ID;全局状态(passed/failed)。 |
| Stage | Pipeline 内的逻辑阶段,用于组织 Job 的执行顺序。 | 同一 Stage 内的 Job 默认并行执行;Stage 之间串行执行;常用阶段:build、test、deploy。 |
| Job | Stage 内的最小执行单元,定义具体的命令、镜像、环境。 | 每个 Job 运行在独立 Runner 上;可配置 artifacts、cache、rules;Job 名称必须唯一。 |
SLI 口径提示: 在定义 SLI 时,Pipeline 级别关注“流水线成功率”和“流水线时长”;Stage 级别关注“阶段阻塞率”;Job 级别关注“作业重试次数”和“作业超时率”。不同层级对应不同的 SLO 目标。
2.2 流水线执行流程
一次典型的 GitLab CI 流水线执行流程如下:
- 触发事件:Push、Merge Request、Schedule 等事件发生。
- 创建 Pipeline:GitLab 根据
.gitlab-ci.yml解析配置,生成 Pipeline 实例。 - Stage 顺序执行:按
stages定义顺序,依次进入每个 Stage。 - Job 并行/串行:同一 Stage 内的 Job 并行执行;所有 Job 成功后进入下一 Stage。
- Runner 分配:GitLab 将 Job 分配给可用的 Runner(共享/特定/组 Runner)。
- Job 执行:Runner 拉取镜像、执行脚本、上传 artifacts。
- 状态汇总:所有 Job 完成后,Pipeline 状态更新为 passed/failed/canceled。
2.3 常见触发方式
GitLab CI 支持多种触发方式,每种方式对应不同的 SLI 口径和配置策略。
| 触发方式 | 触发条件 | 典型场景 | SLI 关注点 |
|---|---|---|---|
| Push | 代码推送到仓库(任意分支或指定分支)。 | 开发提交代码后自动触发构建和单元测试。 | Push 触发成功率、Push 到 Pipeline 创建延迟。 |
| Merge Request (MR) | 创建或更新 MR 时触发。 | 代码审查前自动运行集成测试、代码质量检查。 | MR 流水线通过率、MR 流水线平均时长。 |
| Schedule | 按 Cron 表达式定时触发。 | 每日构建、夜间回归测试、定期安全扫描。 | 定时任务成功率、定时任务超时率。 |
| Manual | 手动点击“Run Pipeline”按钮触发。 | 生产环境部署、手动回滚、特殊环境构建。 | 手动触发频率、手动触发成功率。 |
| API | 通过 GitLab API 调用触发。 | 外部系统集成、自动化运维工具触发。 | API 触发成功率、API 触发响应时间。 |
实战案例: 某团队配置 Push 触发仅对
main 和 develop 分支生效,MR 触发对所有分支生效,Schedule 触发每天凌晨 2:00 执行全量回归测试。通过区分触发方式,可以分别统计“开发分支流水线成功率”和“回归测试流水线成功率”,从而制定差异化的 SLO。
2.4 触发方式配置示例
以下 .gitlab-ci.yml 片段展示了三种常见触发方式的配置方法:
# Push 触发:仅 main 和 develop 分支
build-job:
stage: build
script:
- echo "Building..."
rules:
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
when: always
# MR 触发:所有 MR 事件
test-job:
stage: test
script:
- echo "Running tests..."
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: always
# Schedule 触发:每天凌晨 2:00
nightly-regression:
stage: test
script:
- echo "Running nightly regression..."
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: always
only:
- schedules
注意: 使用
rules 关键字时,务必注意条件顺序。GitLab 按顺序匹配第一条满足的规则,若未匹配到任何规则,Job 默认不添加到 Pipeline 中。建议在规则末尾添加 when: never 作为兜底。
2.5 触发方式与 SLI 口径映射
在 SLI 口径设计中,不同触发方式需要独立统计,避免数据混叠。以下为推荐的口径映射:
| SLI 指标 | Push 口径 | MR 口径 | Schedule 口径 |
|---|---|---|---|
| 流水线成功率 | Push 触发的 Pipeline 中 passed 数量 / 总数 | MR 触发的 Pipeline 中 passed 数量 / 总数 | Schedule 触发的 Pipeline 中 passed 数量 / 总数 |
| 流水线平均时长 | Push 触发的 Pipeline 总时长 / 总数 | MR 触发的 Pipeline 总时长 / 总数 | Schedule 触发的 Pipeline 总时长 / 总数 |
| Job 重试率 | Push 触发的 Job 重试次数 / Job 总数 | MR 触发的 Job 重试次数 / Job 总数 | Schedule 触发的 Job 重试次数 / Job 总数 |
2.6 流水线架构最佳实践
- Stage 数量控制:建议 3~6 个 Stage,过多 Stage 会增加串行等待时间,降低流水线效率。
- Job 粒度:每个 Job 只做一件事(单一职责),便于定位失败原因和重试。
- 触发方式隔离:不同触发方式使用不同的
rules条件,避免 Job 被错误触发。 - SLI 标签化:在 Job 中通过
tags或variables标记触发源,便于后续 SLI 数据采集。 - 超时设置:为每个 Job 设置合理的
timeout值,防止 Job 无限挂起。
参数配置建议: 在
.gitlab-ci.yml 中通过 variables 定义全局超时和重试策略,避免在每个 Job 中重复配置。例如:variables: CI_TIMEOUT: "30m" 和 retry: 2。