【GitOps·ArgoCD篇】同步策略:自动同步、手动同步与同步钩子

前言

GitOps 的"自动应用"原则不代表所有同步都要自动。ArgoCD 提供了精细的同步控制------自动同步、手动同步、同步钩子、同步窗口。本篇讲清楚如何根据场景选择和配置同步策略。


一、同步策略总览

策略 说明 适用场景
Automated + selfHeal 全自动同步+修复漂移 测试环境
Automated (no selfHeal) 自动同步但不修复漂移 预发环境
Manual 手动触发同步 生产环境
Sync Window 限制同步时间窗口 生产环境
Sync Hook 同步前后执行自定义操作 数据库迁移等

二、自动同步

配置

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-dev
  namespace: argocd
spec:
  syncPolicy:
    automated:
      prune: true        # 自动删除 Git 中已删除的资源
      selfHeal: true     # 自动修复漂移(手动改集群会被自动恢复)
      allowEmpty: false  # 禁止同步到空(防止误删所有资源)
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground

prune 和 selfHeal 的区别

复制代码
prune: Git 中删除了某个资源 → 集群中也删除该资源
  Git: 删掉 Service YAML → 集群: 自动删除对应的 Service

selfHeal: 有人手动改了集群中的资源 → 自动恢复为 Git 中的值
  有人: kubectl scale deployment myapp --replicas=1
  Git: replicas=3
  → ArgoCD 检测到漂移 → 自动恢复 replicas=3

自动同步的行为

复制代码
Git push (修改了 replicas 从 2 → 3)
  ↓
ArgoCD 检测到 Git 变化(3秒内,配了 Webhook)
  ↓
ArgoCD 开始同步
  ↓
kubectl set image / kubectl apply(集群内执行)
  ↓
等待 Pod 滚动更新完成
  ↓
状态变为 Synced + Healthy

踩坑提示allowEmpty: false 很重要。如果有人不小心把 Git 仓库清空了,ArgoCD 不会把集群中所有资源都删掉。这是防止"删库跑路"的最后一道防线。


三、手动同步

配置

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-prod
  namespace: argocd
spec:
  # 没有 syncPolicy.automated → 手动同步
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
  # 需要 argocd app sync myapp-prod 手动触发

手动同步操作

bash 复制代码
# CLI 触发同步
argocd app sync myapp-prod

# Web UI 触发同步
# → 应用页面 → Sync 按钮

# 同步时可以只同步部分资源
argocd app sync myapp-prod \
  --resource deployment/myapp \
  --resource service/myapp

# 干运行(只看会做什么,不实际执行)
argocd app sync myapp-prod --dry-run

# 只应用,不删除(不 prune)
argocd app sync myapp-prod --prune=false

手动同步 + 自动审批

yaml 复制代码
# 用 ArgoCD Notifications + Slack 实现审批流程
spec:
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
  # 不配置 automated → 需要手动同步
  # 但可以用 Slack 按钮触发同步
yaml 复制代码
# argocd-notifications-cm
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  trigger.on-sync-status-changed: |
    - when: app.status.sync.status in ['OutOfSync']
      send: [slack-sync-required]

  service.slack: |
    token: $slack-token

  template.slack-sync-required: |
    message: |
      {{.app.metadata.name}} 需要同步
    sync: |
      # 在 Slack 消息中添加同步按钮
      # 点击按钮触发 ArgoCD API 同步

四、同步钩子(Sync Hooks)

什么是同步钩子

复制代码
同步流程:
  PreSync Hook → Sync → PostSync Hook
       ↓              ↓           ↓
  数据库迁移       部署应用     通知/清理

  SyncFail Hook(同步失败时执行)

PreSync Hook:同步前执行

yaml 复制代码
# 在部署清单中定义 PreSync Hook
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration
  annotations:
    argocd.argoproj.io/hook: PreSync              # 同步前执行
    argocd.argoproj.io/hook-delete-policy: HookSucceeded  # 成功后删除
spec:
  template:
    spec:
      containers:
      - name: migration
        image: myapp-migration:v1.0
        command: ["./migrate.sh", "up"]
      restartPolicy: Never
  backoffLimit: 2

PostSync Hook:同步后执行

yaml 复制代码
apiVersion: batch/v1
kind: Job
metadata:
  name: post-deploy-notify
  annotations:
    argocd.argoproj.io/hook: PostSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
  template:
    spec:
      containers:
      - name: notify
        image: curlimages/curl
        command:
        - curl
        - -X
        - POST
        - $(NOTIFY_WEBHOOK)
        - -H
        - "Content-Type: application/json"
        - -d
        - '{"text":"Deployment completed: myapp-prod"}'
      restartPolicy: Never

SyncFail Hook:同步失败时执行

yaml 复制代码
apiVersion: batch/v1
kind: Job
metadata:
  name: sync-fail-handler
  annotations:
    argocd.argoproj.io/hook: SyncFail
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
  template:
    spec:
      containers:
      - name: alert
        image: curlimages/curl
        command:
        - curl
        - -X
        - POST
        - $(ALERT_WEBHOOK)
        - -d
        - '{"text":"Deployment FAILED: myapp-prod"}'
      restartPolicy: Never

Hook 删除策略

策略 说明
HookSucceeded 成功后删除 Hook Job
HookFailed 失败后删除 Hook Job
BeforeHookCreation 下次创建前删除旧的 Hook Job
Never 永不删除

培训要点:PreSync Hook 最常用于数据库迁移------在部署新代码前先跑迁移脚本。这样即使新代码依赖新的表结构,也能保证迁移先于部署执行。


五、同步窗口

限制同步时间

yaml 复制代码
# AppProject 中定义同步窗口
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-alpha
  namespace: argocd
spec:
  syncWindows:
    # 允许窗口:工作日 9:00-21:00
    - kind: allow
      schedule: '0 9 * * 1-5'      # 周一到周五9点
      duration: 12h                 # 持续12小时
      applications:
        - 'myapp-prod'
      namespaces:
        - 'myapp-prod'
      clusters:
        - 'prod-cluster'
      manualSync: true               # 允许紧急手动同步

    # 拒绝窗口:冻结期(如双11)
    - kind: deny
      schedule: '0 0 10 11 *'       # 11月10日0点开始
      duration: 72h                  # 持续72小时
      applications:
        - 'myapp-prod'
      manualSync: false              # 禁止手动同步

同步窗口规则

复制代码
规则:
  1. deny 窗口优先于 allow 窗口
  2. 没有匹配到任何窗口 → 默认允许
  3. 匹配到 allow 窗口 → 允许自动和手动同步
  4. 匹配到 deny 窗口 → 禁止自动同步
  5. deny 窗口 + manualSync=false → 连手动同步也禁止
  6. deny 窗口 + manualSync=true → 禁止自动但允许手动

六、同步选项详解

常用 Sync Options

yaml 复制代码
spec:
  syncPolicy:
    syncOptions:
      # 自动创建命名空间
      - CreateNamespace=true

      # 删除传播策略
      - PrunePropagationPolicy=foreground  # 前台删除(等待完成)
      # - PrunePropagationPolicy=background  # 后台删除

      # 优先应用 Namespace 和 CRD
      - ApplyOutOfSyncOnly=true

      # 跳过验证
      - SkipDryRunOnMissingResource=true

      # 如果资源已存在则不创建(避免冲突)
      # - FailOnSharedResource=true

      # 保留部分资源的差异
      # - RespectIgnoreDifferences=true

忽略资源差异

yaml 复制代码
spec:
  ignoreDifferences:
    # 忽略 Deployment 的副本数差异
    # 适用于 HPA 自动调整副本数的情况
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas

    # 忽略 Secret 的 data 巇异
    # 适用于 External Secrets 自动管理的 Secret
    - group: ''
      kind: Secret
      jsonPointers:
        - /data
      jqPathExpressions:
        - .data

七、本篇要点回顾

  1. 自动同步:automated.prune=true + selfHeal=true,适合测试环境
  2. 手动同步:不配 automated,适合生产环境,可用 Slack 按钮触发
  3. PreSync Hook:同步前执行数据库迁移等操作
  4. PostSync Hook:同步后发通知、跑冒烟测试
  5. SyncFail Hook:同步失败自动告警和回滚
  6. 同步窗口:限制部署时间,deny 优先于 allow
  7. allowEmpty: false 是防止误删所有资源的最后防线

下一篇预告:《与 Helm 集成:Helm Chart 的 GitOps 管理》------学习如何在 ArgoCD 中管理 Helm Chart 部署。

相关推荐
heimeiyingwang4 天前
【GitOps·入门篇】工具生态:ArgoCD、Flux、Jenkins X 对比选型
jenkins·flux·argocd·gitops
xiaoxiangsiyan14 天前
GitLab CI/CD 自托管(EE 企业版)+ Kubernetes Runner 集群 + ArgoCD(GitOps 部署)
运维·网络·ci/cd·容器·kubernetes·gitlab·argocd
nvd1114 天前
ArgoCD 双层轮询深入拆解:从 redis-app.yaml 注册到缓存重建的完整链路
redis·缓存·argocd
meijinmeng15 天前
EKS 集群 ArgoCD `v3.0.6 → v3.1.x → v3.2.x` 备份,恢复,升级,巡检手册
argocd·cicd
运维大师16 天前
【K8S 运维实战】32-GitOps实践ArgoCD
运维·kubernetes·argocd
spider_xcxc17 天前
Argo CD Webhook 完全指南:从原理到实战,实现 Git 变更即时同步
argocd
啊真真真18 天前
ArgoCD:我的GitOps探索之旅与未来展望
java·算法·argocd
nvd1123 天前
基于 ArgoCD 优雅落地 K8s Gateway API 与 Kong 控制器(KIC)
kubernetes·gateway·argocd
求知若渴,虚心若愚。2 个月前
GitOps 部署实战指南(CICD)
argocd