CI/CD 与 GitOps

返回 云原生

CI/CD 是将代码变更自动化构建、测试、部署到生产环境的工程实践;GitOps 是以 Git 仓库为唯一事实来源驱动 K8s 部署的模式。

完整 CI/CD 流程

开发者 git push
      │
      ▼
┌─────────────────────────────────────────┐
│              CI 阶段                    │
│                                         │
│  1. 代码检出(Checkout)                │
│  2. 依赖安装(npm install / mvn install)│
│  3. 单元测试(unit test)               │
│  4. 代码质量扫描(SonarQube / Biome)   │
│  5. 安全扫描(Trivy / Snyk)            │
│  6. Docker 镜像构建(docker build)     │
│  7. 镜像推送(push to Registry)        │
└────────────────────┬────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────┐
│              CD 阶段                    │
│                                         │
│  8. 更新 Helm Chart / K8s Manifest      │
│     (修改镜像 tag)                    │
│  9. ArgoCD 检测 Git 变更                │
│  10. Sync 到 Kubernetes                 │
│  11. 滚动更新 / 金丝雀发布              │
│  12. 健康检查通过 → 发布完成            │
└─────────────────────────────────────────┘

CI(持续集成)

主流 CI 工具

工具特点适用场景
GitHub Actions与 GitHub 深度集成,免运维开源 / SaaS 项目
GitLab CI自建 GitLab 首选,功能完整企业内网
Jenkins最成熟,插件生态最丰富传统企业
TektonK8s 原生 CI,流水线即代码云原生环境

GitHub Actions 示例

name: CI
 
on:
  push:
    branches: [main]
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Run Tests
        run: mvn test
 
      - name: Build Docker Image
        run: docker build -t myapp:${{ github.sha }} .
 
      - name: Push to Registry
        run: |
          docker push registry.example.com/myapp:${{ github.sha }}

CD(持续部署)

发布策略

滚动更新(Rolling Update):

旧版本: Pod1(v1) Pod2(v1) Pod3(v1)

更新过程:
  Pod1(v1) → Pod1(v2) 就绪
  Pod2(v1) → Pod2(v2) 就绪
  Pod3(v1) → Pod3(v2) 就绪

结果: Pod1(v2) Pod2(v2) Pod3(v2)

零停机,但版本混跑期间可能有兼容性问题。

蓝绿部署(Blue-Green):

Blue(当前生产 v1)← 流量 100%
Green(新版本 v2)← 流量 0%

验证通过后:
Blue ← 流量 0%
Green ← 流量 100%

出问题:立刻切回 Blue(秒级回滚)

金丝雀发布(Canary):

v1 Pod × 9 ← 流量 90%
v2 Pod × 1 ← 流量 10%

观察 10% 流量的指标(错误率、延迟)
  正常 → 逐步扩大比例 → 全量
  异常 → 删除 v2 Pod,自动回滚

GitOps

核心理念

Git 是唯一事实来源(Single Source of Truth)

所有 K8s 资源的期望状态都以代码形式存储在 Git 仓库,任何变更必须经过 Git PR。

传统 CD:
  CI 构建完 → CI 直接 kubectl apply → K8s
  问题:生产环境配置散落在 CI 脚本中,无法审计

GitOps:
  CI 构建完 → 更新 Git 仓库中的镜像 tag
  ArgoCD 监听 Git → 检测到变更 → 自动 Sync 到 K8s

优势:

  • 所有变更有 Git 历史记录,可审计
  • 回滚 = git revert,简单可靠
  • 开发者无需直接访问 K8s 集群(安全)
  • PR Review 作为发布审批流程

ArgoCD 架构

Git Repo(Helm Chart / Kustomize / Manifest)
      │
      │ 监听变更(轮询 / Webhook)
      ▼
┌──────────────────────────────────┐
│           ArgoCD                 │
│                                  │
│  Application(期望状态)          │
│  vs                              │
│  Live State(当前状态)           │
│                                  │
│  状态:Synced / OutOfSync         │
└────────────────┬─────────────────┘
                 │ kubectl apply
                 ▼
          Kubernetes Cluster

ArgoCD Application:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: order-service
spec:
  source:
    repoURL: https://github.com/myorg/k8s-config
    path: apps/order-service
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:       # 自动同步
      prune: true    # 删除 Git 中已不存在的资源
      selfHeal: true # 有人手动改了 K8s 资源,自动恢复

镜像管理

镜像命名规范:
  registry.example.com/{team}/{service}:{tag}

Tag 策略:
  开发环境::latest(或 :dev)
  预发布::staging-{git-sha}
  生产::{semantic-version} 如 :1.2.3
      或 :{git-sha} 如 :abc1234

永远不在生产环境使用 :latest(无法追溯具体版本)

镜像安全扫描(CI 阶段):

docker build → Trivy 扫描漏洞
                 │
                 ├── Critical 漏洞 → 阻断流水线
                 ├── High 漏洞    → 告警
                 └── 通过         → 推送到 Registry

多环境管理

Git 分支策略:
  feature/* → dev 环境(自动部署)
  main      → staging 环境(自动部署)
  tag v*.*.*→ prod 环境(手动审批)

Helm values 多环境配置:
  values.yaml          # 通用配置
  values-dev.yaml      # 开发覆盖
  values-staging.yaml  # 预发布覆盖
  values-prod.yaml     # 生产覆盖