
你是否也遇到过这样的情况:查看 Kubernetes 集群仪表盘,各项资源使用率明明看起来很健康,有充足的余量,但集群却在不断地自动添加新节点?这不是幻觉,也不是自动扩缩器配置错了,而是一个在运维良好的集群中也经常出现的经典问题。
根据 CNCF 的最新年度调查,Kubernetes 已成为生产环境中运行 AI 工作负载的默认平台。随着更多突发性、高资源需求的工作负载(尤其是 AI 推理)被调度到 Kubernetes 上,一种熟悉的模式正变得日益普遍:即便监控图表显示利用率正常,集群容量仍在悄悄增长。
如果你已经部署了 Cluster Autoscaler 或 Karpenter,并且排除了节点规格不当、约束过紧或整合策略等明显问题,但容量仍在增加,那根源很可能不在于工具本身,而在于输入数据。问题通常出在 Pod 的资源请求(Request)设置上。这些请求值往往是凭经验估算并加上了安全余量,而且一旦设定,就很少随着工作负载的实际变化而重新审视。
令人困惑的矛盾:指标正常,调度却失败
从监控大盘上看,集群级别的 CPU 和内存使用率图表可能一片“祥和”。但从调度器的视角看,故事完全不同。问题通常会按以下顺序显现:
- 集群范围的资源图表显示有充足空间。
- 然而,调度器(Scheduler)却报告无法放置新的 Pod。
- 新的 Pod 因此陷入
Pending 状态。
- 为了安置这些 Pod,自动扩缩器(Autoscaler)开始添加节点容量。
从外部看,集群仿佛在不该扩容的时候进行了扩容。但从内部逻辑看,它只是在忠实地执行设计目标:根据 Pod 声明的资源请求(Request)来保守地进行调度和打包。
调度器做决策的依据是“请求”,而不是“实际使用量”。因此,当 Pod 的请求值设置得远高于其实际使用时,节点在资源实际被耗尽之前,就会被调度器视为“已满”。一旦没有节点能满足新 Pod 夸大的请求,自动扩缩器就会介入,添加足够的容量来满足这些“预留”需求。于是,集群开始增长,即使从使用率仪表盘上看,一切仍然正常。
即便在运行良好的集群中,请求漂移也会发生
不要以为只有混乱的运维环境才会出现这个问题。实际上,请求漂移(Request Drift)的原因通常非常普通,甚至有些“无聊”:
- 事件响应后遗症:某个服务曾发生过不稳定事件,运维人员提高了其资源请求值以增加稳定性。事件过后,请求值却再也没被调低,因为没人愿意冒险成为那个“调低配置后导致问题复发”的人。
- 被遗忘的默认值:为了标准化发布流程,团队为服务设定了一套默认资源请求。这些默认值在无人记得其设定缘由后,仍被不断复制到新的服务配置中。
- 工作负载的自然演变:流量模式在变,依赖关系在变,业务逻辑在变。一个季度前看似合理的请求值,在几次新版本发布、用户增长或新增了批处理任务后,可能已严重偏离实际。
- AI推理等突发负载放大效应:推理类工作负载会更快速地暴露此问题,因为其副本数会随请求量剧烈波动。一个被高估的请求值,乘以突然暴涨的副本数,瞬间就会“吃掉”大量纸上预留的容量,从而触发不必要的节点扩容。
无论原因如何,结果都是一样的:过时的请求值在 YAML 文件里“幸存”下来,因为缺乏一个强制机制去定期回顾和修正它们。
排查第一步:先问请求值是否还靠谱
当你感觉集群的扩缩行为不对劲时,第一个要问的问题不是工具配置,而是:我们为工作负载设置的资源请求,是否还符合它们今天的实际运行情况?
如果请求值被夸大,那么在你看来本应能装下的 Pod,会被调度器拒之门外。从打包效率看,集群显得比实际更“满”,这误导了自动扩缩器——它开始为不存在的“纸面压力”添加节点,而非真实的资源压力。此时,再好的资源整合策略也无济于事,因为集群在调度器的算法里已经“满”了。
我们的目标不是追求绝对精确的数字,而是将请求值拉回一个合理的范围,让调度和自动扩缩的逻辑不再被过时的预留信息所干扰。
如何快速确认是否存在请求漂移?
进行一次快速的健康检查并不需要启动一个大项目。你可以从占用集群容量最多的那几个命名空间入手,做一两个简单的对比:
- 比较请求与使用量:不是看某个瞬间的快照,而是对比一段时间内(例如一两周)的“平均/峰值请求”与“平均/峰值实际使用量”。寻找那些日复一日持续存在的显著差距。
- 观察扩缩时的变化:重点关注工作负载在压力下扩展时的情况。当副本数从 5 个激增到 50 个时,每个 Pod 上那一点被高估的请求,会迅速累积成巨大的预留容量缺口,直接触发节点扩容。
一旦确认请求值被夸大且副本数会增长,那么集群增加节点就完全是符合逻辑的预期结果了。
从成本视角看问题:分配视图的辅助作用
成本或资源分配视图在这里能提供很大帮助,即使你不进行严格的财务分摊。当请求值存在漂移时,分配视图会清晰显示出矛盾:
- 分配的成本/资源很高(基于夸大的请求值计算)。
- 实际使用的成本/资源很低。
- 共享的基础服务开销变得模糊不清,混杂在每个人的数字里。
这时,可以提出一些更具体的问题来引导分析:
- 哪些命名空间或服务是资源“虚高”的主要贡献者?
- 这种差距是由少数稳定工作负载长期造成的,还是由突发性负载剧烈扩缩瞬间导致的?
- 差距中有多少比例是共享服务/安全缓冲,有多少是业务工作负载直接“虚占”的?
厘清这些类别后,讨论就不再是争论监控数据是否准确,而是聚焦于如何解决最大的资源错配问题。
解决方案:从小处着手,建立可持续机制
很多团队容易在这里过度设计。实际上,你通常只需要从少数几个关键工作负载开始调整,就能取得显著效果。
从主导基线容量的核心服务开始。将这些服务的资源请求调整到更贴近现实的水平,你会发现节点的打包效率立刻提升,自动扩缩器也不再盲目追逐虚假的预留需求。通常,这就是集群停止“莫名”扩缩的时刻。
另一个关键因素是建立部署安全信心。如果每次调整请求值都可能触发告警,那么没人会愿意去做。高估的值之所以长期存在,就是因为它们“感觉”更安全。
因此,可持续的方法是有意保持流程的简单和可控:
- 逐步调整:不要一次性大面积修改,从小范围开始。
- 便于回滚:确保任何调整都能快速、平滑地回退。
- 设置防护栏:明确规则,约定每次调整的激进程度和验证步骤。
当团队确信调整资源请求不会破坏服务稳定性时,管理请求漂移就会从一个棘手难题,变成一个常规的、可执行的运维动作。
当漂移得到控制后,变化是显而易见的
当资源请求值更接近现实后,许多奇怪的现象会随之消失:
- 调度器能够更高效地打包工作负载。
- Pending 的 Pod 数量与实际需求挂钩,而非过时的预留。
- 自动扩缩器 只在面对真实的资源压力时才增加容量。
- 成本分配也更容易解释,因为共享开销变得清晰可见,而不是隐藏在每个人虚高的数字里。
总结一下:如果你的 Kubernetes 集群在仪表盘看似正常的情况下仍在不断添加节点,别急着调整自动扩缩器的参数。首先检查那些资源消耗大户的 Pod 请求值。对比它们一段时间内的请求量与实际使用量。如果两者相差甚远,那么你很可能已经找到了集群异常扩缩行为背后的根本驱动因素。在 云栈社区 的云原生板块,你可以找到更多关于 Kubernetes 资源优化和成本治理的深度讨论与实践案例。
引用链接
[1] Why is your Kubernetes cluster adding nodes when the dashboards look fine?: https://thenewstack.io/why-is-your-kubernetes-cluster-adding-nodes-when-the-dashboards-look-fine/
[2] 最新年度调查: https://www.cncf.io/announcements/2026/01/20/kubernetes-established-as-the-de-facto-operating-system-for-ai-as-production-use-hits-82-in-2025-cncf-annual-cloud-native-survey/
[3] 却在扩缩: https://thenewstack.io/kubernetes-gets-back-to-scaling-with-virtual-clusters/
[4] 团队需要一种发布方式: https://thenewstack.io/think-like-a-developer-to-help-dev-teams-ship-faster/
[5] 调度器会阻止那些本应能适应的放置: https://thenewstack.io/webassembly-needs-schedulers-and-kubernetes-doesnt-quite-fit-the-bill/
[6] 围绕: https://thenewstack.io/how-to-put-guardrails-around-containerized-llms-on-kubernetes/
[7] 共享开销是可见的,而不是隐藏在: https://thenewstack.io/apple-insiders-share-the-story-of-the-birth-of-the-macintosh/