Karmada CronFederatedHPA 深度解析:面向多集群场景的定时弹性伸缩方案 📅 发布时间:2026/9/18 7:17:50 👁 浏览次数: Karmada CronFederatedHPA 深度解析面向多集群场景的定时弹性伸缩方案【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada导读CronFederatedHPA是 Karmada 提出的定时联邦水平自动伸缩Cron-based Federated Horizontal Pod Autoscaler方案用于应对黑色星期五双十一这类可预测的突发流量高峰。本文以其设计提案 cronfederatedhpa.md 为核心结合仓库中的 API 类型定义、控制器与 Webhook 源码及 E2E 测试完整讲解CronFederatedHPA的 API 设计、cron 调度语法、两种伸缩模式直接伸缩工作负载 / 调整 FederatedHPA 的 Min/MaxReplicas、时区支持、冲突约束以及可观测性设计。读完本文你将能够在多集群环境中用一份 CR 提前伸缩工作负载从容应对可预测的流量高峰。背景与动机为什么需要定时伸缩在标准 Kubernetes 集群中HPA 基于实时指标如 CPU、内存或自定义指标对工作负载进行伸缩。但面对可预测的突发流量高峰例如黑色星期五、双十一大促存在两个问题流量在特定时刻突然攀升HPA 依据指标做出反应需要一定时间扩容速度可能跟不上流量增长速度导致服务不可用高峰过后流量回落资源被闲置产生不必要的云成本。在单集群场景下业界已有CronHPA类方案允许集群管理员在指定时间提前扩容、事后缩容。本提案将这一思路延伸到多集群联邦场景提出CronFederatedHPA让管理员可以在特定时间点提前伸缩联邦工作负载如 Deployment、StatefulSet 等实现了 scale 子资源的资源或者在特定时间调整FederatedHPA的副本上下限从而保证服务始终可用。Goals本提案的目标可以归纳为三点定义CronFederatedHPAAPI实现在特定时间伸缩工作负载同时支持FederatedHPA和普通工作负载Deployment、StatefulSet或其他实现了scale子资源的资源给出涉及组件包括karmada-controller-manager的实现思路。用户故事提前扩容、事后缩容作为集群管理员我预知每天上午 9 点会出现一波流量高峰因此希望提前例如 30 分钟将相关服务扩容保证高峰到来时服务可用当高峰过去后例如 2 小时后再缩容以节省云成本。这正是CronFederatedHPA的核心使用场景在流量高峰到来之前提前扩容在高峰过去之后及时缩容从被动响应变为主动准备。API 设计一份 CR 表达何时伸缩、伸缩多少CronFederatedHPA的完整 API 定义位于 cronfederatedhpa_types.go与提案中的设计保持一致。其核心结构如下// CronFederatedHPA represents a collection of repeating schedule to scale // replica number of a specific workload. It can scale any resource implementing // the scale subresource as well as FederatedHPA. type CronFederatedHPA struct { metav1.TypeMeta json:,inline metav1.ObjectMeta json:metadata,omitempty // Spec is the specification of the CronFederatedHPA. // required Spec CronFederatedHPASpec json:spec // Status is the current status of the CronFederatedHPA. // optional Status CronFederatedHPAStatus json:status } // CronFederatedHPASpec is the specification of the CronFederatedHPA. type CronFederatedHPASpec struct { // ScaleTargetRef points to the target resource to scale. // Target resource could be any resource that implementing the scale // subresource like Deployment, or FederatedHPA. // required ScaleTargetRef autoscalingv2.CrossVersionObjectReference json:scaleTargetRef // Rules contains a collection of schedules that declares when and how // the referencing target resource should be scaled. // required Rules []CronFederatedHPARule json:rules }ScaleTargetRef伸缩目标spec.scaleTargetRef复用 Kubernetes 标准的CrossVersionObjectReference通过apiVersion/kind/name三元组定位伸缩目标。目标可以是任意实现了scale子资源的普通工作负载如Deployment、StatefulSetKarmada 的FederatedHPAautoscaling.karmada.io/v1alpha1。Rules定时伸缩规则每个CronFederatedHPA可以包含一组spec.rules每条规则声明何时执行、执行什么动作。CronFederatedHPARule的字段如下字段类型必填说明namestring是规则名同一 CronFederatedHPA 内必须唯一长度 132。规则名会作为执行历史的标识改名会被视为删除旧规则 新增新规则原有执行历史会被丢弃schedulestring是cron 表达式语法与 Kubernetes CronJob 一致targetReplicas*int32条件必填目标副本数仅在伸缩目标不是 FederatedHPA 时需要targetMinReplicas*int32条件必填目标 MinReplicas仅在伸缩目标是 FederatedHPA 时使用可与 targetMaxReplicas 同时或单独指定为 nil 表示不更新 FHPA 的.spec.minReplicastargetMaxReplicas*int32条件必填目标 MaxReplicas规则同上nil 表示不更新 FHPA 的.spec.maxReplicassuspend*bool否是否挂起后续执行默认falsetimeZone*string否规则使用的时区不指定时默认使用 karmada-controller-manager 进程的时区非法时区会在 Webhook 校验阶段被拒绝successfulHistoryLimit*int32否每条规则保留的成功执行记录条数必须为正整数默认 3范围 132failedHistoryLimit*int32否每条规则保留的失败执行记录条数必须为正整数默认 3范围 032从源码中的 kubebuilder 标记可以看出该资源还支持cronfhpa短名shortName并提供了REFERENCE-KIND、REFERENCE-NAME、AGE三个打印列便于kubectl get直接查看见 cronfederatedhpa_types.go。Status执行历史与下一次执行时间CronFederatedHPAStatus通过status.executionHistories记录每条规则的执行历史type ExecutionHistory struct { RuleName string json:ruleName // NextExecutionTime is the next time to execute. // Nil means the rule has been suspended. NextExecutionTime *metav1.Time json:nextExecutionTime,omitempty SuccessfulExecutions []SuccessfulExecution json:successfulExecutions,omitempty FailedExecutions []FailedExecution json:failedExecutions,omitempty }SuccessfulExecution记录ScheduleTime期望执行时间与ExecutionTime实际执行时间二者的差值可以用来评估控制器的执行效率同时记录实际生效的AppliedReplicas/AppliedMaxReplicas/AppliedMinReplicas。FailedExecution则额外记录人类可读的失败原因Message。理解status.executionHistories[*].NextExecutionTime的一个关键是它代表下一次执行时间而非上一次执行时间。提案给出了两个示例schedule 为3 * * * *每小时的第 3 分钟在 9:04 应用规则时NextExecutionTime为 10:03下一次 10:03 执行执行后更新为 11:03。schedule 同为3 * * * *在 9:01 应用规则时NextExecutionTime为 09:03执行后更新为 10:03。组件实现控制器 Webhook 双引擎karmada-controller-manager调度执行引擎CronFederatedHPA控制器实现于karmada-controller-manager中代码位于 pkg/controllers/cronfederatedhpa/。控制器会在配置的时间点检查并执行规则时间由spec.rules[*].schedule决定采用标准的 5 段 cron 表达式格式# ┌───────────── minute (0 - 59) # │ ┌───────────── hour (0 - 23) # │ │ ┌───────────── day of the month (1 - 31) # │ │ │ ┌───────────── month (1 - 12) # │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday; # │ │ │ │ │ 7 is also Sunday on some systems) # │ │ │ │ │ OR sun, mon, tue, wed, thu, fri, sat # │ │ │ │ │ # * * * * *常见示例描述等价表达式每年 1 月 1 日午夜执行一次0 0 1 1 *每月第一天午夜执行一次0 0 1 * *每周日午夜执行一次0 0 * * 0每天午夜执行一次0 0 * * *每小时开始时执行一次0 * * * *从源码实现看控制器由三部分组成cronfederatedhpa_controller.go标准 controller-runtime 控制器controller 名为cronfederatedhpa-controller负责监听CronFederatedHPA对象的增删改。Reconcile流程会当对象删除或处于删除中时停止所有 cron 执行器当scaleTargetRef发生变化时重建执行器为每条规则创建/更新/删除对应的定时任务并同步status.executionHistories中的NextExecutionTime。cronfederatedhpa_handler.go基于github.com/go-co-op/gocron封装了调度器管理器CronHandler以[CronFederatedHPA 名][规则名]的二级 map 维护每个规则的 gocron Scheduler。创建执行器时会先time.LoadLocation(rule.TimeZone)解析时区代码中通过import _ time/tzdata内嵌 tzdata 以支持时区解析未指定时则使用进程本地时区。cronfederatedhpa_job.go真正执行伸缩动作的ScalingJob。RunCronFederatedHPARule是 gocron 调度的入口先判断规则是否被Suspend挂起则跳过随后根据scaleTargetRef的 apiVersion 分流执行ScaleFHPA或ScaleWorkloads最后写入成功/失败执行历史。两种伸缩动作的底层实现直接伸缩工作负载ScaleWorkloads通过client.SubResource(scale)读取目标资源的 scale 子资源比较当前spec.replicas与targetReplicas不一致时调用helper.ApplyReplicaAlways强制写入目标副本数并通过 scale 子资源更新。由于Deployment、StatefulSet等均实现了 scale 子资源因此它们天然可作为伸缩目标。伸缩 FederatedHPAScaleFHPA获取同命名空间下名为scaleTargetRef.name的FederatedHPA当targetMaxReplicas与 FHPA 当前spec.maxReplicas不一致时更新之当targetMinReplicas与 FHPA 当前spec.minReplicas不一致时更新之。两个动作都用retry.RetryOnConflict包裹以应对并发更新导致的资源版本冲突。执行完成后job 会依据规则的成功/失败历史上限由successfulHistoryLimit/failedHistoryLimit决定默认 3见 helper/cronfederatedhpa.go修剪记录并将最新执行历史前插到status.executionHistories中同时更新NextExecutionTime。此外执行耗时还会上报到 Karmada 的 metricsmetrics.ObserveProcessCronFederatedHPARuleLatency便于观测调度执行效率。karmada-webhook准入校验为了保证配置正确性CronFederatedHPA的校验逻辑实现在karmada-webhook中代码位于 pkg/webhook/cronfederatedhpa/validating.go。校验规则包括目标类型约束若spec.scaleTargetRef.apiVersion为autoscaling.karmada.io/v1alpha1则kind只能是FederatedHPA且规则中targetMinReplicas与targetMaxReplicas不能同时为空非 FHPA 目标约束若 apiVersion 不是autoscaling.karmada.io/v1alpha1则规则中targetReplicas不能为空cron 格式校验spec.rules[*].schedule必须是合法的 cron 表达式使用github.com/adhocore/gronx校验其他校验规则名不能重复timeZone必须能被time.LoadLocation解析非法时区直接拒绝针对 FHPA 的targetMinReplicas必须大于 0、targetMaxReplicas必须大于 0 且不小于targetMinReplicas针对普通工作负载的targetReplicas必须大于等于 0允许缩容到 0例如周末清空副本。这些校验与提案中的设计一一对应并在 validating_test.go 中通过构造不同场景进行了单元测试覆盖。实战配置两种伸缩模式与多时区场景场景一直接伸缩 Deployment回到用户故事 1要求每天 08:30 将工作负载扩容到 1000每天 11:00 缩容到 1。apiVersion: autoscaling.karmada.io/v1alpha1 kind: CronFederatedHPA metadata: name: cron-federated-hpa spec: scaleTargetRef: apiVersion: app/v1 kind: Deployment name: shop rules: - name: Scale-Up schedule: 30 08 * * * targetReplicas: 1000 - name: Scale-Down schedule: 0 11 * * * targetReplicas: 1说明示例 YAML 沿用提案原文写法。在实际 Kubernetes 中Deployment 的 apiVersion 为apps/v1请按你的集群实际情况填写scaleTargetRef.apiVersion。场景二调整 FederatedHPA 的 MinReplicas推荐直接设targetReplicas会在 11:00 将副本瞬间从 1000 砍到 1可能造成服务中断。更稳妥的做法是把伸缩目标指向FederatedHPA通过调整其MinReplicas让 HPA 平滑接管apiVersion: autoscaling.karmada.io/v1alpha1 kind: CronFederatedHPA metadata: name: cron-federated-hpa spec: scaleTargetRef: apiVersion: autoscaling.karmada.io/v1alpha1 kind: FederatedHPA name: shop-fhpa rules: - name: Scale-Up schedule: 30 08 * * * targetMinReplicas: 1000 - name: Scale-Down schedule: 0 11 * * * targetMinReplicas: 1采用这种方案11:00 时工作负载不会被骤然缩容避免了潜在的服务中断——这正是提案特别强调的推荐做法。场景三按业务时区配置timeZone假设业务同时面向美国和中国每天北京时间 07:30 有一波高峰洛杉矶时间 07:30 也有一波高峰而工作负载部署在中国时区的集群中。可以为不同规则配置各自的timeZoneapiVersion: autoscaling.karmada.io/v1alpha1 kind: CronFederatedHPA metadata: name: cron-federated-hpa spec: scaleTargetRef: apiVersion: autoscaling.karmada.io/v1alpha1 kind: FederatedHPA name: shop-fhpa rules: - name: scale-up-asia-shanghai schedule: 30 07 * * * targetMinReplicas: 1000 timeZone: Asia/Shanghai - name: scale-up-america-los-angeles schedule: 30 07 * * * targetMinReplicas: 1000 timeZone: America/Los_Angeles这样工作负载会在 Asia/Shanghai 与 America/Los_Angeles 时区每天 07:30 分别扩容到至少 1000 副本。时区名遵循 IANA tz database 规范如Asia/Shanghai、America/Los_Angeles非法时区会被 karmada-webhook 拒绝。风险与约束避免与 FederatedHPA 双重伸缩需要特别强调的是CronFederatedHPA既可以伸缩FederatedHPA也可以直接伸缩工作负载。如果工作负载正被FederatedHPA管理同时又配置了CronFederatedHPA直接伸缩该工作负载两者会在同一时刻争夺副本数控制权产生冲突如下所示因此请务必保证同一工作负载不会同时被FederatedHPA和CronFederatedHPA直接伸缩。合理的使用方式是二选一工作负载不启用 FHPA 时用targetReplicas直接设定副本数工作负载启用 FHPA 时用targetMinReplicas/targetMaxReplicas调整 FHPA 的边界把实际副本决策交给 HPA。高可用与测试保障高可用CronFederatedHPA的调度执行完全依赖 Karmada 控制平面。为保证高可用Karmada 控制平面应跨可用区multi-zone高可用部署若控制平面整体宕机工作负载将无法再被定时伸缩。这一约束与 Karmada 其他控制面组件一致属于部署层面的前提条件。开发与测试计划提案将实现分为两个阶段先在karmada-controller-manager中实现控制器伸缩工作负载或设置 FHPA 副本边界再在karmada-webhook中实现准入校验。测试方面要求现有测试全部通过、不引入破坏性变更并新增 E2E 用例覆盖新特性包括在不同时间直接伸缩工作负载、在不同时间设置 FHPA 的 MinReplicas/MaxReplicas、构造不同场景校验 Webhook 校验逻辑。这些测试计划已经在仓库中落地控制器单元测试覆盖了执行器管理、scaleTargetRef 变更检测、cron 任务创建等关键路径见 cronfederatedhpa_handler_test.goE2E 测试位于 test/e2e/suites/base/cronfederatedhpa_test.go配套的测试框架封装创建、删除、更新规则见 test/e2e/framework/cronfederatedhpa.go辅助函数挂起判断、历史记录上限、对象 key 生成及其单测见 pkg/util/helper/cronfederatedhpa.go 与对应的测试文件。总结CronFederatedHPA为多集群场景提供了可预测流量高峰的主动伸缩能力通过一份 CR 即可按 cron 表达式在指定时间直接伸缩工作负载副本数或调整FederatedHPA的 Min/MaxReplicas并支持按规则独立配置时区以适配全球化业务。其核心机制由karmada-controller-manager中的调度执行引擎基于 gocron与karmada-webhook中的准入校验共同保障执行历史与下次执行时间通过 status 完整暴露方便运维观测与排障。使用时唯一需要牢记的约束是避免FederatedHPA与CronFederatedHPA对同一工作负载的直接伸缩二者应通过伸缩 FHPA 副本边界的方式协同工作。【免费下载链接】karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration项目地址: https://gitcode.com/GitHub_Trending/ka/karmada创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考