GitLab CI/CD 流水线
概览
创建全面的 GitLab CI/CD 流水线,自动化构建、测试和部署,使用 GitLab Runner 基础设施和容器执行。
何时使用
- GitLab 仓库 CI/CD 设置
- 多阶段构建流水线
- Docker 仓库集成
- Kubernetes 部署
- 审核应用部署
- 缓存优化
- 依赖管理
实施示例
1. 完整流水线配置
# .gitlab-ci.yml
image: node:18-alpine
variables:
DOCKER_DRIVER: overlay2
FF_USE_FASTZIP: "true"
stages:
- 代码检查
- 测试
- 构建
- 安全
- 部署审核
- 部署生产
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
代码检查:
stage: 代码检查
script:
- npm install
- npm run lint
- npm run format:check
artifacts:
reports:
codequality: code-quality-report.json
expire_in: 1周
单元测试:
stage: 测试
script:
- npm install
- npm run test:coverage
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
junit: test-results.xml
paths:
- coverage/
expire_in: 1周
coverage: '/Coverage: \d+\.\d+%/'
集成测试:
stage: 测试
services:
- postgres:13
- redis:7
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password
script:
- npm run test:integration
only:
- merge_requests
- main
构建:
stage: 构建
image: docker:latest
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
REGISTRY: registry.gitlab.com
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
only:
- main
- tags
安全扫描:
stage: 安全
image: alpine:latest
script:
- apk add --no-cache git
- git clone https://github.com/aquasecurity/trivy.git
- ./trivy image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
allow_failure: true
部署审核:
stage: 部署审核
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.review.example.com
auto_stop_in: 1周
script:
- helm upgrade --install review-$CI_COMMIT_REF_SLUG ./chart
--set image.tag=$CI_COMMIT_SHA
--set environment=review
only:
- merge_requests
部署生产:
stage: 部署生产
environment:
name: production
url: https://example.com
script:
- helm upgrade --install prod ./chart
--set image.tag=$CI_COMMIT_SHA
--set environment=production
only:
- main
when: manual
2. GitLab Runner 配置
#!/bin/bash
# install-runner.sh
# 注册 GitLab Runner
gitlab-runner register \
--url https://gitlab.com/ \
--registration-token $RUNNER_TOKEN \
--executor docker \
--docker-image alpine:latest \
--docker-privileged \
--docker-volumes /certs/client \
--description "Docker Runner" \
--tag-list "docker,linux" \
--run-untagged=false \
--locked=false \
--access-level not_protected
# 启动 runner
gitlab-runner start
3. Docker 层缓存优化
# .gitlab-ci.yml
stages:
- 构建
构建镜像:
stage: 构建
image: docker:latest
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# 拉取之前的镜像用于缓存
- docker pull $CI_REGISTRY_IMAGE:latest || true
# 带缓存构建
- docker build
--cache-from $CI_REGISTRY_IMAGE:latest
--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--tag $CI_REGISTRY_IMAGE:latest
.
# 推送镜像
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
cache:
key: ${CI_COMMIT_REF_SLUG}-docker
paths:
- .docker/
4. 多项目流水线
# .gitlab-ci.yml
stages:
- 构建
- 测试
- 部署
构建:后端:
stage: 构建
script:
- cd backend && npm run build
artifacts:
paths:
- backend/dist/
构建:前端:
stage: 构建
script:
- cd frontend && npm run build
artifacts:
paths:
- frontend/dist/
测试:后端:
stage: 测试
needs: ["构建:后端"]
script:
- cd backend && npm test
artifacts:
reports:
junit: backend/test-results.xml
测试:前端:
stage: 测试
needs: ["构建:前端"]
script:
- cd frontend && npm test
artifacts:
reports:
junit: frontend/test-results.xml
部署:
stage: 部署
needs: ["测试:后端", "测试:前端"]
script:
- echo "Deploying backend and frontend..."
when: manual
5. Kubernetes 部署
# .gitlab-ci.yml
部署-k8s:
stage: 部署
image: alpine/k8s:latest
script:
- mkdir -p $HOME/.kube
- echo $KUBE_CONFIG_ENCODED | base64 -d > $HOME/.kube/config
- chmod 600 $HOME/.kube/config
# 更新部署中的镜像
- kubectl set image deployment/app-deployment
app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
-n production
# 等待滚动更新
- kubectl rollout status deployment/app-deployment -n production
environment:
name: production
kubernetes:
namespace: production
only:
- main
when: manual
6. 性能测试阶段
# .gitlab-ci.yml
性能测试:
stage: 测试
image: grafana/k6:latest
script:
- k6 run tests/performance.js
artifacts:
reports:
performance: performance-results.json
expire_in: 1周
allow_failure: true
only:
- main
- merge_requests
7. 语义化版本控制的发布流水线
# .gitlab-ci.yml
发布:
stage: 部署生产
image: node:18-alpine
script:
- npm install -g semantic-release @semantic-release/gitlab
# 配置 git
- git config user.email "ci@example.com"
- git config user.name "CI Bot"
# 运行 semantic-release
- semantic-release
only:
- main
when: manual
最佳实践
✅ 执行
- 使用阶段来组织流水线流程
- 实施依赖缓存
- 使用工件存储测试报告
- 设置适当的缓存键
- 使用
only和except实施条件执行 - 使用
needs:表示作业依赖 - 使用
expire_in清理工件 - 使用 Docker 以获得一致的环境
- 实施安全扫描阶段
- 为作业设置资源限制
- 使用合并请求流水线
❌ 不要
- 并行可测试时串行运行测试
- 不必要地缓存一切
- 无限期地保留大工件
- 在配置文件中存储机密
- 无必要地运行特权 Docker
- 跳过安全扫描
- 忽略流水线失败
- 无适当控制地使用
only: [main]
Gitlab Runner 执行器类型
# Docker 执行器(推荐)
gitlab-runner register --executor docker
# Kubernetes 执行器
gitlab-runner register --executor kubernetes
# Shell 执行器(本地)
gitlab-runner register --executor shell
# Machine 执行器(用于自动扩展)
gitlab-runner register --executor machine