资讯详情

资讯详情

Argo CD Server-Side Apply 深度解析:从提案设计到三级配置的源码实现

Argo CD Server-Side Apply 深度解析从提案设计到三级配置的源码实现【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd本篇以 Argo CD 的提案文档 server-side-apply.md2022 年 3 月由 leoluz 发起为主体完整继承提案中的动机分析、设计目标、使用场景与风险缓解方案并结合当前仓库中 gitops-engine 同步上下文、资源操作实现 等源码讲清 Server-Side ApplySSA在 Argo CD 中的实际落地方式三级开启粒度、冲突处理策略、manager 注册机制与 Client-Side Apply 迁移。读完本文你可以掌握如何在 Application 与资源两个层面精确控制 SSA并理解其背后的实现细节与提案中未完全实现的差异。一、背景客户端 3-way merge 的局限提案开篇给出了引入 SSA 的核心动因Argo CD 在同步资源时使用 kubectl 库默认的客户端逻辑会在客户端即 Argo CD 自身完成三方合并3-way-mergeLive state集群中的实际状态Desired stateGit 中的期望状态Previous statelast-applied-configuration注解中记录的上次应用状态。客户端算好 patch 后再发送给 API Server。这种策略在大多数场景下工作良好但提案Motivation 章节指出了三类典型问题与 Admission Controllers 的互操作性差Validating/Mutating Webhook 只在服务端执行。当用户依赖 dry-run 判断是否继续部署时客户端计算的 patch 可能绕开或绕过这些钩子产生不符合预期的结果。启用 SSA 后即使资源没有 diff同步也会保证 Admission Controllers 被执行且 dry-run 结果更可靠。资源冲突识别能力弱SSA 通过自 Kubernetes 1.18 起所有资源都具备的managedFields元数据来分析字段所有权能更好地发现并处理与其他 controller 的字段冲突。大 CRD 同步失败客户端模式依赖last-applied-configuration注解保存上次状态而注解有 262144 字节256KB的大小上限。同步 schema 较大的 CRD 时经常因注解超限而失败SSA 不使用该注解天然规避此问题。二、提案的五个设计目标提案的 Goals 章节定义了五项必须达成的目标对照当前源码可以逐一核对实现情况G-1 细粒度配置允许用户在三个层级选择是否使用 SSA控制器级二进制 flag、Application 级syncOptions、资源级注解。G-2 Diff 阶段支持 Strategic Merge PatchDiff 计算需支持 strategic merge patch并保证 Service 等类型能正确 patch例如端口列表这类列表字段的合并语义。当前 diff 实现中已有针对 SSA 场景的适配例如 diff 主流程 中识别ServerSideApplytrue注解来决定 diff 行为配合 diff 选项构建 传递 SSA dry-run 能力。G-3 Admission Controllers 兼容性确保即使某资源没有 diffAdmission Controllers 也能被执行提案标注此点需要进一步调研。G-4 冲突管理Argo CD 应尊重字段所有权并提供配置让用户定义冲突时的行为。G-5 注册规范的 managerArgo CD 必须以预定义的 manager 名称注册自己而不是依赖 kubectl 代码的默认值默认 manager 为kubectl。这一目标已在当前代码中落实common/common.go 定义了常量ArgoCDSSAManager argocd-controller同步时通过 controller/sync.go 传入sync.WithServerSideApply(syncOp.SyncOptions.HasOption(common.SyncOptionServerSideApply)), sync.WithServerSideApplyManager(cdcommon.ArgoCDSSAManager),即所有 SSA 同步在managedFields中登记的 owner 均为argocd-controller便于运维识别“哪些字段归 Argo CD 管”。三、使用场景三级启用粒度与实际实现提案的 Use cases 章节定义了三个用户故事下面逐一对照当前仓库实现。UC-1控制器级启用提案设想提案建议实现一个二进制 flag--server-side-applytrue默认false让所有 Application 的同步都走 SSA。需要说明的是从当前源码看argocd-application-controller 命令行 中没有找到该控制器级--server-side-applyflag现有与 server-side 相关的控制器 flag 是--server-side-diff-enabled对应 G-2 的 diff 能力。也就是说提案中 UC-1 的设想在当前版本中并未以控制器全局开关形式落地实际可用的启用粒度是下面的 UC-2 与 UC-3。UC-2Application 级启用syncOptions提案建议新增 syncOptionServerSideApplytrue未设置时保持客户端行为。该设计已完整实现。官方文档 sync-options.md 中的示例apiVersion: argoproj.io/v1alpha1 kind: Application spec: syncPolicy: syncOptions: - ServerSideApplytrue其生效链路在 controller/sync.go控制器读取 Application 的syncOptions若包含ServerSideApplytrue则通过sync.WithServerSideApply(true)把该标志写入同步上下文。选项常量定义在 sync/common/types.goSyncOptionServerSideApply ServerSideApplytrue SyncOptionDisableServerSideApply ServerSideApplyfalse注意这里同时定义了ServerSideApplyfalse——这是提案 UC-3 之外的一个增量能力见下。UC-3资源级启用注解提案建议复用现有argocd.argoproj.io/sync-options注解在单个资源上声明ServerSideApplytrue且不能影响注解中的其他 sync-options。当前实现位于同步上下文的判定函数 shouldUseServerSideApplyfunc (sc *syncContext) shouldUseServerSideApply(targetObj *unstructured.Unstructured, dryRun bool) bool { // dry run 时禁用 server side apply目标是验证渲染后的 // 清单 yaml 正确性server 模式 dry-run 会破坏 namespace 自动创建能力 if sc.dryRun || dryRun { return false } resourceHasDisableSSAAnnotation : resourceutil.HasAnnotationOption( targetObj, common.AnnotationSyncOptions, common.SyncOptionDisableServerSideApply) if resourceHasDisableSSAAnnotation { return false } return sc.serverSideApply || resourceutil.HasAnnotationOption( targetObj, common.AnnotationSyncOptions, common.SyncOptionServerSideApply) }从这段源码可以提炼出四条明确的判定规则比提案文字描述更精确dry-run 永远不走 SSAsc.dryRun为真时直接返回false注释指出 server 模式 dry-run 会破坏“namespace 自动创建”功能资源级ServerSideApplyfalse具有最高否决权即使 Application 级开启了 SSA单个资源加注解argocd.argoproj.io/sync-options: ServerSideApplyfalse即可回退到客户端 apply资源级ServerSideApplytrue可以单独开启不依赖 Application 配置多选项共存无冲突HasAnnotationOption按逗号分割注解内容逐项匹配ServerSideApplytrue与其他选项如Validatefalse互不影响满足了提案“不影响其他 sync-options”的要求。典型资源级配置示例继承自 官方 sync-options 文档metadata: annotations: argocd.argoproj.io/sync-options: ServerSideApplytrue一个实际用途部分 YAML patch 存量资源SSA 还有一个客户端模式做不到的能力用不完整清单patch 存量资源。例如只更新 Deployment 副本数apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3按 Deployment 的 schema 规范这并非合法清单因此必须同时关闭校验。Application 配置如下spec: syncPolicy: syncOptions: - ServerSideApplytrue - Validatefalse此时 Argo CD 相当于执行kubectl apply --server-side --force-conflicts --validatefalse。文档同时明确了一点优先级Replacetrue优先于ServerSideApplytrue——在同步上下文的 apply 执行分支 中shouldReplace为真时走ReplaceResource/UpdateResource/CreateResource路径只有不满足 replace 条件时才调用ApplyResource。四、冲突处理Q-1 的结论如何落地提案的 Open Questions 中最关键的是 Q-1启用 SSA 后服务端可能返回与其他 manager 的字段冲突Argo CD 该怎么办提案的结论是第一版直接使用 force 语义覆盖冲突未来有需求再增加选项。当前源码印证了这一决策。在 kubectlResourceOperations 构建 apply 选项 时o.DeleteOptions.ForceDeletion force !serverSideApply o.ForceConflicts serverSideApply即只要走 SSA 路径就固定设置ForceConflicts true等价于kubectl apply --server-side --force-conflicts——遇到字段冲突时 Argo CD 声明这些字段的归属权而不是中止同步。这与官方文档的说明一致kubectl apply --server-side本身不支持--force因此Forcetrue单独存在时会被忽略资源仍按--force-conflicts处理Forcetrue仅在客户端 apply 或配合Replacetrue时生效。五、风险与缓解Risks and MitigationsR-1 目标集群版本检查SSA 在 Kubernetes 1.22 转 GAmanagedFields完整支持在 1.18 以 beta 引入。提案要求实现必须检查目标集群至少运行 1.18若启用 SSA 但集群版本低于 1.18Argo CD 应记录警告并回退到客户端同步。R-2 服务端/客户端 apply 交替切换KEP-555 的升级/降级策略部分提到Kubernetes 会校验 apply 请求的 user-agent 是否为kubectl以决定是否更新last-applied-configuration注解。Argo CD 依赖该注解因此在切换到 SSA、且 manager 取argocd-controller而非kubectl时必须保证注解的兼容处理不受影响避免 G-5 的 manager 改名破坏客户端/服务端模式的来回切换。当前代码中这一问题的缓解手段进一步演化为“Client-Side Apply 迁移”机制见下一节。六、当前实现中的增量Client-Side Apply 迁移在提案2022 年之后当前仓库在 sync_context.go 中新增了提案未涉及的 CSA→SSA 迁移能力恰好是对 R-2 交替切换风险的工程化解决needsClientSideApplyMigration 检查 live 对象的managedFields若目标 manager 的存在形式是operation: Update客户端 apply 的特征则判定需要迁移operation: Apply的 manager 视为已迁移避免重复迁移performCSAUpgradeMigration 借助csaupgrade包生成迁移 patch直接把 CSA manager 的字段所有权并入argocd-controller这个 SSA manager 并移除原 CSA 条目。注释明确说明这是 Argo CD 中 CSA→SSA 迁移的主要手段且刻意绕开了last-applied-configuration注解262KB 上限通过带冲突重试的managedFieldspatch 完成所有权转移。迁移在 apply 前的调用点位于 sync_context.go#L1443-L1450仅当serverSideApply !dryRun enableClientSideApplyMigration且确实检测到待迁移的Update操作 manager 时才执行失败则本次同步标记为SyncFailed并给出明确错误信息。用户侧默认开启该迁移也可通过 sync option 关闭见 sync-options 文档 的 Client-Side Apply Migration 一节。七、升级 / 降级与已知代价提案的 Upgrade / Downgrade 章节指出无需更新 CRD因为 Application 资源的syncOptions字段是非类型化的字符串数组[]string新增ServerSideApplytrue取值不需要 API 结构变更升级只需更新 Argo CD 控制器本身。Drawbacks 部分也坦承了唯一代价Argo CD 代码库复杂度略有增加——这一点从当前实现看确实成立shouldUseServerSideApply的多条件判定、CSA 迁移、dry-run 特殊处理等分支都集中在同步主路径上由 sync_context_test.go 与 e2e 测试 等用例覆盖验证。八、小结回到提案本身可以给出如下实现对照表提案要素当前实现状态依据G-5 注册argocd-controllermanager已实现common/common.go、controller/sync.goUC-2 Application 级ServerSideApplytrue已实现sync/common/types.go、sync-options 文档UC-3 资源级注解开启已实现且新增ServerSideApplyfalse资源级关闭sync_context.goQ-1 冲突处理用 force已实现固定ForceConflictstrueresource_ops.goUC-1 控制器级--server-side-applyflag当前源码中未见该 flag仅有--server-side-diff-enabledargocd_application_controller.goR-2 客户端/服务端交替切换以 CSA→SSAmanagedFields迁移机制缓解sync_context.go总体而言这份提案提出的 SSA 集成路线已在 Argo CD 中基本落地managedFields驱动的字段所有权、argocd-controller的显式 manager、冲突即 force 的策略以及针对注解 262KB 上限的迁移方案共同构成了 Argo CD 在“存量资源共存”与“大 CRD 同步”两类场景下的重要能力支撑。【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →