3. GitOps 工作流基础:ArgoCD / Flux 核心流程、同步窗口机制、健康检查策略
GitOps 将 Kubernetes 集群的期望状态声明式地存储在 Git 仓库中,并通过自动化工具持续将集群实际状态向 Git 中的期望状态对齐。ArgoCD 和 Flux 是目前最主流的两个 GitOps 实现。理解它们的核心流程、同步窗口与健康检查机制,是排查“Envoy 异常导致同步窗口阻塞”这类故障的前提。
3.1 核心工作流对比
ArgoCD 采用 Pull 模型:ArgoCD Application Controller 定期轮询 Git 仓库(或监听 Webhook),对比集群实时状态与 Git 中的期望状态,发现差异后执行同步操作。Flux v2 同样基于 Pull 模型,但通过 Source Controller 和 Kustomize Controller / Helm Controller 解耦了源获取与资源协调。
| 维度 | ArgoCD | Flux v2 |
|---|---|---|
| 架构核心 | Application CRD + ApplicationSet + Repo Server | Source CRD + Kustomize/Helm Controller + Notification Controller |
| 同步触发 | 轮询(默认 3 分钟)+ Webhook + 手动 Sync | 轮询(默认 1 分钟)+ Webhook + 手动 Reconcile |
| 同步策略 | 自动同步(Auto-Sync)+ Prune + Self-Heal | 自动应用(Reconcile)+ Prune + Decrypt |
| 状态对比 | Diff 基于 Live State vs Desired State | Diff 基于 Source 中的 Manifest vs Cluster State |
| 回滚方式 | 通过 Git 历史回退 + Sync | 通过 Git 历史回退 + Reconcile |
关键差异: ArgoCD 的 Application 是一个独立 CRD,拥有完整的 UI 和 RBAC;Flux 更强调“Kubernetes 原生”,通过多个 Controller 组合实现 GitOps 管道,无独立 UI,依赖 kubectl 或第三方 Dashboard。
3.2 同步窗口机制
同步窗口(Sync Window)用于限制 GitOps 工具在特定时间段内执行同步操作,常用于生产环境的变更管控。当 Envoy 异常导致集群状态不稳定时,同步窗口可能被错误地阻塞或跳过。
3.2.1 ArgoCD 同步窗口
- 定义方式: 通过
argocd-cmConfigMap 中的syncWindows字段配置,或通过 Application 级别的spec.syncPolicy.syncOptions覆盖。 - 窗口类型:
allow:仅允许在窗口内同步。deny:在窗口内禁止同步。
- 匹配规则: 支持按
kind、namespace、cluster、application进行过滤。 - 阻塞表现: 当同步被窗口拒绝时,ArgoCD 会在 UI 中显示
SyncWindowDenied状态,不会执行任何同步操作,直到窗口结束。
# argocd-cm 示例:禁止生产环境在 22:00-06:00 之间同步
data:
syncWindows: |
- kind: deny
schedule: "0 22 * * *"
duration: 8h
applications:
- "prod-*"
clusters:
- "https://prod-cluster.example.com"
namespaces:
- "production"
timezone: "Asia/Shanghai"
3.2.2 Flux 同步窗口
- 定义方式: Flux 没有内置的同步窗口 CRD,但可以通过 Kustomization 的
.spec.suspend字段 结合外部调度器(如 CronJob)实现类似效果。 - 实现原理: 在需要禁止同步的时间段,将 Kustomization 对象的
suspend设置为true,Flux 的 Reconciler 会跳过该对象的协调。 - 阻塞表现: 当
suspend: true时,Flux 不会拉取新源,不会应用变更,也不会触发健康检查。
Envoy 故障关联: 如果 Envoy 异常导致集群网络分区或 API Server 响应延迟,ArgoCD/Flux 的健康检查可能持续失败,进而触发同步窗口的“自动阻塞”逻辑(如 ArgoCD 的 Auto-Sync 在健康检查失败时默认不会继续同步)。此时即使窗口处于允许状态,同步也会被阻塞。
3.3 健康检查策略
健康检查是 GitOps 判断应用是否“健康”的核心机制。只有健康的应用才会被允许继续后续同步或流量切换。Envoy 作为数据面组件,其健康状态直接影响整个工作负载的健康判定。
3.3.1 ArgoCD 健康检查
- 内置检查: ArgoCD 为 Deployment、StatefulSet、DaemonSet、Service、Ingress 等内置了健康检查逻辑。例如,Deployment 需要满足
AvailableReplicas == Replicas且UpdatedReplicas == Replicas。 - 自定义检查: 通过 Resource Customization 或 Lua 脚本 扩展健康检查逻辑,适用于 Envoy 等自定义资源。
- Envoy 特殊处理: 对于 Envoy 部署的
Deployment或DaemonSet,ArgoCD 默认检查 Pod 是否 Ready。如果 Envoy 配置错误导致 Pod 启动失败或 Readiness Probe 失败,ArgoCD 会标记该资源为Degraded。
3.3.2 Flux 健康检查
- 内置检查: Flux 通过 Kustomize Controller 对标准 Kubernetes 资源进行健康评估,检查
Ready状态、Available状态等。 - 自定义检查: 使用 Health Check 策略(
.spec.healthChecks)显式指定需要检查的资源。支持检查自定义资源的特定字段。 - Envoy 特殊处理: 如果 Envoy 通过
HelmRelease部署,Flux 会检查 Helm Release 的status.conditions中的Released和Ready条件。Envoy Pod 不健康会导致 Helm Release 状态变为Failed。
排查要点: 当同步窗口阻塞时,优先检查 ArgoCD Application 的
status.health.status 或 Flux Kustomization 的 status.conditions。如果健康状态为 Degraded 或 False,说明 Envoy 或其他组件异常,同步窗口的“允许同步”条件可能被自动抑制。
3.4 同步窗口与健康检查的交互流程
下图展示了 ArgoCD 在同步窗口与健康检查共同作用下的决策流程。Envoy 异常可能出现在“健康检查”阶段,导致同步被阻塞。
3.5 同步窗口阻塞的典型场景
- 窗口内健康检查持续失败: Envoy 配置错误导致 Pod 反复 CrashLoopBackOff,ArgoCD 健康检查始终为
Degraded,即使窗口允许同步,Auto-Sync 也会因为Self-Heal策略(默认要求健康)而停止。 - 窗口外手动同步被拒绝: 运维人员在非窗口时间尝试手动同步,ArgoCD 直接拒绝,但此时 Envoy 异常已经导致集群状态不一致,需要等到下一个窗口才能修复。
- Flux suspend 与 Envoy 故障叠加: 运维人员手动 suspend 了 Kustomization 以阻止同步,但忘记恢复,导致 Envoy 修复后无法自动同步。
- Webhook 触发与窗口冲突: Git 提交触发 Webhook,ArgoCD 尝试同步,但当前处于 deny 窗口,同步被阻塞,Envoy 的配置变更无法生效。
最佳实践: 为生产环境配置
allow 窗口,并开启 Self-Heal 和 Auto-Sync。同时,为 Envoy 等关键组件配置独立的健康检查策略,确保在窗口内能够快速发现并修复异常。建议在 ArgoCD 中启用 syncWindows 的 timezone 字段,避免跨时区调度错误。