CI/CD流水线是DevOps实践的核心基础设施,通过代码提交触发自动构建、测试、部署流程,将软件交付周期从天级压缩到分钟级。本文以GitLab CI为核心,结合Docker容器化技术,搭建一套覆盖代码检查、单元测试、镜像构建、灰度发布、回滚应急的完整流水线。
GitLab Runner部署与流水线架构设计
GitLab Runner是流水线执行引擎,生产环境推荐使用Docker executor隔离构建环境。注册Runner时指定executor类型和标签,便于流水线按标签调度:
# 安装GitLab Runner
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner
# 注册Runner(Docker executor)
sudo gitlab-runner register -n \
--url https://gitlab.example.com \
--registration-token $REGISTRATION_TOKEN \
--executor docker \
--description "shared-docker-runner" \
--docker-image "docker:24.0" \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock \
--tag-list "docker,build,deploy"
流水线架构设计为四个Stage:lint(代码规范检查)、test(单元测试+集成测试)、build(Docker镜像构建推送)、deploy(多环境部署)。每个Stage失败即终止流水线,确保代码质量门禁。.gitlab-ci.yml核心配置:
# .gitlab-ci.yml
stages:
- lint
- test
- build
- deploy
variables:
IMAGE_REGISTRY: registry.example.com
IMAGE_NAME: $CI_PROJECT_NAME
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
# 代码规范检查
lint:code:
stage: lint
image: node:20-alpine
script:
- npm ci
- npm run lint
- npm run type-check
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# 单元测试与覆盖率
test:unit:
stage: test
image: node:20-alpine
script:
- npm ci
- npm run test:coverage
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
paths:
- coverage/
coverage: '/Lines.*?(\d+\.\d+)%/'
# Docker镜像构建与推送
build:image:
stage: build
image: docker:24.0
services:
- docker:24.0-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $IMAGE_REGISTRY
- docker build -t $IMAGE_REGISTRY/$IMAGE_NAME:$IMAGE_TAG -t $IMAGE_REGISTRY/$IMAGE_NAME:latest .
- docker push $IMAGE_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
- docker push $IMAGE_REGISTRY/$IMAGE_NAME:latest
rules:
- if: $CI_COMMIT_BRANCH == "main"
Docker多阶段构建与镜像优化
Dockerfile采用多阶段构建减小镜像体积,构建依赖与运行环境隔离。Node.js应用示例:构建阶段使用完整Node镜像编译TypeScript,运行阶段仅包含dist产物和精简Node运行时:
# Dockerfile 多阶段构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist
RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -s /bin/sh -D appuser
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/main.js"]
镜像构建后使用Trivy进行安全漏洞扫描,严重漏洞阻止发布:
# 安全扫描集成到build stage
scan:security:
stage: build
image: aquasec/trivy:latest
script:
- trivy image --exit-code 1 --severity CRITICAL $IMAGE_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
rules:
- if: $CI_COMMIT_BRANCH == "main"
多环境部署与灰度发布策略
部署策略采用多环境递进:dev(开发环境)自动部署、staging(预发布环境)手动触发、production(生产环境)灰度发布。生产环境使用Kubernetes滚动更新配合流量切分实现灰度:
# .gitlab-ci.yml 部署配置
deploy:staging:
stage: deploy
image: bitnami/kubectl:1.28
environment:
name: staging
script:
- kubectl set image deployment/$IMAGE_NAME app=$IMAGE_REGISTRY/$IMAGE_NAME:$IMAGE_TAG -n staging
- kubectl rollout status deployment/$IMAGE_NAME -n staging --timeout=300s
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
deploy:production:
stage: deploy
image: bitnami/kubectl:1.28
environment:
name: production
script:
# 灰度发布:先部署新版本Pod但不切换流量
- kubectl set image deployment/$IMAGE_NAME app=$IMAGE_REGISTRY/$IMAGE_NAME:$IMAGE_TAG -n production
# 等待新Pod就绪
- kubectl rollout status deployment/$IMAGE_NAME -n production --timeout=300s
# 健康检查
- |
for i in $(seq 1 10); do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://$IMAGE_NAME.production/health)
if [ "$STATUS" != "200" ]; then
echo "Health check failed, rolling back"
kubectl rollout undo deployment/$IMAGE_NAME -n production
exit 1
fi
sleep 5
done
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
故障应急响应与流水线回滚
生产环境部署失败需快速回滚。GitLab CI环境变量保留最近5个版本的镜像TAG,回滚脚本通过kubectl rollout undo恢复上一版本。日志分析方面,部署日志通过Filebeat采集到ELK集群,结合Grafana Loki实现日志流式查询。混沌工程层面定期注入Pod故障、网络延迟验证流水线自愈能力,关键指标包括部署成功率(目标99%)、平均部署时间(目标低于5分钟)、故障恢复时间(MTTR目标低于10分钟)。
流水线稳定性保障措施:Runner节点配置资源水位告警(CPU超过80%、内存超过90%);构建缓存使用GitLab Cache加速npm依赖安装;并发构建限制避免Runner资源争抢。定期审查流水线配置,移除废弃Stage和无效规则,保持配置文件简洁可维护。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/cicd-liu-shui-xian-zi-dong-hua-bu-shu-shi-zhan-gitlabci-yu/