3. GitLab CI/CD 概述:架构、语法与 Runner 部署

在构建 MTTR 优化方案时,GitLab CI/CD 是管道自动化的核心引擎。本章从架构、配置语法和 Runner 部署三个维度,建立对 GitLab CI 的完整认知,为后续 Runbook 联动设计打下基础。

3.1 GitLab CI 整体架构

GitLab CI 采用协调器-执行器模型,由三个核心组件协同工作:

  • GitLab 实例(Coordinator):负责解析 .gitlab-ci.yml、调度 Job、管理 Pipeline 状态、收集日志与制品。
  • GitLab Runner:独立部署的代理进程,从 Coordinator 拉取 Job 并执行,将结果上报。
  • 代码仓库与 Registry:提供源代码、Docker 镜像、依赖包等运行时资源。
架构要点: Runner 与 Coordinator 之间通过 HTTPS/gRPC 通信,支持轮询(Polling)和 WebSocket 推送两种模式。在 MTTR 场景中,建议启用 WebSocket 模式以减少调度延迟。
GitLab CI 核心架构 GitLab 实例 Coordinator 解析 .gitlab-ci.yml 调度 Job / 管理 Pipeline GitLab Runner 执行器集群 拉取 Job / 上报状态 支持 Docker / Shell / K8s 资源层 代码仓库 Container Registry 制品 / 缓存 通信协议 HTTPS / gRPC 双向通信 | 轮询模式(默认) | WebSocket 推送(低延迟) Pipeline 执行流程 代码 Push 触发 Pipeline 分配 Runner 执行 Job 完成

3.2 .gitlab-ci.yml 基础语法

.gitlab-ci.yml 是定义 CI/CD 管道的 YAML 配置文件,位于项目根目录。以下是最常用的语法元素:

关键字 作用 示例
stages 定义管道阶段及其执行顺序 stages: [build, test, deploy]
job 定义一个任务,包含脚本、阶段、依赖等 build-app: { stage: build, script: make }
script Job 要执行的 Shell 命令 script: echo "Hello"
before_script 每个 Job 执行前运行的公共脚本 before_script: npm install
after_script 每个 Job 执行后运行的清理脚本 after_script: rm -rf tmp/
only / except 控制 Job 在哪些分支或条件下执行 only: [main, tags]
rules 更灵活的 Job 执行条件(推荐替代 only/except) rules: [{ if: '$CI_PIPELINE_SOURCE == "merge_request_event"' }]
artifacts 定义 Job 产生的制品,可传递到后续 Job artifacts: { paths: [dist/] }
cache 缓存依赖文件以加速后续管道 cache: { key: ${CI_COMMIT_REF_SLUG}, paths: [node_modules/] }
variables 定义管道或 Job 级别的环境变量 variables: { DEPLOY_ENV: "staging" }
MTTR 优化提示: 使用 rules 替代 only/except 可以更精确地控制 Runbook 触发条件,例如仅在故障标签(incident)或特定分支上执行诊断 Job。

一个典型的 .gitlab-ci.yml 结构如下:

stages:
  - build
  - test
  - deploy

variables:
  APP_VERSION: "1.0.0"

before_script:
  - echo "Pipeline 开始于 $(date)"

build-job:
  stage: build
  script:
    - make build
    - docker build -t myapp:$APP_VERSION .
  artifacts:
    paths:
      - dist/

test-job:
  stage: test
  script:
    - make test
  only:
    - main
    - merge_requests

deploy-job:
  stage: deploy
  script:
    - kubectl apply -f k8s/deployment.yaml
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual
    - when: never

3.3 Runner 类型与部署模式

GitLab Runner 是实际执行 Job 的代理,根据注册范围和部署方式分为以下类型:

Runner 类型 注册范围 适用场景 MTTR 关联
Shared Runner 整个 GitLab 实例 通用构建、测试,适合开源项目 共享资源,可能存在排队延迟
Group Runner 指定用户组 团队级管道,隔离不同业务线 减少跨组干扰,提升稳定性
Specific Runner 单个项目 专用环境、安全合规要求高的项目 独占资源,适合 Runbook 紧急执行

Runner 支持多种执行器(Executor),决定 Job 的运行环境:

  • Shell:直接在宿主机执行,简单但隔离性差,适合快速诊断脚本。
  • Docker:每个 Job 运行在独立容器中,环境一致性强,是生产环境首选。
  • Kubernetes:动态在 K8s 集群中创建 Pod 执行,弹性伸缩能力强。
  • Docker Machine:自动创建临时虚拟机,适合大规模并行任务。
MTTR 部署建议: 对于 Runbook 联动场景,推荐部署 Specific Runner + Docker 执行器,确保诊断 Job 能快速启动且环境隔离。避免使用 Shared Runner 以免因资源争抢导致管道延迟。
Runner 部署模式对比 Shared Runner 实例级共享 所有项目可用 排队延迟 ⚠️ 适合通用任务 Group Runner 用户组级隔离 组内项目共享 资源可控 适合团队级管道 Specific Runner 项目级独占 零排队延迟 ✅ 环境完全可控 推荐用于 Runbook 执行器对比 Shell Docker Kubernetes Docker Machine 隔离性低,启动快 环境一致,推荐 弹性伸缩,云原生 大规模并行

3.4 Runner 注册与配置

部署 Runner 后,需要向 GitLab 实例注册。注册命令如下:

# 安装 Runner(以 Linux 为例)
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner

# 启动 Runner
sudo gitlab-runner start

# 注册 Runner
sudo gitlab-runner register \
  --url https://gitlab.example.com \
  --registration- YOUR_ \
  --executor docker \
  --docker-image alpine:latest \
  --description "runbook-specific-runner" \
  --tag-list "runbook,diagnosis" \
  --run-untagged="false" \
  --locked="true"
关键参数说明:
  • --tag-list:为 Runner 打标签,Job 可通过 tags 关键字指定使用哪个 Runner。
  • --locked:锁定 Runner 仅用于当前项目,防止被其他项目占用。
  • --run-untagged:设置为 false 确保只有带标签的 Job 才能使用此 Runner。

在 MTTR 场景中,建议为 Runbook 管道配置专用标签,例如 runbook、diagnosis、emergency,并在 .gitlab-ci.yml 中通过 tags 关键字绑定:

runbook-diagnosis:
  stage: diagnosis
  tags:
    - runbook
    - diagnosis
  script:
    - ./runbook/collect-logs.sh
    - ./runbook/analyze-metrics.sh
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
      when: always

通过上述架构、语法和 Runner 部署的配合,可以为 MTTR 优化构建一个低延迟、高可控的 CI/CD 管道基础。下一节将深入如何利用这些能力设计 Runbook 联动管道。