Karmada FederatedHPA 深度解析:把 Kubernetes HPA 从单集群扩展到多集群

发布时间:2026/9/18 1:49:14
Karmada FederatedHPA 深度解析:把 Kubernetes HPA 从单集群扩展到多集群
Karmada FederatedHPA 深度解析把 Kubernetes HPA 从单集群扩展到多集群【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmadaKarmada 是面向多云、多集群场景的 Kubernetes 编排系统它让用户可以像使用单集群一样在多个集群上运行应用。本篇文章围绕 Karmada 的设计提案 docs/proposals/hpa/federated-hpa.md 展开系统讲解 FederatedHPA 如何把单集群的 Horizontal Pod AutoscalerHPA能力带到多集群环境包括其设计目标、用户故事、架构方案、核心控制器职责、与现有 HPA 资源的迁移共存机制以及最终在仓库中的落地实现。读完本文你将理解 Karmada 多集群自动伸缩的设计思路与关键实现原理并掌握 FederatedHPA 相关的配置与使用方式。背景与动机为什么单集群 HPA 不够用了HPA 是 Kubernetes 生态中应对突发流量、提升资源利用率的经典手段它持续观测工作负载的指标如 CPU 利用率在指标超过目标时自动扩容副本在指标回落后缩容从而兼顾服务稳定性与资源成本。Karmada 让用户可以把应用同时调度到多个成员集群但早期版本并不具备跨集群的 HPA 能力——也就是说应用可以在多个集群运行但应用的弹性伸缩仍停留在单集群思维。提案 docs/proposals/hpa/federated-hpa.md 正是为填补这一空缺而提出把 HPA 从单集群带入多集群场景尽量让多集群下的用户体验与单集群 HPA 保持一致降低迁移成本。Goals设计目标提案明确列出五个目标将 HPA 从单集群扩展到多集群Bring HPA from single cluster to multiple clusters兼容单集群中的 HPA 相关资源Compatible with the HPA related resources in the single cluster能够容忍成员集群或 Karmada 控制面发生故障Tolerate the disaster of member cluster or karmada control plane更好地与工作负载迁移workloads shifting、云爆发cloud bursting等场景集成同时支持 Kubernetes 原生 HPA 与自定义 HPAcustomized HPA。Non-Goals非目标不处理工作负载由不同服务子集构成的场景Deal the workloads with different subset of services。也就是说本提案针对的是所有成员集群共享同一份应用负载、可被同一 HPA 统管的情况。使用约束Notes/Constraints/Caveats提案对适用场景有一项明确限制被同一个 HPA 资源选中的、分布在多个成员集群中的工作负载/Pod 必须平均分担应用负载。例如应用共 10 个 Pod按cluster1: 3 pods, cluster2: 7 pods分布则 cluster1 的 3 个 Pod 承担总请求的 3/10cluster2 的 7 个 Pod 承担 7/10。不满足该前提的场景不在本提案考虑范围内——这一约束决定了后续基于权重拆分 HPAmin/max的合理性。用户故事三类典型诉求提案通过三个 User Story 说明 FederatedHPA 要解决的真实问题Story 1平台开发者基于 Kubernetes 的 CD 生态建立在单集群上且重度依赖原生 HPA。希望在不做大幅改造的前提下把已有 HPA 资源平滑迁移到多集群最好兼容单集群中 HPA 的 Schema。Story 2应用开发者应用在 Karmada 上运行并启用 FederatedHPA配置了target cpu util 30%、min replica 3、max replica 100。某个成员集群突然故障、无法再创建新 Pod而此时恰好请求突发CPU 利用率超过 30%总共需要 100 个 Pod 才能扛住。希望 FederatedHPA 能自动在其他健康集群中扩容新 Pod而不是因为单个集群故障而整体失效。Story 3平台管理员Karmada 控制面宕机所有对控制面的请求失败。大量应用依赖 HPA 应对不可预测的请求突发如果系统无法容忍联邦控制面的故障发生 RCARoot Cause Analysis事故的概率会非常高。希望即使 Karmada 控制面不可用成员集群内的伸缩也能继续工作。Story 3 直接对应 Goal 3容忍控制面故障它也是该提案分布式设计思路的重要动因。核心架构设计FederatedHPAController 与成员集群原生 HPA 协同架构总览提案设计的架构如下图所示图片来源 docs/proposals/hpa/statics/karmadafederatedhpa-arch.drawio.png该设计遵循两条核心原则成员集群内的 Kubernetes HPA 组件继续使用、且可独立工作。提案不打算重写每个集群的伸缩逻辑而是复用原生 HPA 能力。设计不引入新的 CRD 或资源核心功能全部收敛在FederatedHPAController中注这是提案阶段的表述后续落地实现引入了一个名为FederatedHPA的 CRD详见下文从提案到实现一节。FederatedHPAController 的三大职责提案明确 FederatedHPAController 承担以下工作学习传播信息监听 HPA 资源以及与Workload对应的PropagationPolicy/ResourceBinding从而得知HPA 资源应该被传播到哪些集群、工作负载在集群之间按什么权重分布。创建 HPA 对应的Work资源将 HPA 传播到成员集群并根据学习到的权重把 HPA 资源的min/max字段拆分配置到各成员集群。重新分配当PropagationPolicy/ResourceBinding变化后重新分配 HPA 资源的相关字段。此外针对不同类型的Workload需要提供相应的ResourceInterpreterWebhook用于保留成员集群内的replicas并聚合状态。这正是 Karmada 的 resource interpreter webhook 能力pkg/resourceinterpreter/目录下包含 default 与 customized 两套解释器实现。FederatedHPAController 如何学习 Workload 的传播信息当一个新的 HPA 资源被创建或变更时FederatedHPAController 需要知道对应Workload的传播与权重信息。它的查找链路非常直接通过 HPA 的ScaleTargetRef字段定位到对应的Workload基于Workload与PropagationPolicy的ResourceSelectors匹配找到对应的PropagationPolicy。权重信息则直接复用 Karmada 调度器的调度结果——因为 Karmada scheduler 本来就在负责副本的跨集群调度分配FederatedHPAController 无需重复计算权重直接读取调度结果即可。这里存在一个关键矛盾成员集群内的HPAController会直接伸缩成员集群中的Workload这会与 Karmada scheduler 的副本分配产生冲突。提案的解法是利用 resource interpreter webhook 能力在成员集群侧保留replicas字段避免调度器的分配被成员集群内 HPA 的伸缩覆盖。两个棘手问题的处理方案问题一控制面spec.replicas与成员集群实际副本不一致原生 Kubernetes 中HPA 通过Workload如 Deployment的scale子资源完成伸缩伸缩后replicas字段会被更新为目标值。但在本设计中成员集群内的 HPAController 独立工作不再通过控制面伸缩工作负载因此成员集群的实际 Pod 数量与控制面Workload的spec.replicas会不一致。这种不一致会引发事故例如用户删除 HPA 资源时如果控制面的spec.replicas远小于成员集群中的实际副本数调度器会按错误的期望值做收缩导致服务容量被意外削减。提案的解决方案是FederatedHPAController 汇总各成员集群的spec.replicas之和写回控制面Workload的scale子资源让控制面的期望副本数始终与实际总副本数保持一致。即便控制面spec.replicas与成员集群实际总数一致只要该字段被修改Karmada scheduler 重新计算出的Work副本分布大概率仍与成员集群中的实际分布不一致同样可能引发上述事故。提案将其拆成两个子问题如何优雅迁移graceful shifting当 Karmada scheduler 计算的期望分布与成员集群实际分布差异显著时可能因PropagationPolicy变更或 HPA 被删除导致如何优雅地迁移成员集群内的工作负载避免服务容量不足。提案认为未来可能需要Federated Pod Disruption Budget之类的机制来解决该子问题建议放在另一个提案中单独解决。如何控制偏差即便启用了 FederatedHPA也要控制成员集群实际分布与 scheduler 期望状态之间的偏差。提案认为如果第一个子问题解决这个问题就不会太严重。问题二spec.replicas为 1 时怎么办当控制面spec.replicas大于 1 时工作负载可以分布到多个成员集群某个集群或控制面故障时其他集群仍能扩容从而容忍灾难。但当spec.replicas等于 1 时工作负载和 HPA 资源只会被传播到单个成员集群。如果该成员集群与控制面同时不可用工作负载将无法完成伸缩——这是该设计在极端场景下的固有局限提案对此做了明确说明。与现有 HPA 资源的集成与迁移在实际平台中Karmada 支持 FederatedHPA 之前用户可能已经通过PropagationPolicyOverridePolicy管理了大量 HPA 资源。提案考虑两种真实诉求出于风险考虑平台管理员希望逐步迁移这些 HPA 资源由 FederatedHPA 管理同一个 Karmada 控制面内部分用户想用原生 FederatedHPA部分用户想保持旧方式FederatedHPA不应与旧方式管理的 HPA 资源冲突。为此提案引入一个**标签label**作为开关federatedhpa.karmada.io/enabledtrue/false该标签标注在 HPA 资源上用于精细控制哪些 HPA 资源由 FederatedHPAController 接管从而实现渐进式迁移与新旧方式共存。用户故事如何落地一个完整的分布式示例以 Story 1 为例提案给出了完整的端到端场景第一步平台管理员预先创建一个全局默认的ClusterPropagationPolicy用于apps命名空间内的Workload资源传播clustera与clusterb的权重为4:1apiVersion: policy.karmada.io/v1alpha1 kind: ClusterPropagationPolicy metadata: name: default spec: placement: clusterAffinity: clusterNames: - clustera - clusterb replicaScheduling: replicaDivisionPreference: Weighted replicaSchedulingType: Divided weightPreference: staticWeightList: - targetCluster: clusterNames: - clustera weight: 4 - targetCluster: clusterNames: - clusterb weight: 1 resourceSelectors: - apiVersion: workload.example.io/v1alpha1 kind: Workload第二步用户在apps命名空间创建一个Workload5 个副本与一个HPAmin 2 / max 10CPU 平均利用率 50% 为目标apiVersion: workload.example.io/v1alpha1 kind: Workload metadata: name: nginx namespace: apps labels: app: nginx spec: replicas: 5 paused: false template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ------------------ apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nginx namespace: apps spec: scaleTargetRef: apiVersion: workload.example.io/v1alpha1 kind: Workload name: nginx minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50第三步Karmada scheduler 依据默认策略生成ClusterResourceBinding并完成调度apiVersion: work.karmada.io/v1alpha2 kind: ClusterResourceBinding metadata: name: xxx spec: resource: apiVersion: workload.example.io/v1alpha1 kind: Workload name: nginx ... clusters: - name: clustera replicas: 4 - name: clusterb replicas: 1第四步FederatedHPAController 持续监听 HPA 与 Karmada 相关资源ClusterPropagationPolicy/PropagationPolicy或ClusterResourceBinding/ResourceBinding的事件学习两件事HPA 资源应传播到哪些集群工作负载在各集群间的权重该权重将用于把 HPA 的min/max拆分到各集群。最终FederatedHPAController 创建/更新 HPA 对应的Work资源HPA 被传播到clustera和clusterbclustera的 min/max 为1/8clusterb的 min/max 为1/2按 4:1 权重拆分总 min2、max10 的结果。ResourceBinding相关类型定义位于 pkg/apis/work/v1alpha2ClusterPropagationPolicy/PropagationPolicy位于 pkg/apis/policy/v1alpha1。从提案到实现仓库中的落地代码值得说明的是原提案2022 年描述的是分布式方案——把 HPA 传播到成员集群并按权重拆分min/max而从仓库源码看最终落地的实现演变为集中式方案新增了FederatedHPACRD由控制面统一聚合多集群指标并计算出期望副本数再交给 Karmada scheduler 做跨集群分配。从 federatedhpa_types.go 的类型注释可以确认FederatedHPA 是集中式 HPA可以聚合多个集群中的指标。当系统负载上升时它从多个集群查询指标并扩容副本负载下降时同理缩容。副本伸缩后karmada-scheduler 会基于策略重新调度副本。以下梳理实际实现的关键模块帮助你把提案思想与代码对应起来。FederatedHPA CRD 定义CRD 定义在autoscaling.karmada.io/v1alpha1组中安装包位于 charts/karmada/_crds/bases/autoscaling/autoscaling.karmada.io_federatedhpas.yaml。核心类型见 pkg/apis/autoscaling/v1alpha1/federatedhpa_types.goFederatedHPASpec包含字段类型说明scaleTargetRefCrossVersionObjectReference指向要伸缩的目标资源用于采集指标与修改副本数必填minReplicas*int32缩容下限默认为 1maxReplicasint32扩容上限不能小于 minReplicasmetrics[]MetricSpec计算期望副本数所用的指标规格多指标取最大值未设置时默认使用 80% 平均 CPU 利用率behaviorHorizontalPodAutoscalerBehavior配置 scaleUp/scaleDown 方向的伸缩行为未设置时使用默认 HPA 伸缩规则从 CRD 的 kubebuilder 标记可以看出它支持fhpa短名、命名空间级作用域并在kubectl get时直接展示REFERENCE-KIND、REFERENCE-NAME、MINPODS、MAXPODS、REPLICAS等列federatedhpa_types.go。同组还提供CronFederatedHPAcronfederatedhpas实现定时触发式伸缩见 cronfederatedhpa_types.go。FHPAController 的协调流程控制器实现位于 pkg/controllers/federatedhpa/federatedhpa_controller.go文件头注释明确说明它是从 Kubernetes HPA controller 移植/借鉴而来被引用的代码已在注释中标记。FHPAController的核心数据结构federatedhpa_controller.go#L81-L110包含ReplicaCalc副本计算器ReplicaCalculatorClusterScaleClientSetFunc按集群创建 scale client 的函数TypedInformerManager多集群 informer 管理器用于在成员集群中维护 Pod informerrecommendations/scaleUpEvents/scaleDownEvents与原生 HPA 相同的缩容稳定窗口downscale stabilization与伸缩事件记录hpaSelectors双向多映射用于校验同一组 Pod 是否被多个 HPA 同时控制。Reconcile方法在每次协调结束后会以RequeueAfter: c.HorizontalPodAutoscalerSyncPeriod的方式周期重入federatedhpa_controller.go#L188。一次完整的reconcileAutoscaler流程如下federatedhpa_controller.go#L192-L406解析ScaleTargetRef的 API 版本获取目标资源对象通过getBindingByLabel依据目标资源上的PropagationPolicyPermanentIDLabel/ClusterPropagationPolicyPermanentIDLabel标签找到对应的ResourceBindingfederatedhpa_controller.go#L408-L449通过getTargetCluster从 binding 中取出状态就绪的成员集群列表federatedhpa_controller.go#L451-L469通过scaleForTargetCluster逐集群查询scale子资源汇总各集群的Spec.Replicas/Status.Replicas并借助按集群构建的 Pod informer 拉取各集群的 Pod 列表聚合为multiClusterScale与multiClusterPodListfederatedhpa_controller.go#L471-L550——这正对应提案中收集成员集群 spec.replicas 之和的思想读取控制面模板的scale子资源得到currentReplicas再依据minReplicas/maxReplicas分支判断目标副本为 0 时禁用伸缩、当前副本超过 max 时缩到 max、低于 min 时提到 min否则进入指标计算computeReplicasForMetrics对每种指标类型Object/Pods/Resource/ContainerResource见 federatedhpa_controller.go#L733-L771计算期望副本取最大值通过normalizeDesiredReplicas或normalizeDesiredReplicasWithBehaviors施加缩放限制scale up/down 速率、稳定窗口、min/max 约束逻辑与原生 HPA 的 stabilization 和 behavior 规则一致如calculateScaleUpLimit使用scaleUpLimitFactor 2.0、scaleUpLimitMinimum 4.0federatedhpa_controller.go#L68-L72若需要伸缩则修改控制面模板的scale子资源并提交更新随后更新 HPA 状态与事件。ReplicaCalculator 与校准因子副本计算器在 pkg/controllers/federatedhpa/replica_calculator.go同样注明大量代码 lifted 自 Kubernetes 的replica_calculator.go但有两处关键差异replica_calculator.go#L34-L38ReplicaCalculator不再内嵌 pod listerPod 列表由外层 controller 预先计算好再传入引入校准因子calibration当计算结果由全局就绪 Pod 数量或指标决定时用它校准期望副本数。在 federatedhpa_controller.go#L600-L602 中可以看到校准值定义为calibration : float64(scale.Spec.Replicas) / float64(specReplicas)即各集群实际期望副本总和 / 控制面模板副本数从而抵消多集群聚合场景下的比例偏差。多集群指标查询与 metrics-adapter指标查询抽象定义在 pkg/controllers/federatedhpa/metrics/interfaces.goQueryClient接口提供四类查询能力GetResourceMetric资源指标如 CPU/内存GetRawMetric按 selector 的原始指标GetObjectMetric对象指标GetExternalMetric外部指标。REST 客户端实现在 pkg/controllers/federatedhpa/metrics/client.go分别对接resource metrics API、custom metrics API与external metrics API与原生 HPA 的数据源形态保持一致。在实际链路中多集群指标由karmada-metrics-adapter提供pkg/metricsadapter。它在返回指标时会通过MergeAnnotation打上resource.karmada.io/query-from-cluster注解以记录指标来源集群见 pkg/metricsadapter/provider/resourcemetrics.go该注解键在 pkg/apis/autoscaling/v1alpha1/well_known_constants.go 中定义为QuerySourceAnnotationKey。controller-manager 中的装配与参数控制器由karmada-controller-manager启动装配代码在 cmd/controller-manager/app/controllermanager.go#L703-L734 的startFederatedHorizontalPodAutoscalerController中构建RESTMetricsClient→ 构建ReplicaCalculator→ 构建FHPAController并注册到 controller manager。控制器命名为federatedHPA-controllerfederatedhpa_controller.go#L66。相关启动参数定义在 pkg/controllers/federatedhpa/config/types.go默认值与语义如下与原生 kube-controller-manager 的 HPA 参数对齐参数默认值说明horizontal-pod-autoscaler-sync-period15sHPA 同步 Pod 数量的周期horizontal-pod-autoscaler-upscale-delay3m上次扩容后、允许再次扩容前的等待窗口horizontal-pod-autoscaler-downscale-stabilization5m缩容稳定窗口期间内不缩容到低于任何历史推荐值horizontal-pod-autoscaler-downscale-delay5m上次缩容后、允许再次缩容前的等待窗口horizontal-pod-autoscaler-tolerance0.1期望/实际指标比率相对 1.0 的最小变化量低于该值不触发伸缩horizontal-pod-autoscaler-cpu-initialization-period5mPod 启动后可能跳过 CPU 采样的时间段horizontal-pod-autoscaler-initial-readiness-delay30sPod 启动后、就绪状态变化按初次就绪处理的延迟窗口这些参数共同决定了 FederatedHPA 在控制面的伸缩节奏与稳定性与提案尽量与单集群 HPA 体验一致的目标相呼应。测试与质量保障控制器配套了较完整的单元测试federatedhpa_controller_test.go覆盖协调主流程与边界分支replica_calculator_test.go覆盖副本计算逻辑metrics/下有client_test.go、utilization_test.go覆盖指标客户端与利用率计算config/types_test.go覆盖配置解析。多集群伸缩是状态一致性与故障处理要求很高的能力测试是保障其正确性的重要基础。高可用、集成与测试计划提案模板中为High Availability、Integration、Test Plan预留了章节正文中为占位说明其核心思路贯穿在设计目标与用户故事之中高可用成员集群内 HPA 独立工作Story 3使得控制面故障时成员集群仍可独立伸缩集成通过ResourceInterpreterWebhook保留成员集群replicas、聚合状态通过标签机制与既有 PropagationPolicy 管理的 HPA 共存迁移测试需要同时考虑单元测试、集成测试与 e2e 测试尤其是与其他组件隔离测试 vs 组合测试的取舍以及实现中比较棘手的场景如多集群指标聚合、故障注入、稳定窗口行为的测试策略。风险与替代方案提案模板为 Risks and Mitigations、Alternatives 预留了讨论空间。从设计本身可以归纳出的主要风险点包括控制面spec.replicas与成员集群实际副本的偏差风险通过写回 scale 子资源缓解、分布变化时的优雅迁移风险建议由Federated Pod Disruption Budget类机制在未来解决、以及spec.replicas 1时单点集群的伸缩盲区。替代方案方面最终实现的集中式FederatedHPACRD聚合多集群指标、统一计算与提案最初的分布式方案按权重拆分 min/max 传播到成员集群代表了两种不同的取舍仓库中最终以集中式方案落地。总结Karmada FederatedHPA 的设计提案回答了如何把单集群 HPA 能力平滑带到多集群这一核心问题通过 FederatedHPAController 学习传播策略与调度权重、复用成员集群原生 HPA、通过标签实现渐进式迁移、并针对控制面副本不一致与单副本场景给出了明确的处理边界。仓库中的实际实现FederatedHPA CRD FHPAController ReplicaCalculator在继承 Kubernetes HPA 成熟逻辑的基础上以集中式指标聚合的方式完成了多集群自动伸缩的落地相关启动参数、CRD 与测试均可在当前仓库中直接查阅与验证。如果你正在规划多集群应用的弹性伸缩方案可以重点参考 federated-hpa.md 了解设计脉络再结合 federatedhpa_types.go 与 federatedhpa_controller.go 深入实现细节同目录下的 cronfederatedhpa.md 还提供了定时触发式伸缩CronFederatedHPA的延伸能力可作为后续研究方向的补充。【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考