GitLab CI/CD
核心概念
GitLab CI/CD 通过项目根目录的 .gitlab-ci.yml 配置流水线。
| 概念 | 说明 |
|---|---|
| Pipeline | 一次构建的完整流程,由多个 Stage 组成 |
| Stage | 同一阶段的 Job 并行执行,阶段之间串行 |
| Job | 最小执行单元,运行在 Runner 上 |
| Runner | 执行 Job 的代理(Shared / Group / Project) |
| Artifact | Job 产出物,可在后续 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 Pod | K8s 环境 |
| 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 有什么区别?
答案:
| 特性 | Cache | Artifact |
|---|---|---|
| 用途 | 加速构建(依赖缓存) | 传递构建产物 |
| 生命周期 | 跨 Pipeline 复用 | 当前 Pipeline 内共享 |
| 可靠性 | 尽力而为(可能失效) | 保证可用 |
| 下载 | 不可从 UI 下载 | 可从 UI 下载 |
| 示例 | node_modules、.m2 | 测试报告、构建产物 |
Q2: 如何实现 MR 自动部署预览环境?
答案:
使用 GitLab Review Apps:
- MR 创建时触发部署到动态环境(
review/$CI_MERGE_REQUEST_IID) - MR 页面显示预览链接
- MR 合并或关闭时,通过
on_stopJob 自动清理 - 设置
auto_stop_in自动超时清理