跳到主要内容

GitLab CI/CD

核心概念

GitLab CI/CD 通过项目根目录的 .gitlab-ci.yml 配置流水线。

概念说明
Pipeline一次构建的完整流程,由多个 Stage 组成
Stage同一阶段的 Job 并行执行,阶段之间串行
Job最小执行单元,运行在 Runner 上
Runner执行 Job 的代理(Shared / Group / Project)
ArtifactJob 产出物,可在后续 Job 中使用
Cache跨 Pipeline 复用的文件(如 node_modules)

完整示例

.gitlab-ci.yml
# 默认配置
default:
image: node:20-alpine
# 全局缓存
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store/
policy: pull

# 定义阶段顺序
stages:
- lint
- test
- build
- deploy

# 全局变量
variables:
REGISTRY: registry.gitlab.com/$CI_PROJECT_PATH
PNPM_STORE: .pnpm-store

# ===== 代码检查 =====
lint:
stage: lint
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store/
policy: pull-push # 首次构建同时更新缓存
script:
- corepack enable
- pnpm install --frozen-lockfile --store-dir $PNPM_STORE
- pnpm lint
- pnpm type-check
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"

# ===== 单元测试 =====
test:unit:
stage: test
script:
- corepack enable
- pnpm install --frozen-lockfile --store-dir $PNPM_STORE
- pnpm test -- --coverage
coverage: '/Statements\s*:\s*(\d+\.?\d*)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
paths:
- coverage/
expire_in: 7 days

# ===== 构建 Docker 镜像 =====
build:docker:
stage: build
image: docker:24
services:
- docker:24-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build
--cache-from $REGISTRY:latest
--tag $REGISTRY:$CI_COMMIT_SHORT_SHA
--tag $REGISTRY:latest .
- docker push $REGISTRY:$CI_COMMIT_SHORT_SHA
- docker push $REGISTRY:latest
rules:
- if: $CI_COMMIT_BRANCH == "main"

# ===== 部署预发布 =====
deploy:staging:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl config use-context staging
- kubectl set image deployment/myapp
myapp=$REGISTRY:$CI_COMMIT_SHORT_SHA -n staging
- kubectl rollout status deployment/myapp -n staging --timeout=300s
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"

# ===== 部署生产(手动) =====
deploy:production:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl config use-context production
- kubectl set image deployment/myapp
myapp=$REGISTRY:$CI_COMMIT_SHORT_SHA -n production
- kubectl rollout status deployment/myapp -n production --timeout=300s
environment:
name: production
url: https://example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual # 手动触发
needs: ["deploy:staging"] # 依赖 staging 部署成功

Runner 配置

# 安装 GitLab Runner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner

# 注册 Runner
sudo gitlab-runner register \
--url https://gitlab.com/ \
--registration-token $TOKEN \
--executor docker \
--docker-image alpine:latest \
--description "docker-runner" \
--tag-list "docker,linux"
Executor说明适用场景
Docker每个 Job 运行在 Docker 容器通用场景(推荐)
Shell直接在 Runner 宿主机执行需要宿主机资源
Kubernetes每个 Job 运行在 K8s PodK8s 环境
Docker Machine自动创建/销毁 Docker 宿主机弹性伸缩

关键特性

includes 与模板复用

.gitlab-ci.yml
# 引入共享模板
include:
- project: 'devops/ci-templates'
ref: main
file: '/templates/docker-build.yml'
- local: '.gitlab/ci/test.yml'
- template: Security/SAST.gitlab-ci.yml # 官方模板

环境与审批

deploy:production:
environment:
name: production
url: https://example.com
# 环境可配置 Protected → 需要审批
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
allow_failure: false # 阻塞后续 Job

动态环境(Review Apps)

deploy:review:
stage: deploy
script:
- deploy-to-k8s --namespace review-$CI_MERGE_REQUEST_IID
environment:
name: review/$CI_MERGE_REQUEST_IID
url: https://$CI_MERGE_REQUEST_IID.review.example.com
on_stop: stop:review # 关联清理 Job
auto_stop_in: 1 week # 自动清理
rules:
- if: $CI_MERGE_REQUEST_IID

stop:review:
stage: deploy
script:
- kubectl delete namespace review-$CI_MERGE_REQUEST_IID
environment:
name: review/$CI_MERGE_REQUEST_IID
action: stop
rules:
- if: $CI_MERGE_REQUEST_IID
when: manual

常见面试问题

Q1: GitLab CI 的 cache 和 artifact 有什么区别?

答案

特性CacheArtifact
用途加速构建(依赖缓存)传递构建产物
生命周期跨 Pipeline 复用当前 Pipeline 内共享
可靠性尽力而为(可能失效)保证可用
下载不可从 UI 下载可从 UI 下载
示例node_modules.m2测试报告、构建产物

Q2: 如何实现 MR 自动部署预览环境?

答案

使用 GitLab Review Apps

  1. MR 创建时触发部署到动态环境(review/$CI_MERGE_REQUEST_IID
  2. MR 页面显示预览链接
  3. MR 合并或关闭时,通过 on_stop Job 自动清理
  4. 设置 auto_stop_in 自动超时清理

相关链接