GitLab CI/CD 是内置于 GitLab 平台的流水线自动化系统——无需安装任何外部工具,只需在仓库根目录添加一个 .gitlab-ci.yml 文件,每次提交代码时就会自动触发构建、测试和部署的完整流程。
需要企业数据解决方案?
自 2019 年起,AlgoData 为企业提供数据工程、分析与 AI 解决方案。
GitLab CI/CD 是什么?

GitLab CI/CD 是原生内置于 GitLab 的持续集成/持续交付平台,完全由仓库根目录下的 .gitlab-ci.yml 配置文件驱动。每当开发者推送代码或创建 Merge Request,GitLab 自动读取该文件,创建一条由多个 Stage(阶段)顺序执行的 Pipeline(流水线),每个 Stage 内可包含一个或多个并行运行的 Job(作业)。
流水线遵循 test → build → deploy 的经典模式。一旦某个 Job 失败,流水线立即停止并通知开发者——"快速失败"原则确保错误在尽可能早的阶段被捕获,防止问题代码进入生产环境。
GitLab 相较于 Jenkins 等独立 CI/CD 工具的核心优势在于:GitLab 将容器镜像仓库、包仓库、安全扫描(SAST、DAST)、环境管理和部署追踪集成于同一平台,大幅减少了团队需要管理的工具数量。
.gitlab-ci.yml 的结构
整个流水线在一个 YAML 文件中定义。以下是一个将 Python 应用部署到 Kubernetes 的实际示例:
1stages:
2 - test
3 - build
4 - deploy
5
6variables:
7 DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
8
9# ── 阶段一:运行测试 ───────────────────────────────────────────
10test:
11 stage: test
12 image: python:3.11
13 script:
14 - pip install -r requirements.txt # 安装依赖
15 - pytest tests/ -v # 运行测试
16 cache:
17 key: ${CI_COMMIT_REF_SLUG}
18 paths:
19 - .cache/pip # 缓存 pip 包,加速后续运行
20
21# ── 阶段二:构建 Docker 镜像并推送到 GitLab 镜像仓库 ──────────
22build:
23 stage: build
24 image: docker:24
25 services:
26 - docker:dind # 启用 Docker-in-Docker
27 script:
28 - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
29 - docker build -t $DOCKER_IMAGE . # 构建镜像
30 - docker push $DOCKER_IMAGE # 推送到仓库
31 only:
32 - main # 仅在 main 分支触发
33
34# ── 阶段三:部署到 Kubernetes(手动确认) ─────────────────────
35deploy:
36 stage: deploy
37 script:
38 - kubectl set image deployment/myapp app=$DOCKER_IMAGE
39 environment:
40 name: production
41 when: manual # 需要人工点击确认
42 only:
43 - main
核心概念说明:
stages— 声明执行顺序。同一 Stage 内的 Job 并行运行;下一个 Stage 只有在上一个 Stage 全部成功后才会启动。variables— 作用于整个流水线的环境变量。GitLab 还提供内置预定义变量,如$CI_COMMIT_SHA、$CI_REGISTRY_IMAGE、$CI_COMMIT_REF_SLUG。image— 用作 Job 执行环境的 Docker 镜像,每个 Job 可使用不同的镜像。services— 与 Job 并行运行的辅助容器(例如:docker:dind允许在容器内构建 Docker 镜像)。cache— 在多次流水线运行之间持久保存的目录,用于加速构建(.cache/pip、node_modules/)。artifacts— Job 产生的输出文件,可传递给下游 Job 或在流水线完成后供下载。only/rules— 控制 Job 触发条件(仅在main分支运行、仅在打 tag 时运行等)。when: manual— Job 不会自动运行,需要有权限的人员在界面点击执行按钮——适合生产环境部署的审批门控。environment— 将 Job 关联到 GitLab Environments 中的命名环境,支持部署历史追踪和一键回滚。
GitLab Runner

GitLab Runner 是安装在服务器(或容器/Kubernetes Pod)上的代理软件,负责从 GitLab 服务器接收 Job 并执行。Runner 持续轮询 GitLab,接收分配的 Job,克隆源代码,在已配置的执行器中运行脚本,最后将日志和退出码返回给 GitLab。
共享 Runner 与专用 Runner
| 共享 Runner | 专用 Runner | |
|---|---|---|
| 管理方 | GitLab(或组管理员) | 您的团队 |
| 使用范围 | 实例内所有项目 | 特定项目或群组 |
| 资源 | 共享,高峰期可能排队 | 独享,无需排队 |
| 费用 | 按 CI 分钟计费 | 自有服务器成本 |
| 适合场景 | 小型项目、公共仓库 | 重度生产工作负载 |
Docker 执行器——最常用的选择
Docker 执行器在全新的 Docker 容器中运行每个 Job,确保每次运行的环境完全隔离且干净。这是大多数场景下推荐的执行器。
使用 Docker 执行器注册专用 Runner:
1# 在 Ubuntu/Debian 上安装 GitLab Runner
2curl -L --output /usr/local/bin/gitlab-runner \
3 "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64"
4chmod +x /usr/local/bin/gitlab-runner
5
6# 注册 Runner(在 Settings → CI/CD → Runners 获取 Token)
7gitlab-runner register \
8 --url "https://gitlab.com/" \
9 --registration-token "YOUR_REGISTRATION_TOKEN" \
10 --executor "docker" \
11 --docker-image "alpine:latest" \
12 --description "my-docker-runner" \
13 --tag-list "docker,production"
注册完成后,Runner 出现在 Settings → CI/CD → Runners 中并开始接收 Job。使用**标签(tag)**将特定 Job 路由到特定 Runner——例如,生产部署 Job 只允许在打了 production 标签、部署在内网的 Runner 上执行。
GitLab vs GitHub Actions vs Jenkins

| 对比维度 | GitLab CI/CD | GitHub Actions | Jenkins |
|---|---|---|---|
| 配置复杂度 | 低(内置) | 低(内置) | 高(需安装配置) |
| 免费自托管 | 是(GitLab CE) | 否(需 GitHub Enterprise) | 是(开源) |
| 免费云端额度 | 400 分钟/月 | 2,000 分钟/月 | 无 |
| 内置容器镜像仓库 | 是 | 是(GHCR) | 否 |
| 内置安全扫描 | 是(SAST/DAST) | 部分(CodeQL) | 插件 |
| 配置语法 | YAML (.gitlab-ci.yml) | YAML (.github/workflows/) | Groovy (Jenkinsfile) |
| 市场/插件生态 | GitLab 模板 | 20,000+ Actions | 1,800+ 插件 |
| 最适合 | 自托管、一体化平台 | GitHub 生态 | 企业本地部署 |
何时选择 GitLab CI/CD:
- 项目需要将整个技术栈(代码 + CI/CD + 镜像仓库)自托管于本地环境。
- 团队需要在同一平台内整合安全扫描、合规管理和审计追踪。
- 金融科技、银行、医疗健康等行业需要 100% 的数据主权,所有数据必须保留在内部服务器。
何时选择 GitHub Actions:
- 仓库已在 GitHub 上,希望零配置接入流水线。
- 开源项目需要充裕的免费 CI 分钟数。
- 需要与 GitHub 生态深度集成(Dependabot、CodeQL、GitHub Packages)。
何时选择 Jenkins:
- 已在 Jenkins 插件和 Groovy 流水线上积累大量投资的传统企业环境。
- 需要与多种代码管理系统集成(Bitbucket Server、Perforce、SVN)。
最佳实践
1. 缓存依赖以加速构建
1# Python——缓存 pip 包
2cache:
3 key: ${CI_COMMIT_REF_SLUG}-pip
4 paths:
5 - .cache/pip
6 policy: pull-push
7
8# Node.js——缓存 node_modules
9cache:
10 key:
11 files:
12 - package-lock.json
13 paths:
14 - node_modules/
对于只读缓存的 Job,使用 policy: pull,避免每次 Job 结束后不必要的缓存上传。
2. 使用 needs: 实现并行化(DAG 流水线)
1test-unit:
2 stage: test
3 script: pytest tests/unit/ # 运行单元测试
4
5test-integration:
6 stage: test
7 script: pytest tests/integration/ # 运行集成测试
8
9build:
10 stage: build
11 needs: [test-unit] # test-unit 完成即可开始,无需等待 test-integration
12 script: docker build .
needs: 打破了传统的顺序 Stage 模型,让 build Job 在 test-unit 完成后立即启动,无需等待 test-integration,从而显著缩短流水线总耗时。
3. 保护生产环境
在 Settings → CI/CD → Environments → production 中配置:
- 必要审批人数:生产部署需至少 1-2 名指定审批人确认。
- 受保护分支:仅
main或release/*分支可触发生产部署。 - 部署冻结期:在流量高峰或重要假日期间禁止部署。
4. 启用内置 SAST 扫描
1include:
2 - template: Security/SAST.gitlab-ci.yml # 引入官方 SAST 模板
3
4sast:
5 stage: test
6 variables:
7 SAST_EXCLUDED_PATHS: "tests/, docs/" # 排除测试和文档目录
GitLab SAST 会自动为项目使用的语言选择合适的分析器(Python 使用 Bandit、JS/TS 使用 Semgrep、Java 使用 SpotBugs),无需额外配置。
5. 为生产部署设置手动审批门控
始终将 when: manual 与 environment: production 结合使用。这在 GitLab 界面中创建了一个清晰的确认按钮,并记录完整的审计日志——谁触发了部署以及触发时间。
实际应用场景
初创企业——快速启动,无需专职运维
初创企业可以免费使用 GitLab.com(每月 400 分钟),配置一条基础的三阶段流水线:测试 → 构建 Docker 镜像 → 通过 SSH 部署到 VPS。所有配置集中在一个 .gitlab-ci.yml 文件中,从第一天起就无需专职 DevOps 工程师。随着规模扩大,只需对现有流水线结构做最小改动即可升级为 Kubernetes 部署。
银行与金融科技——自托管满足合规要求
金融机构需要将源代码、制品和日志完全保留在自有基础设施中。自托管 GitLab CE 实例提供:
- 无流水线分钟限制 — 在内部服务器上自由运行流水线。
- 数据不离开数据中心 — 源代码、Docker 镜像和流水线日志均保存在内部服务器。
- 完整审计日志 — GitLab 记录每一个操作:谁提交了代码、谁批准了 Merge Request、谁触发了部署以及触发时间。
- 集成 SAST 和密钥检测 — 意外提交到仓库的凭证信息在流水线内即刻被标记。
核心银行系统的典型流水线:sast → 单元测试 → 集成测试 → 构建镜像 → 推送到内部镜像仓库 → 部署预生产环境(自动)→ 部署生产环境(手动,需2人审批)。
总结: 当您需要一个一体化平台——从代码管理到 CI/CD、容器镜像仓库和安全扫描——尤其是对数据主权要求严格的自托管项目,GitLab CI/CD 是极具竞争力的选择。从一个简单的 .gitlab-ci.yml 开始,随着团队成熟度的提升,逐步引入缓存、并行 Job 和手动审批门控。

