内容提要
文章指出Kubernetes自动扩缩存在架构缺陷:HPA、VPA、KEDA、Karpenter等控制器各自独立运行,基于局部信息做出相互矛盾的决策,导致扩缩震荡、GitOps冲突和资源浪费。根本原因是工作负载容量本是一个耦合的优化问题,却被拆分成多个解耦控制器。解决方案是保留各执行组件,但增加统一智能控制层,综合副本、资源请求与成本,实现真正的自主决策。
延伸解读
局部最优为何导致全局震荡
文章用checkout-api的例子说明:HPA、VPA、KEDA、Karpenter各自基于局部信息做出合理决策,但彼此看不到对方的动作。HPA用声明请求作分母计算利用率,VPA却会缩小分母,导致HPA误判并过度扩容,形成“VPA缩、HPA扩”的死亡螺旋。这揭示了一个关键点:当多个控制器并发修改同一组API字段时,模块化反而制造了反馈不稳定。
GitOps与自动扩缩的冲突不是配置问题
文章指出,GitOps将Git视为唯一真相源,而HPA在流量高峰时修改副本数会触发OutOfSync。若开启自动同步,GitOps会把副本重置回基线,导致应用在峰值时容量不足。即使配置忽略副本差异,也破坏了声明式基础设施的完整性——Git不再反映生产现实,后续发布可能悄悄恢复过时基线。这说明冲突源于控制权归属,而非简单的忽略规则。
节点自动扩缩放大资源浪费
Karpenter依据容器声明的requests而非实际消耗来规划节点。文章举例:容器请求1000m CPU但实际只用150m,调度器仍预留整个核心,Karpenter便为“幻影需求”创建实例。文章还提到生产集群平均CPU利用率仅约8%,却仍大量配置节点。这意味着上游的过度请求会被节点层成倍放大为云账单,单纯优化节点层无法解决根因。
自主不等于自动:需要统一决策层
文章区分了“自动”与“自主”:现有扩缩器像生物反射,各自对单一信号做出预设反应,缺乏中枢神经系统。真正的自主需要闭环观察整个运行环境,权衡性能与成本,并对结果端到端负责。文章建议保留HPA、VPA、KEDA、Karpenter作为执行层,但增加统一智能控制层,综合副本、资源请求与成本做决策。这为平台团队提供了新的提问方向:谁来决定工作负载规模,以及它是否掌握全貌。
Q&A
为什么Kubernetes的HPA和VPA同时使用会导致扩缩震荡?
HPA基于Pod CPU利用率(实际使用量/声明请求量)计算目标副本数,而VPA会降低CPU请求以消除浪费。VPA降低请求后,分母变小,同样的流量会使CPU利用率百分比升高,触发HPA扩容;扩容后每个Pod的负载降低,VPA又会进一步降低请求,形成恶性循环:VPA不断缩小Pod规格,HPA却创建大量微小容器。
KEDA和HPA同时配置时会出现什么问题?
当KEDA基于队列长度扩缩容,而HPA基于CPU利用率扩缩容时,两者会同时操作同一个Deployment的/scale子资源。如果队列积压导致KEDA扩容,但工作负载是I/O密集型、CPU利用率低,HPA会认为资源过剩而缩容,导致API服务器记录交替的扩缩事件,实际处理吞吐量停滞。
GitOps(如Argo CD)如何与自动扩缩器产生冲突?
GitOps将Git仓库视为唯一事实来源。当HPA在流量高峰时扩容Deployment,Argo CD会标记应用为OutOfSync;如果启用自动同步,GitOps会将实时部署重置回基线副本数,导致应用在高峰时容量不足。即使配置忽略副本差异,也会破坏声明式基础设施,使Git不再反映生产现实,未来部署可能恢复过时的基线。
Karpenter节点自动扩缩器为什么会导致云成本浪费?
Karpenter严格根据容器声明的资源请求(而非实际消耗)来配置节点。如果容器请求1000m CPU但实际只使用150m,调度器仍会预留整个核心,Karpenter会为这种虚假需求配置物理实例,将上游的 sizing 低效放大为高昂的云账单。生产集群的平均CPU利用率仅约8%,却配置了大量节点。
文章认为Kubernetes自动扩缩的根本架构缺陷是什么?
根本缺陷在于将工作负载容量这个单一的、耦合的数学优化问题拆分给了多个解耦的控制器(HPA、VPA、KEDA、Karpenter)。这些控制器各自独立运行、基于局部信息做出决策,并发修改相同的API字段(如.spec.replicas、.resources.requests),却无法看到完整画面,导致决策相互矛盾、系统震荡。
文章提出的解决方案是什么?
保留现有的执行组件(HPA、VPA、KEDA、Karpenter)作为执行层,但增加一个统一的智能控制层。该控制层综合副本数、资源请求、限制和扩缩阈值,在满足延迟SLO的前提下以最低成本做出决策,实现真正的自主决策,而不是依赖反应式的单指标启发式。
“自动化”和“自主性”在自动扩缩上下文中有何区别?
自动化像生物反射:测量孤立的遥测信号并触发预定义响应(如HPA触发、KEDA扩缩、Karpenter配置节点),但缺乏中枢神经系统。自主性则需要一个闭环,观察整个运行环境,理解性能与成本之间的权衡,并对结果承担端到端责任。当多个独立反射同时作用于同一肢体时,系统就会震荡。