前置知识: 运维与中间件

GitOps 与持续交付

2 min高级

GitOps与持续交付:ArgoCD、Flux、渐进式交付与发布策略

1. GitOps 原则

1.1 核心原则

  1. 声明式:系统描述是声明式的
  2. 版本控制:期望状态存储在 Git
  3. 自动拉取:自动应用期望状态
  4. 持续协调:持续确保一致性

1.2 Push vs Pull 模式

模式触发方式安全性适用场景
PushCI 推送部署需要凭证传统 CI/CD
PullAgent 拉取变更凭证在集群内GitOps

2. ArgoCD

2.1 核心概念

flowchart LR
    G[Git 仓库] --> A[ArgoCD] --> K[Kubernetes 集群]
    K -.->|状态同步| G

2.2 Application 配置

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/org/k8s-manifests.git
    targetRevision: main
    path: overlays/production
    helm:
      valueFiles:
        - values-prod.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: myapp
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

2.3 App of Apps 模式

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: apps
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/org/argocd-apps.git
    path: apps
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd

2.4 ApplicationSet

多集群/多环境自动生成 Application:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp
spec:
  generators:
    - git:
        repoURL: https://github.com/org/k8s-manifests.git
        files:
          - path: 'clusters/**/config.json'
  template:
    metadata:
      name: '{{cluster_name}}-myapp'
    spec:
      source:
        repoURL: https://github.com/org/k8s-manifests.git
        targetRevision: '{{branch}}'
        path: overlays/{{overlay}}
      destination:
        server: '{{server}}'
        namespace: myapp

3. Flux

3.1 核心组件

组件功能
source-controller管理 Git/Helm/OCI 源
kustomize-controllerKustomize 构建
helm-controllerHelm 发布
notification-controller通知
image-automation自动镜像更新

3.2 基本配置

# Git 仓库源
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: myapp
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/org/k8s-manifests.git
  ref:
    branch: main
---
# Kustomize 部署
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: myapp
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: myapp
  path: ./overlays/production
  prune: true
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: myapp
      namespace: default

3.3 自动镜像更新

apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: myapp
spec:
  image: registry/myapp
  interval: 1m
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: myapp
spec:
  imageRepositoryRef:
    name: myapp
  policy:
    semver:
      range: '^1.x'
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
  name: myapp
spec:
  sourceRef:
    kind: GitRepository
    name: myapp
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        name: fluxbot
        email: fluxbot@example.com
      messageTemplate: 'Update image to {{ .Image }}'
    push:
      branch: main
  interval: 1m

4. 渐进式交付

4.1 Argo Rollouts

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp
spec:
  replicas: 10
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: { duration: 5m }
        - setWeight: 30
        - pause: { duration: 5m }
        - setWeight: 50
        - pause: { duration: 5m }
        - setWeight: 80
        - pause: { duration: 5m }
      canaryService: myapp-canary
      stableService: myapp-stable
      trafficRouting:
        istio:
          virtualServices:
            - name: myapp-vsvc
              routes:
                - primary
      analysis:
        templates:
          - templateName: success-rate
        args:
          - name: service-name
            value: myapp-canary
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      provider:
        prometheus:
          address: http://prometheus:9090
          query: |
            sum(rate(http_requests_total{service="{{args.service-name}}",status!~"5.."}[5m]))
            /
            sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))
      successCondition: result[0] >= 0.99
      interval: 30s
      count: 10

4.2 Flagger

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: myapp
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  service:
    port: 8080
  analysis:
    interval: 1m
    threshold: 5
    maxWeight: 50
    stepWeight: 10
    metrics:
      - name: request-success-rate
        thresholdRange:
          min: 99
        interval: 1m
      - name: request-duration
        thresholdRange:
          max: 500
        interval: 1m
    webhooks:
      - name: load-test
        url: http://flagger-loadtester/
        timeout: 5s
        metadata:
          cmd: 'hey -z 1m -q 10 -c 2 http://myapp:8080/'

4.3 发布策略对比

策略流量切换回滚速度资源开销风险
滚动更新逐步中低中
蓝绿部署一次性快高(2倍)低
金丝雀渐进快中低
影子测试复制流量即时高最低

5. 多环境管理

5.1 环境隔离

flowchart TD
    T0["Git 仓库结构:"]
    T1["base/                    # 基础配置"]
    T2["kustomization.yaml"]
    T3["deployment.yaml"]
    T4["overlays/"]
    T5["development/         # 开发环境"]
    T6["staging/             # 预发布"]
    T7["production/          # 生产"]
    T8["apps/"]
    T9["dev.yaml             # ArgoCD Application"]
    T10["staging.yaml"]
    T11["prod.yaml"]
    T0 --> T1
    T3 --> T4
    T7 --> T8
    T8 --> T9
    T8 --> T10
    T8 --> T11

5.2 促销流程(Promotion)

flowchart LR
    D[开发环境] -->|合并到 dev 分支| S[预发布环境]
    S -->|合并到 staging 分支| P[生产环境]
    P -->|合并到 main 分支| P

5.3 配置差异管理

方法说明适用场景
Kustomize overlays覆盖差异简单差异
Helm values值文件差异Helm 项目
环境变量运行时注入通用
配置中心动态配置需要热更新