AI AgentTechnical Deep Dive

CI/CD 容器化部署流程实战

发布时间2026/03/29
分类AI Agent
预计阅读10 分钟
作者吴长龙
*

CI/CD 容器化部署流程实战

01.内容

# CI/CD 容器化部署流程实战

从代码提交到生产部署,自动化流程是现代软件交付的核心。本文介绍完整的 CI/CD 容器化部署流程,包括 GitHub Actions、镜像构建、自动部署到 Kubernetes。

02.一、整体流程架构

code snippetcode
代码提交 → 构建 → 测试 → 镜像构建 → 推送镜像 → 部署 → 健康检查
  ↓
GitHub Actions (CI)
  ↓
Container Registry (镜像存储)
  ↓
Kubernetes / 云平台 (CD)

03.二、GitHub Actions CI 配置

2.1 基础 CI 工作流

yaml snippetyaml
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_DB: test
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linter
        run: npm run lint
      
      - name: Run tests
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/test
          REDIS_URL: redis://localhost:6379
        run: npm test
      
      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info

2.2 镜像构建与推送

yaml snippetyaml
# .github/workflows/build.yml
name: Build and Push

on:
  push:
    branches: [main]
    tags:
      - 'v*'
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}/api
          tags: |
            type=ref,event=branch
            type=sha,prefix=
            type=raw,value=latest,enable={{is_default_branch}}
            type=match,pattern=v(\d+\.\d+\.\d+),group=1
      
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          build-args: |
            NODE_ENV=production

04.三、CD 部署配置

3.1 部署到云平台

yaml snippetyaml
# .github/workflows/deploy.yml
name: Deploy to Production

on:
  workflow_run:
    workflows: [Build and Push]
    types: [completed]
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: ${{ workflow_run.conclusion == 'success' }}
    environment: production
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Railway
        run: |
          curl -fsSL https://railway.app/install.sh | sh
          railway deploy --token=${{ secrets.RAILWAY_TOKEN }}
      
      - name: Wait for deployment
        run: sleep 30
      
      - name: Health check
        run: |
          for i in {1..10}; do
            if curl -sf https://api.example.com/health > /dev/null; then
              echo "Deployment successful"
              exit 0
            fi
            echo "Waiting for health check... ($i/10)"
            sleep 10
          done
          echo "Health check failed"
          exit 1

3.2 部署到 Kubernetes

yaml snippetyaml
# .github/workflows/deploy-k8s.yml
name: Deploy to K8s

on:
  workflow_run:
    workflows: [Build and Push]
    types: [completed]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-east-1
      
      - name: Login to ECR
        uses: aws-actions/amazon-ecr-login@v1
      
      - name: Update Kubernetes deployment
        env:
          ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
          IMAGE_TAG: ${{ github.sha }}
        run: |
          # 更新 deployment 镜像
          kubectl set image deployment/api \
            api=$ECR_REGISTRY/api:$IMAGE_TAG \
            --namespace=production \
            --kubeconfig=${{ secrets.KUBE_CONFIG }}
          
          # 等待滚动更新完成
          kubectl rollout status deployment/api \
            --namespace=production \
            --kubeconfig=${{ secrets.KUBE_CONFIG }} \
            --timeout=300s

3.3 完整的 K8s 部署配置

yaml snippetyaml
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: production
  labels:
    app: api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: ghcr.io/user/repo/api:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: production
spec:
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 3000
  type: ClusterIP

05.四、回滚策略

4.1 自动回滚

yaml snippetyaml
# .github/workflows/deploy-with-rollback.yml
name: Deploy with Rollback

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy
        run: |
          # 记录当前版本
          kubectl rollout history deployment/api -n production
          
          # 部署新版本
          kubectl apply -f k8s/
          kubectl rollout status deployment/api -n production --timeout=5m
      
      - name: Verify deployment
        run: |
          # 健康检查
          curl -sf https://api.example.com/health || exit 1
          
          # 基础功能测试
          curl -sf https://api.example.com/api/users | grep -q "data" || exit 1
      
      - name: Rollback on failure
        if: failure()
        run: |
          echo "Deployment failed, rolling back..."
          kubectl rollout undo deployment/api -n production
          kubectl rollout status deployment/api -n production

4.2 手动回滚

bash snippetbash
# 查看历史版本
kubectl rollout history deployment/api -n production

# 回滚到上一个版本
kubectl rollout undo deployment/api -n production

# 回滚到指定版本
kubectl rollout undo deployment/api -n production --to-revision=3

06.五、最佳实践

  • [ ] 代码必须通过 CI 才能合并
  • [ ] 镜像使用语义化版本和 SHA 标签
  • [ ] 生产环境使用私有镜像仓库
  • [ ] 部署前先在 staging 环境验证
  • [ ] 配置健康检查和就绪检查
  • [ ] 实现自动回滚机制
  • [ ] 敏感信息使用 Secrets 管理
  • [ ] 记录部署日志和变更

07.总结

阶段工具关键点
CIGitHub Actions自动化测试、代码检查
构建Buildx/Docker多平台镜像、缓存优化
镜像存储ECR/GHCR/阿里云私有仓库、版本管理
CD平台特定滚动更新、健康检查
回滚kubectl版本记录、自动回滚

完整的 CI/CD 流程能显著提升交付效率和质量。关键是要自动化一切可自动化的环节,同时保留人工审批和回滚的能力。

---

*容器化部署系列已完成,下一篇将介绍 AI API 网关实战。*