ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Argo CD ApplicationSet Progressive Syncs 实战指南:基于 RollingSync 的渐进式应用发布与回滚删除

2026/9/13 6:35:14 拓冰建站 浏览量
Argo CD ApplicationSet Progressive Syncs 实战指南:基于 RollingSync 的渐进式应用发布与回滚删除 Argo CD ApplicationSet Progressive Syncs 实战指南基于 RollingSync 的渐进式应用发布与回滚删除【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd导读Progressive Syncs渐进式同步是 Argo CD ApplicationSet 提供的Beta 功能自 v3.3.0 起它允许你控制 ApplicationSet 控制器创建、更新乃至删除其托管 Application 的顺序。通过为生成的 Application 打上标签并按matchExpressions分组你可以实现先灰度环境、再验证环境、最后生产环境分批发布的滚动式发布流程并让每一步都等待前一批应用进入Healthy状态后再继续。读完本文你将掌握 Progressive Syncs 的启用方式、RollingSync创建策略与Reverse删除策略的完整配置并能结合源码理解其底层状态机Waiting → Pending → Progressing → Healthy与最终器finalizer保障机制。功能状态Beta。该功能整体稳定但可能仍存在未覆盖的边缘场景。相关实现位于 applicationset/progressivesync/progressive_sync.go。使用场景与设计边界Progressive Syncs 的设计目标被刻意保持为轻量且灵活该功能只与托管 Application 的健康状态Health交互不会与 Argo Rollouts、原生 ReplicaSet 控制器等回滚控制器直接集成。控制器会监听托管 Application 变为Healthy才进入下一阶段。由于应用在 Pod 滚动期间会进入Progressing状态因此 Deployment、DaemonSet、StatefulSet 以及 Argo Rollouts 都天然受支持实际上任何健康检查能够报告Progressing状态的资源都受支持见 gitops-engine/pkg/health 的健康状态定义。Argo CD Resource Hooks资源钩子同样受支持例如 sync-waves同步波次。官方建议在无法使用 Argo Rollout 但又需要高级功能的场景例如 DaemonSet 变更后的冒烟测试下优先采用这一方案。启用 Progressive Syncs作为实验性功能Progressive Syncs 必须显式开启三种方式任选其一命令行参数在 ApplicationSet 控制器启动参数中传入--enable-progressive-syncs环境变量设置ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCStrueConfigMap在 Argo CD 的argocd-cmd-params-cmConfigMap 中设置applicationsetcontroller.enable.progressive.syncs: true。从源码看命令行标志通过环境变量兜底解析默认均为false见 cmd/argocd-applicationset-controller/commands/applicationset_controller.gocommand.Flags().BoolVar(enableProgressiveSyncs, enable-progressive-syncs, env.ParseBoolFromEnv(ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS, false), Enable use of the experimental progressive syncs feature.)启用后控制器在协调循环reconcile中才会进入渐进式同步分支。注意两点行为差异见 applicationset/controllers/applicationset_controller.go若功能开启但某个 ApplicationSet 的策略从RollingSync切回了默认策略控制器会清理残留的ApplicationStatus条目若功能关闭控制器同样会清空所有ApplicationStatus避免脏数据残留。策略总览创建与删除是两个独立字段ApplicationSet 的策略spec.strategy同时控制应用的创建/更新与删除二者由两个独立字段配置字段控制对象可选值type应用的创建与更新顺序AllAtOnce默认、RollingSyncdeletionOrder应用的删除顺序AllAtOnce默认、Reverse创建策略Creation StrategiesAllAtOnce默认这是 ApplicationSet 的原始默认行为ApplicationSet 一旦更新其管理的所有 Application 将同时被更新行为与未启用 Progressive Syncs 时完全一致。spec: strategy: type: AllAtOnce # 显式声明但该值本就是默认值RollingSync该更新策略允许你按生成 Application 资源上的标签进行分组当 ApplicationSet 变化时变更将按组依次应用到各 Application。其核心语义如下分组通过 Application 的labels与matchExpressions完成选择一个 Application 必须满足某步内的所有matchExpressions才会被选中多个表达式之间是AND关系In与NotIn操作符只要匹配到至少一个values值即为真OR关系当NotIn与In同时命中时NotIn优先级更高每个分组内的所有 Application必须全部变为Healthy控制器才会继续更新下一组同组内并发更新的 Application 数量不超过maxUpdate参数默认 100%即不设上限RollingSync会捕获 ApplicationSet 资源之外的变更因为它依赖监听托管 Application 的OutOfSync状态RollingSync会强制所有生成的 Application 关闭自动同步autosync凡是在 Application 规范里配置了自动同步策略的都会在 applicationset-controller 日志中打印警告Sync 操作的触发方式与在 UI/CLI 中手动触发完全一致即直接设置 Application 资源的operation状态字段因此RollingSync 会像用户在 Argo UI 点击Sync按钮一样遵守同步窗口sync windows触发同步时沿用 Application 自身配置的 syncPolicy例如保留其重试retry设置未被任何步骤选中的 Application 会被排除在滚动同步之外需要手动通过 CLI 或 UI 同步。配置示例——两个发布步骤spec: strategy: type: RollingSync rollingSync: steps: - matchExpressions: - key: envLabel operator: In values: - env-dev - matchExpressions: - key: envLabel operator: In values: - env-prod maxUpdate: 10%该示例的执行过程第一步所有带标签envLabelenv-dev的 Application 被选中先同步。由于未定义maxUpdate采用默认值 100%所有匹配的 Application 将同时同步控制器等待每个被选中的应用都达到Healthy状态才进入下一步第二步所有带标签envLabelenv-prod的 Application 被选中同步但这里maxUpdate: 10%意味着每次只同步匹配应用中的 10%。每一批应用达到Healthy后再同步下一批直到全部匹配应用完成同步。若存在未匹配任何表达式的应用它们不会被 RollingSync 策略同步必须如前文所述手动同步。maxUpdate 的取值规则源码佐证在 applicationset/progressivesync/progressive_sync.go 的UpdateApplicationSetApplicationStatusProgress中maxUpdate同时支持整数与百分比字符串两种写法底层为intstr.IntOrString经GetScaledValueFromIntOrPercent换算百分比值向下取整但对于大于 0% 的值至少保证有 1 个 Application 被选中maxUpdateVal 1时强制置为 1maxUpdate: 0表示该步骤不会更新任何匹配的 Application若maxUpdate值非法控制器会记录一条InvalidMaxUpdates校验问题并忽略该步骤的 maxUpdate 逻辑即退化为不限数量。分组选择逻辑源码佐证buildAppDependencyList见 progressive_sync.go负责把当前 Application 按步骤分桶对每个步骤的每个matchExpression先查 Application 是否含对应 label keyIn操作符下缺 key 即不入选NotIn下缺 key 则视为匹配一个 Application 被多个步骤选中时会打印警告并记录为DuplicateAppSelections校验问题没有任何 Application 匹配的步骤会被记录为EmptySteps空步骤未被任何表达式选中的 Application 在步骤映射中默认落在step -1见getAppStep即被排除在滚动同步之外。校验与状态条件源码佐证ValidationIssues见 applicationset/progressivesync/validation_issues.go会收集四类问题非法matchExpression操作符仅支持In/NotIn、重复选中、空步骤、非法maxUpdate。当存在问题时控制器会在 ApplicationSet 上设置ApplicationSetConditionInvalidRolloutConfig条件并优先报告其中优先级最高的一项。同时控制器会根据各步骤是否全部Healthy来维护ApplicationSetConditionRolloutProgressing条件getProgressingCondition见 progressive_sync.go进行中时消息为ApplicationSet is performing rollout of step N完成时为ApplicationSet Rollout has completed。底层状态机Waiting → Pending → Progressing → Healthy从UpdateApplicationSetApplicationStatus与UpdateApplicationSetApplicationStatusProgress的实现progressive_sync.go可以看到每个 Application 在渐进式同步中经历以下状态Waiting等待检测到目标修订TargetRevisions或期望 spec 与当前不一致非 Git 变更例如生成器参数变化时进入控制器会比较 revision 与 spec通过SpecsEquivalent与BuildIgnoreDiffConfig支持ignoreApplicationDifferences配置Pending待定当前步骤满足所有前序步骤均 Healthy且未超过maxUpdate配额后由UpdateApplicationSetApplicationStatusProgress推进Progressing进行中观测到 Application 触发了同步操作OperationState后进入若 Application 存在错误条件如InvalidSpecError、UnknownError也会直接推进到 Progressing 以暴露问题Healthy健康Application 的 Health 为Healthy且 Sync 状态为Synced时达成此时才算该波次完成。此外PerformProgressiveSyncs在开始前会通过ensureApplicationsReconciledprogressive_sync.go确保所有 Application 已在最近一次变更之后完成协调reconcile必要时会给应用添加 refresh annotation 强制刷新refresh-grace-period-seconds默认 30 秒环境变量ARGOCD_APPLICATIONSET_CONTROLLER_REFRESH_GRACE_PERIOD_SECONDS用于控制强制刷新前的宽限期。同步触发方式源码佐证SyncDesiredApplications与syncApplicationprogressive_sync.go展示了滚动同步如何触发同步只为处于Pending状态的 Application 触发同步并锁定到该步骤解除阻塞时记录的 TargetRevisions避免发布中途新提交劫持已在进行中的步骤通过构造OperationInitiatedBy为applicationset-controller、Automated: true写入 Application 的operation字段与 UI/CLI 手动触发路径一致默认设置重试上限Retry.Limit 5与 Argo CD 应用控制器的自动同步行为保持一致若 Application 的 syncPolicy 配置了自定义retry则以其为准同步时携带 Application 的syncOptions与prune设置同时强制关闭生成应用的自动同步disableAutomatedSync这正是文档所述RollingSync 会强制所有生成的 Application 关闭 autosync的底层实现。删除策略Deletion StrategiesdeletionOrder字段控制应用从 ApplicationSet 移除时的删除顺序。AllAtOnce 删除默认所有需要删除的 Application同时被删除。该模式与AllAtOnce和RollingSync两种创建策略均可搭配使用。spec: strategy: type: RollingSync # 或 AllAtOnce deletionOrder: AllAtOnce # 显式声明但该值本就是默认值Reverse 删除逆序删除当RollingSync策略搭配deletionOrder: Reverse时应用将按rollingSync.steps中定义步骤的逆序被删除越晚部署的应用越先删除。这在需要按特定顺序拆除依赖服务时尤其有用——例如先删前端服务再删后端依赖。Reverse 删除的硬性要求必须与type: RollingSync搭配使用必须定义rollingSync.steps应用严格按照步骤序列的逆序删除。重要保障机制ApplicationSet 的 finalizer 在所有 Application 成功删除前不会被移除这确保了清理的完整性防止 ApplicationSet 在托管应用之前被删除当deletionOrder设置为Reverse且渐进式同步启用时ApplicationSet 控制器会确保存在 finalizer如果 ApplicationSet 缺少必需的 finalizer控制器会在生成应用之前自动为它添加见 applicationset/controllers/applicationset_controller.go。spec: strategy: type: RollingSync deletionOrder: Reverse rollingSync: steps: - matchExpressions: - key: envLabel operator: In values: - env-dev # 步骤 1最先创建最后删除 - matchExpressions: - key: envLabel operator: In values: - env-prod # 步骤 2第二个创建最先删除删除时执行顺序env-prod的应用步骤 2先删除env-dev的应用步骤 1后删除。该顺序适合拆除依赖服务的场景例如先删除前端服务、再删除其后端依赖。Reverse 删除的底层实现源码佐证PerformReverseDeletion见 progressive_sync.go实现了逆序删除先通过buildAppDependencyList得到每个应用所属步骤再按stepLength - appStep - 1计算逆序优先级并排序逐级触发Client.Delete每个步骤删除后控制器会以 10 秒为间隔重新入队requeue持续轮询直到对象消失对已经标记删除但迟迟未消失的应用若超过2 分钟staleCacheThreshold仍未消失控制器会绕过 informer 缓存直接向 API Server 求证通过APIReader区分删除缓慢与DELETED 事件丢失导致的幽灵缓存项两种情形必要时通过带 UID 前置条件的 Delete 触发缓存驱逐避免幽灵条目阻塞 finalizer 的释放相关回归测试见 applicationset/progressivesync/phantom_livecheck_test.go整个流程结束全部删除完成后才返回控制器才会释放 ApplicationSet 的 finalizer。完整示例分环境渐进式发布 guestbook下面的完整示例演示了如何为显式配置了环境标签的 Application 编排一次渐进式发布。当一次变更被推送后将按顺序发生如下动作所有env-dev的 Application同时更新滚动过程会等待所有env-qa的 Application 通过argocdCLI 或 UI 中的 Sync 按钮被手动同步所有env-prod的 Application 将每次更新 10%直到全部更新完毕。apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: guestbook spec: generators: - list: elements: - cluster: engineering-dev url: https://1.2.3.4 env: env-dev - cluster: engineering-qa url: https://2.4.6.8 env: env-qa - cluster: engineering-prod url: https://9.8.7.6/ env: env-prod strategy: type: RollingSync deletionOrder: Reverse # 应用将按步骤逆序删除 rollingSync: steps: - matchExpressions: - key: envLabel operator: In values: - env-dev #maxUpdate: 100% # 若不定义默认一次更新所有匹配应用默认 100% - matchExpressions: - key: envLabel operator: In values: - env-qa maxUpdate: 0 # 若为 0则不会更新任何匹配的应用 - matchExpressions: - key: envLabel operator: In values: - env-prod maxUpdate: 10% # maxUpdate 支持整数和百分比字符串向下取整但 0% 时至少为 1 个应用 goTemplate: true goTemplateOptions: [missingkeyerror] template: metadata: name: {{.cluster}}-guestbook labels: envLabel: {{.env}} spec: project: my-project source: repoURL: https://github.com/infra-team/cluster-deployments.git targetRevision: HEAD path: guestbook/{{.cluster}} destination: server: {{.url}} namespace: guestbook要点解读goTemplate: true开启 Go 模板渲染生成器参数envLabel标签来自生成器的env字段是步骤选择matchExpressions的匹配依据maxUpdate: 0让env-qa步骤只等待、不自动同步配合手动同步使用deletionOrder: Reverse保证删除时按env-prod → env-qa → env-dev的顺序逆序进行模板中的project、source、destination是 Application 的标准字段会被渐进式同步流程原样继承。参考实现与延伸阅读渐进式同步核心实现applicationset/progressivesync/progressive_sync.go配置校验问题模型applicationset/progressivesync/validation_issues.go渐进式同步单元测试applicationset/progressivesync/progressive_sync_test.go、applicationset/progressivesync/specchanged_regression_test.goApplicationSet 控制器集成逻辑applicationset/controllers/applicationset_controller.go控制器启动参数与环境变量cmd/argocd-applicationset-controller/commands/applicationset_controller.go配合使用的同步波次Resource Hooksdocs/user-guide/sync-waves.md注意事项与限制Beta 功能开启后请先在非生产环境验证关注控制器日志中的警告例如自动同步被强制关闭、非法maxUpdate、重复选中、空步骤等提示不要混用自动同步RollingSync 会强制关闭托管应用的自动同步并打印警告请确保模板中未配置syncPolicy.automated避免行为冲突未命中步骤的应用需手动同步任何未被matchExpressions选中的应用都不会被自动更新删除依赖最终器Reverse 删除依赖 ApplicationSet finalizer 保障顺序请勿手动移除该 finalizer否则可能破坏删除顺序保障。【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考