CI/CD基础:持续集成与部署
CI/CD基础:持续集成与部署
什么是CI/CD
CI/CD是现代软件开发的核心实践,通过自动化流程提高交付效率和代码质量。
- CI(持续集成):开发人员频繁合并代码,自动构建和测试
- CD(持续交付):代码随时可以部署到生产环境
- CD(持续部署):通过所有测试的代码自动部署到生产环境
CI/CD流程设计
典型流水线
代码提交 → 代码检查 → 单元测试 → 构建 → 集成测试 → 部署测试环境 → 验收测试 → 部署生产环境
阶段定义
stages:
- checkout: 拉取代码
- lint: 代码规范检查
- test: 单元测试
- build: 构建镜像
- scan: 安全扫描
- deploy-staging: 部署测试环境
- integration-test: 集成测试
- deploy-production: 部署生产环境
- notify: 通知
流水线配置示例
简单的CI流程
# .gitlab-ci.yml
stages:
- test
- build
variables:
DOCKER_IMAGE: myapp
test:
stage: test
image: node:18
script:
- npm ci
- npm run lint
- npm test
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $DOCKER_IMAGE:$CI_COMMIT_SHA .
- docker tag $DOCKER_IMAGE:$CI_COMMIT_SHA $DOCKER_IMAGE:latest
- docker push $DOCKER_IMAGE:$CI_COMMIT_SHA
- docker push $DOCKER_IMAGE:latest
only:
- main
完整的CI/CD流程
# .gitlab-ci.yml
stages:
- lint
- test
- build
- deploy-staging
- integration-test
- deploy-production
variables:
IMAGE: registry.example.com/myapp
KUBE_NAMESPACE: production
lint:
stage: lint
image: node:18
script:
- npm ci
- npm run lint
test:
stage: test
image: node:18
services:
- postgres:14
- redis:7
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test
POSTGRES_PASSWORD: test
DATABASE_URL: postgres://test:test@postgres/test_db
REDIS_URL: redis://redis:6379
script:
- npm ci
- npm run test:unit
- npm run test:integration
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $IMAGE:$CI_COMMIT_SHA .
- docker push $IMAGE:$CI_COMMIT_SHA
only:
- main
deploy-staging:
stage: deploy-staging
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/myapp myapp=$IMAGE:$CI_COMMIT_SHA -n staging
- kubectl rollout status deployment/myapp -n staging --timeout=300s
environment:
name: staging
only:
- main
integration-test:
stage: integration-test
image: curlimages/curl:latest
script:
- |
for i in 1 2 3 4 5; do
if curl -sf http://staging.myapp.com/health; then
echo "Health check passed"
exit 0
fi
echo "Attempt $i failed, retrying..."
sleep 10
done
echo "Health check failed"
exit 1
deploy-production:
stage: deploy-production
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/myapp myapp=$IMAGE:$CI_COMMIT_SHA -n production
- kubectl rollout status deployment/myapp -n production --timeout=600s
environment:
name: production
when: manual
only:
- main
Jenkins Pipeline
// Jenkinsfile
pipeline {
agent any
environment {
IMAGE = 'registry.example.com/myapp'
COMMIT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Test') {
steps {
sh 'npm ci'
sh 'npm run test'
}
}
stage('Build') {
steps {
sh "docker build -t ${IMAGE}:${COMMIT} ."
sh "docker push ${IMAGE}:${COMMIT}"
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh "kubectl set image deployment/myapp myapp=${IMAGE}:${COMMIT}"
}
}
}
post {
success {
slackSend channel: '#devops', message: "Build succeeded: ${env.JOB_NAME}"
}
failure {
slackSend channel: '#devops', message: "Build failed: ${env.JOB_NAME}"
}
}
}
GitHub Actions
# .github/workflows/ci-cd.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
- run: npm ci
- run: npm run lint
- run: npm test
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: azure/k8s-set-context@v1
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- run: |
kubectl set image deployment/myapp \
myapp=ghcr.io/${{ github.repository }}:${{ github.sha }}
流水线最佳实践
# 1. 保持流水线快速(<10分钟)
# 2. 失败时快速反馈
# 3. 使用缓存加速构建
# 4. 并行执行独立任务
# 5. 保持环境一致性
# 6. 使用密钥管理工具
# 7. 实施蓝绿/金丝雀部署
总结
CI/CD是DevOps的核心实践。选择合适的工具,设计合理的流水线,可以显著提高软件交付效率和质量。