为什么CI/CD流水线是DevOps的基础设施
DevOps实践的核心目标:缩短代码从提交到上线的时间,同时保证质量。手工打包、SSH上传、停服替换的方式,一次发布至少30分钟,且人为操作出错率居高不下。CI/CD流水线将构建、测试、部署全流程自动化,发布时间压缩到分钟级,错误率降低90%以上。
GitLab CI/CD的优势在于与代码仓库深度集成,无需额外搭建Jenkins,.gitlab-ci.yml一个文件定义全部流程,学习成本低、维护简单。
流水线架构设计
一个标准的生产级流水线包含五个阶段:
stages:
- lint # 代码规范检查
- test # 单元测试+集成测试
- build # 构建Docker镜像
- staging # 部署到预发布环境
- production # 部署到生产环境
每个阶段只有前一个阶段全部通过才执行,production阶段设置手动触发,防止未经确认的代码直接上线。
完整的.gitlab-ci.yml配置
stages:
- lint
- test
- build
- staging
- production
variables:
DOCKER_REGISTRY: "registry.example.com"
APP_NAME: "webapp"
lint:
stage: lint
image: node:20-alpine
script:
- npm ci
- npm run lint
- npm run type-check
only:
- merge_requests
- main
test:unit:
stage: test
image: node:20-alpine
script:
- npm ci
- npm run test:unit -- --coverage
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
build:
stage: build
image: docker:24
services:
- docker:24-dind
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
script:
- docker build -t $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA .
- docker push $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA
only:
- main
- tags
staging:
stage: staging
image: alpine:3.18
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$DEPLOY_KEY" | ssh-add -
script:
- ssh deploy@staging.example.com "docker pull $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA && docker stop $APP_NAME 2>/dev/null || true && docker rm $APP_NAME 2>/dev/null || true && docker run -d --name $APP_NAME -p 3000:3000 -e NODE_ENV=staging $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA"
environment:
name: staging
only:
- main
production:
stage: production
image: alpine:3.18
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$DEPLOY_KEY" | ssh-add -
script:
- ssh deploy@prod.example.com "docker pull $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA && docker stop $APP_NAME 2>/dev/null || true && docker rm $APP_NAME 2>/dev/null || true && docker run -d --name $APP_NAME -p 3000:3000 -e NODE_ENV=production $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA"
environment:
name: production
when: manual
only:
- main
Docker镜像构建优化
流水线的构建速度直接影响开发效率。Docker镜像构建慢,往往是因为没有利用好缓存层:
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["node", "dist/main.js"]
关键优化点:package.json和package-lock.json先于源码复制进镜像。依赖不频繁变化,这样源码改动时不会触发npm ci重新安装,构建时间从5分钟降到30秒以内。
故障应急响应与回滚机制
部署失败或上线后发现Bug,快速回滚是生产环境的生命线。在CI/CD流水线中集成回滚Job,手动触发时回滚到上一个稳定版本镜像。核心是每次部署前记录当前运行镜像的tag,回滚时直接拉取并替换。
监控告警体系与流水线集成
部署完成后需要自动验证服务健康状态:
health_check:
stage: .post
image: alpine:3.18
script:
- |
for i in $(seq 1 10); do
STATUS=$(wget -qO- https://app.example.com/health | jq -r '.status')
if [ "$STATUS" = "ok" ]; then
echo "Health check passed"
exit 0
fi
sleep 5
done
echo "Health check failed"
exit 1
健康检查失败时,GitLab Pipeline标记为failed,触发告警通知(通过企业微信、Slack等Webhook)。运维人员收到告警后可立即执行回滚Job。核心运维原则:CI/CD流水线不是一次性的脚本,是持续运行的系统。每次部署后的健康检查、失败时的自动回滚、日志的集中采集,都是保证流水线生产可用的必要组件。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/devops-shi-jian-gitlabcicd-zi-dong-hua-bu-shu-liu-shui-xian/