DevOps CI/CD流水线最佳实践:从Git提交到生产部署的10分钟之旅

大家好,我是迪哥。从前我们部署上线要半天:打包、上传、解压、重启,还要提工单等审批。现在代码提交后,10分钟内自动部署到生产,出错还能自动回滚。这就是 CI/CD 的魔力。今天就聊聊,我们用 GitHub Actions 搭的这套流水线。

文章总体概览信息图

为什么要 CI/CD?

痛点(前 CI/CD 时代):

  • ❌ 部署慢:半天一次
  • ❌ 容易错:人工操作容易手滑
  • ❌ 回滚难:出问题要手动恢复
  • ❌ 质量差:合并代码就挂

收益(后 CI/CD 时代):

  • ✅ 部署快:提交即部署
  • ✅ 质量好:代码先过测试
  • ✅ 回滚易:一键回滚
  • ✅ 效率高:解放运维,专注开发

流水线设计

┌─────────────────────────────────────────────────────────────────┐
│  开发者 Git Push 代码                                             │
└─────────────────────────┬───────────────────────────────────────┘
                          │
                   ┌──────▼────────┐
                   │  1. 代码扫描   │ (SonarQube)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  2. 单元测试   │ (JUnit)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  3. 构建镜像   │ (Docker Build)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  4. 推镜像仓库 │ (Harbor/ACR)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  5. 自动部署测试│ (K8s Test Env)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  6. 集成测试   │ (Postman/Newman)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  7. 人工审批   │ (仅生产环境)
                   └──────┬────────┘
                          │
                   ┌──────▼────────┐
                   │  8. 自动部署生产│ (K8s Rolling Update)
                   └────────────────┘

实战:GitHub Actions 配置

.github/workflows/ci.yml

name: CI/CD Pipeline

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

env:
  REGISTRY: registry.example.com
  IMAGE_NAME: order-service

jobs:
  # 1. 代码扫描
  sonar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: SonarQube Scan
        uses: sonarsource/sonarcloud-github-action@v2
        with:
          args: >
            -Dsonar.projectKey=order-service
            -Dsonar.organization=dicky
            -Dsonar.host.url=https://sonar.example.com
            -Dsonar.token=${{ secrets.SONAR_TOKEN }}

  # 2. 构建 & 测试
  build-test:
    runs-on: ubuntu-latest
    needs: sonar
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven
      - name: Build & Test
        run: mvn clean verify -DskipTests=false

  # 3. 构建镜像 & 推送
  build-push:
    runs-on: ubuntu-latest
    needs: build-test
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v3
      - name: Login to Registry
        uses: docker/login-action@v2
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASSWORD }}
      - name: Build & Push
        uses: docker/build-push-action@v4
        with:
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

  # 4. 部署测试环境
  deploy-test:
    runs-on: ubuntu-latest
    needs: build-push
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to K8s
        uses: steebchen/kubectl@v2
        with:
          config: ${{ secrets.KUBE_CONFIG }}
          command: set image deployment/order-service order-service=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} -n test

  # 5. 人工审批 & 部署生产
  deploy-prod:
    runs-on: ubuntu-latest
    needs: deploy-test
    if: github.ref == 'refs/heads/main'
    environment:
      name: production
      url: https://order.example.com
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to Production
        uses: steebchen/kubectl@v2
        with:
          config: ${{ secrets.KUBE_CONFIG }}
          command: set image deployment/order-service order-service=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} -n prod

最佳实践清单

阶段最佳实践
代码提交分支保护,PR 必须经过 Code Review
CI每次提交必须过单测,代码扫描必须达标
构建缓存依赖,并行构建,镜像多阶段
测试单测覆盖 > 80%,集成测试覆盖核心流程
部署蓝绿/金丝雀发布,先小流量验证
回滚出问题一键回滚上一版本
监控部署后自动检查服务健康状态

K8s 滚动更新配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  strategy:
    rollingUpdate:
      maxSurge: 25%        # 先启 25% 新 Pod
      maxUnavailable: 25%  # 最多关 25% 旧 Pod
  template:
    metadata:
      annotations:
        rollme: ${{ github.sha }}  # 每次发布强制更新

回滚方案

自动回滚(出问题时)

kubectl rollout undo deployment/order-service -n prod

回滚到特定版本

# 查看历史
kubectl rollout history deployment/order-service -n prod

# 回滚到版本 2
kubectl rollout undo deployment/order-service --to-revision=2 -n prod

安全建议

  1. Secrets 不要写在代码里! 用 GitHub Secrets 或 K8s Secret
  2. 镜像扫描! 用 Trivy 扫漏洞
  3. 权限最小化! CI/CD 账号只给必要权限
  4. 签名! 镜像签名,防止篡改

最终效果

指标优化前优化后
发布周期半天10 分钟
发布频率每月1次每天 N 次
发布错误率20%< 1%
回滚时间1 小时1 分钟

说到 CI/CD,我家那只叫 Docker 的哈士奇最近吃饭也流水线化了:闻一闻 → 咬一口 → 咽下去 → 下一块,整个流程丝滑顺畅,跟我们的流水线有的一拼 😂

我是迪哥,这 10 篇系列文章就到这里!感谢大家一路陪伴!


往期推荐(10 篇完):

  1. 《亿级流量系统性能优化实战》
  2. 《JVM 调优让系统性能提升3倍》
  3. 《从单体到微服务架构拆分实战》
  4. 《Redis 高可用架构实战》
  5. 《分布式链路追踪实战》
  6. 《Kubernetes 生产环境部署与弹性伸缩》
  7. 《MySQL 分库分表实战》
  8. 《消息队列 Kafka/RocketMQ 选型与高可用》
  9. 《Go 语言高并发服务性能调优实战》
  10. 《Spring Cloud Alibaba 微服务全家桶》
  11. 《系统容量规划与压测实战》
  12. 《线上故障排查与应急响应》
  13. 《云原生可观测性体系建设》
  14. 《DevOps CI/CD 流水线最佳实践》

更多推荐