看容器集群哪些资源在白白闲置,核心动作就是拿 Pod 的 requests、limits 和实际用量做三方对比,再叠加节点可分配资源与已分配资源的差值,凡是 requests 高但实际用量低、节点有剩余但无法调度的部分,都是闲置。
容器集群资源闲置怎么排查?先分清三种“白占坑”面孔
很多运维看到集群节点 CPU 使用率只有个位数,第一反应是“有资源浪费”,但真正动手查的时候,又说不清到底谁在浪费,容器集群里的闲置资源,通常不是一种单一面孔,而是三种情况叠加出来的。
- requests 申请过高:Pod 调度时向节点“预订”了 2 核 4G,实际运行只吃 0.2 核 300M,节点认为这 2 核 4G 已经被占掉,无法再分给别的 Pod。
- limits 预留过宽:limits 是容器能摸到的上限,有些团队图省事,直接把 limits 设成节点物理核数,结果容器内应用以为自己有 8 核,实际只用了 1 核,多出来的 7 核在节点上被“冻住”。
- 节点碎片化:单个节点看剩余资源足够,但新 Pod 要求 2 核 4G,节点却只剩下 1.5 核 6G 或 3 核 2G,资源东一块西一块,谁都调度不上去。
业内专家指出,相当一部分容器集群存在 requests 与 limits 设置不合理导致的隐性闲置,这种闲置不像显性故障那样报警,往往要等成本账单出来才被关注。
Kubernetes资源利用率低怎么办?从 requests 和 limits 这本账算起
Kubernetes 资源利用率低,大多数情况下不是节点物理机不够强,而是 requests 和 limits 的账本对不上实际花销,要弄明白闲置在哪,先得看懂这两个字段。
| 字段 | 作用 | 典型误解 | 对闲置的影响 |
|---|---|---|---|
| requests | 调度依据,决定 Pod 落到哪个节点 | 当作“最大使用量”来填 | 填太高,节点资源被提前占满 |
| limits | 资源上限,限制容器最多用多少 | 当作“预留”来填 | 填太高,容器突发时可能吃垮节点,平时又空着 |
| 实际用量 | 应用真实消耗 | 不去看监控 | 不知道 requests 比实际大多少倍 |
举一个具体场景:一个 Java 服务,启动时 JVM 堆内存设置 1G,非堆再加 300M,日常流量下整 Pod 内存使用 1.3G,但部署时为了“稳妥”,写的是 requests memory 4Gi,limits memory 8Gi,节点上这一个 Pod 就多占用了 2.7G 不可调度的内存。
Kubernetes 资源利用率低怎么办,第一步不是加机器,也不是急着上超卖,而是把 requests 改到接近真实峰值,可以用一条命令把 Pod 的 requests、limits 和当前实际用量拉出来对比:
kubectl top pods --all-namespaces --containers
再配合自定义列查看 requests 设置:
kubectl get pods -n production -o custom-columns=POD:.metadata.name,REQ_CPU:.spec.containers[].resources.requests.cpu,LIM_CPU:.spec.containers[].resources.limits.cpu,REQ_MEM:.spec.containers[].resources.requests.memory
两条命令的结果放到一起,肉眼就能看出哪些 Pod 是“申请了套房,住了个工位”。
用几条 kubectl 命令快速找出“白吃资源”的 Pod
排查容器集群资源闲置,离不开可验证的实操路径,下面按从集群到 Pod 的顺序走一遍。
先看节点总体水位
kubectl top nodes
输出里 CPU(cores) 和 MEMORY(bytes) 是节点当前实际使用量,不代表调度水位,真正决定能否继续调度的是 Allocatable 和 Requests 的差值,查看节点已分配资源:
kubectl describe node <node-name> | grep -A 5 "Allocated resources"
Allocated resources 里 CPU requests 已经 90%,但 kubectl top nodes 显示实际 CPU 使用率只有 15%,说明大量资源是被“预订”而不是被使用。
再查哪些 Pod 的 requests 与实际用量差距大
用 kubectl top pod 列出实际用量,再用 kubectl get pod -o yaml 或自定义列列出 requests,把两者放进同一个表格或脚本里比较,下面是一个不需要额外工具的对比思路:
kubectl get pods -n default -o jsonpath='{range .items[]}{.metadata.name}{" "}{.spec.containers[].resources.requests.cpu}{" "}{.spec.containers[].resources.requests.memory}{"n"}{end}'
然后手动对照 kubectl top pods -n default,多数情况下,requests 比实际用量高 3 到 5 倍的 Pod,就是闲置资源的主要贡献者。
找出“零使用”的静态 Pod 和不必要的副本
有些 Pod 长年运行,但没有任何流量或任务,比如旧版服务已经切换流量,但 Deployment 还保留 3 个副本,查一下 Pod 的年龄和最近重启时间:
kubectl get pods --all-namespaces --sort-by=.status.startTime
再结合应用日志或接入层流量,如果长时间没有请求进入,这类 Pod 的 requests 和 limits 就是纯粹闲置。
节点CPU内存闲置率为什么降不下来?问题常出在调度侧
很多集群明明整体资源充足,但新 Pod 就是调度失败,节点 CPU 内存闲置率居高不下,这通常不是资源不够,而是调度约束把资源切成了碎块。
- NodeSelector 和亲和性太死:某些 Pod 只允许落在特定标签的节点上,即使其他节点空闲,也无法使用。
- 污点和容忍不匹配:GPU 节点打了污点,只允许 GPU Pod 调度,但如果 GPU Pod 只申请了 GPU,没有申请足够 CPU 内存,节点上的 CPU 内存就空着。
- 拓扑分布约束不合理:为了高可用,强制每个可用区至少一个副本,但某个区节点少,导致该区资源被独占。
举个真实一点的场景:集群有 6 个节点,2 个节点标记为 disk=ssd,一个日志服务要求必须落在 SSD 节点,requests 2 核 4G,结果这 2 个 SSD 节点上塞满了日志 Pod,其他 4 个节点 CPU 使用率只有 5%,从全局看,资源闲置了一半,但从调度角度看,SSD 节点已经满了。
解决这类节点 CPU 内存闲置率问题,要检查节点标签、污点、亲和性规则是否过度限制,命令如下:
kubectl get nodes --show-labels kubectl describe node <node-name> | grep -A 3 "Taints"
适当放宽标签约束,或者把非关键服务的亲和性从“必须”改成“优先”,就能让闲置节点重新接单。
容器集群成本优化方案:把闲置资源变成可复用池
把闲置资源找出来之后,需要一套可持续的容器集群成本优化方案,而不是每次靠人工跑命令。
-
设置合理的 requests 基准
:建议以过去 7 到 14 天的实际峰值加上一定缓冲作为 requests,缓冲比例不必拍脑袋,可以用监控数据回看。 - 启用 Vertical Pod Autoscaler:VPA 能根据历史用量自动调整 requests 和 limits,但要注意,VPA 调整 requests 会触发 Pod 重建,需要在低峰期执行。
- 使用 HPA 做横向弹性:白天副本数多,夜间副本数少,HPA 根据 CPU 或自定义指标自动增减副本,避免夜里还开着满额 Pod。
- 对批处理任务使用优先级和抢占:低优先级任务可以填在空闲资源上,高优先级 Pod 来了就抢占,这样闲置资源可以用来跑 CI、模型训练等可中断任务。
行业共识认为,单纯靠人肉巡检无法长期解决容器资源闲置,必须把利用率的评估纳入 CI/CD 和容量管理流程,比如每次发布前,用 CI 检查 requests 是否超过实际用量的两倍,超过就拦截或告警。
容器资源超卖和闲置的区别需要分清:超卖是故意让 requests 总量超过节点可分配资源,利用的是不同 Pod 使用峰值错开的时间差,闲置是 requests 本身设置不合理导致节点预留了过多用不到的资源,超卖有风险,闲置是纯粹浪费,处理顺序一定是先消闲置,再考虑超卖。
容器集群资源闲置相关问题解答
容器集群资源闲置如何快速定位?
先看 kubectl top nodes 了解实际使用水位,再看 kubectl describe node 的 Allocated resources 了解调度水位,两者差距大,说明 requests 申请过度,再用 kubectl top pods 和 requests 对比,定位具体 Pod。
Kubernetes集群怎么查哪些Pod浪费资源?
用自定义列输出 Pod 的 requests 和 limits,与 kubectl top pods 的实际用量对比,重点关注 requests 比实际用量高 3 倍以上、且长期没有流量或任务的 Pod,再检查这些 Pod 是否由 Deployment、StatefulSet 控制,评估副本数是否过多。
容器集群成本优化从哪一步开始?
第一步永远是把 requests 调准,先采集 7 到 14 天实际用量数据,把 requests 设置到接近真实峰值的水平,第二步才是上 VPA、HPA 等自动化策略,跳过第一步直接上超卖,等于在错误的账本上叠加风险。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/638848.html





