Chapter 03

Sync 策略与自愈机制

深入掌握 ArgoCD 的同步生命周期:Sync Hooks 在不同阶段执行任务,Sync Waves 精确控制资源创建顺序,配合 Retry 策略构建生产级可靠部署流程。

自动同步深入配置

上一章介绍了 syncPolicy.automated 的基础配置。这里深入两个关键参数:

syncPolicy:
  automated:
    prune: true           # 删除 Git 中移除的资源(需谨慎!)
    selfHeal: true        # 修复集群漂移(强烈推荐开启)
    allowEmpty: false     # false: Git 为空时拒绝同步(防误删)
prune 的危险性

prune: true 意味着如果你不小心删除了 Git 仓库中的某个资源文件,ArgoCD 会自动删除集群中的对应资源(包括有状态资源如 PVC)。生产环境建议先在测试环境充分验证后再开启,或结合 AppProject 限制 prune 操作的资源范围。

Sync Phase:同步生命周期

ArgoCD 的同步过程分为三个阶段,每个阶段可以执行特定的 Hook 任务:

ArgoCD Sync 生命周期

┌─────────────────────────────────────────────────────────────────┐
                    Sync 开始                                     
└──────────────────────────┬──────────────────────────────────────┘
                            
┌──────────────────────────▼──────────────────────────────────────┐
                   Phase 1: PreSync                              
  执行 Hook Job(如数据库 schema 迁移、备份数据)                   
  所有 PreSync Hook 成功后才进入下一阶段                            
└──────────────────────────┬──────────────────────────────────────┘
                            
┌──────────────────────────▼──────────────────────────────────────┐
                   Phase 2: Sync                                 
  应用所有普通 K8s 资源(Deployment、Service、ConfigMap 等)        
  按 Sync Wave 顺序依次应用                                        
└──────────────────────────┬──────────────────────────────────────┘
                            
┌──────────────────────────▼──────────────────────────────────────┐
                   Phase 3: PostSync                             
  执行部署后任务(如运行集成测试、发送部署通知)                     
  PostSync Hook 失败不影响 Sync Status(但会影响 Health)           
└──────────────────────────┬──────────────────────────────────────┘
                            
┌──────────────────────────▼──────────────────────────────────────┐
                   SyncFail Hook(可选)                          
  仅在同步失败时执行(如发送告警、执行回滚脚本)                     
└─────────────────────────────────────────────────────────────────┘

Sync Hooks 实战

Sync Hook 通过 Kubernetes Job 实现,在资源的 Annotation 中声明 Hook 类型:

# PreSync Hook: 数据库迁移(在部署新版本前执行)
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
  annotations:
    argocd.argoproj.io/hook: PreSync         # Hook 类型
    argocd.argoproj.io/hook-delete-policy: HookSucceeded  # 成功后自动删除 Job
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: migrate
        image: my-app:v2.0.0
        command: ["python", "manage.py", "migrate"]
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url
# PostSync Hook: 部署成功后运行集成测试
apiVersion: batch/v1
kind: Job
metadata:
  name: smoke-test
  annotations:
    argocd.argoproj.io/hook: PostSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation  # 下次 Hook 前删除
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: test
        image: curlimages/curl:8.0
        command:
        - sh
        - -c
        - curl -sf http://my-app-svc/health || exit 1
hook-delete-policy
Hook Job 的清理策略:HookSucceeded(成功后删除)、HookFailed(失败后删除)、BeforeHookCreation(下次 Hook 创建前删除旧的)。不设置则 Job 保留用于查看日志。

Sync Waves:精确控制资源顺序

在同一个 Sync Phase 内,不同资源的创建顺序可以通过 Sync Wave 注解控制。Wave 值越小,越先被应用;相同 Wave 的资源并发处理。只有当前 Wave 的所有资源健康后,才会处理下一个 Wave。

# Wave -1: 先创建 Namespace 和 ConfigMap
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"

---
# Wave 0(默认): 部署数据库 StatefulSet
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "0"

---
# Wave 1: 等数据库健康后再部署后端 API
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "1"

---
# Wave 2: 最后部署前端(依赖后端 API)
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "2"
Wave + Hook 组合使用

Sync Waves 和 Sync Hooks 可以组合:PreSync Hook 在所有 Wave 之前执行,PostSync Hook 在所有 Wave 完成后执行。Wave 可以是负数(如 -1、-5),负数 Wave 比 Wave 0 先执行,适合创建基础设施资源(Namespace、CRD 等)。

Replace vs Apply

ArgoCD 默认使用 kubectl apply(三路合并),某些场景需要使用 kubectl replace(完全替换):

# 对特定资源使用 Replace(如 Job 需要重新创建)
metadata:
  annotations:
    argocd.argoproj.io/sync-options: Replace=true

# 全局使用 Server-Side Apply(推荐)
syncPolicy:
  syncOptions:
  - ServerSideApply=true

Sync 失败与 Retry 策略

网络抖动、资源临时不可用等原因可能导致同步失败。ArgoCD 支持配置自动 Retry:

syncPolicy:
  automated:
    prune: true
    selfHeal: true
  retry:
    limit: 5                    # 最多重试 5 次(-1 为无限次)
    backoff:
      duration: 5s              # 初始等待时间
      factor: 2                  # 指数退避倍数(5s → 10s → 20s → 40s)
      maxDuration: 3m           # 最大等待时间上限

实战:带数据库迁移的应用部署

将上述概念综合运用,实现一个完整的带数据库迁移的 Web 应用部署:

my-app/
├── 00-namespace.yaml          # Wave -1
├── 01-configmap.yaml          # Wave -1
├── 02-db-migrate-hook.yaml    # PreSync Hook
├── 03-postgres.yaml           # Wave 0(数据库)
├── 04-backend.yaml            # Wave 1(等数据库健康)
├── 05-frontend.yaml           # Wave 2(等后端健康)
└── 06-smoke-test-hook.yaml    # PostSync Hook
# 00-namespace.yaml - 最先创建基础资源
apiVersion: v1
kind: Namespace
metadata:
  name: my-app
  annotations:
    argocd.argoproj.io/sync-wave: "-1"
---
# 03-postgres.yaml - 数据库先启动
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  annotations:
    argocd.argoproj.io/sync-wave: "0"
---
# 04-backend.yaml - 等 Wave 0 健康后再启动
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  annotations:
    argocd.argoproj.io/sync-wave: "1"
本章小结

ArgoCD 的同步生命周期分 PreSync → Sync → PostSync 三阶段,Hook Job 在特定阶段执行任务(数据库迁移、测试等)。Sync Waves 注解控制同一阶段内资源的创建顺序,确保依赖关系正确。Retry 策略的指数退避设计可有效应对临时性故障。这三个机制组合使用,能够实现生产级的安全部署流程。