Requests 参与放置和资源共享,limits 约束运行时消耗。它们是有关联的输入,不是对应用性能的一套通用下限与上限保证。应结合负载行为、争用风险和恢复要求选择,并查看准入后的 Pod,因为默认值与策略可能改变清单里提交的资源值。先区分记账、实际使用和执行约束,才能解释配置为什么影响行为。

默认值也是契约的一部分

某资源只有 limit、没有 request 时,如果准入没有提供另一请求,Kubernetes 会把限制复制为请求。因此,只配 limit 通常不是零调度成本。LimitRange 默认值与 ResourceQuota 检查也会影响准入。解释 Pod 为什么 Pending 之前,应读取实际保存的两张资源映射,不能仅凭源文件中某一字段缺失进行判断。

Request 不会预先分配应用的物理内存,也不必然独占 CPU 核心。CPU 请求参与调度及争用时的相对份额。没有 CPU limit 的容器可以利用超过请求的空闲 CPU,但节点容量、祖先约束和竞争负载仍然构成边界。省略限制可能是有意选择,应配套明确容量和争用策略,而不是简单认定只配一边必然错误。

Linux 上 CPU limit 通常通过带宽节流执行,耗尽配额本身不会直接杀死进程。但等待可能增加延迟、触发应用超时或影响探针。整机 CPU 平均值低,也不能排除某个上限很紧的容器正在频繁节流。要比较对应时间窗口的需求、配额和等待,而不是拿整机平均值替代容器约束。

内存具有不同失败行为

内存限制不是 CPU 那种周期额度。内核可以回收记账内存,并在无法满足约束时触发控制组 OOM;它是响应实际压力的机制,不是看板曲线越线就立刻杀死进程。节点压力与应用自身失败又是另外的机制。应区分容器 OOM、节点驱逐和普通进程终止,避免给所有重启使用同一种解释。

容器记账内存不只包含托管堆。原生分配、线程栈、文件相关内存以及内存型卷都可能参与。进程 RSS 和应用堆指标很有用,却都不等于控制组全部计费字节。应依据运行时与内核检查合适的记账视图,并考虑采样间隔可能漏掉的短峰值,不能只把堆参数与 limit 作一次简单大小比较。

退出码 137 是 shell 风格的 SIGKILL 表示,不是 OOM 的独立证明。应结合容器终止原因、控制器计数、节点事件和负载指标;操作者或其他机制也能发送 KILL。突然终止后的日志可能不完整,但仍可揭示泄漏、过大输入或工作负载变化,不能因为怀疑 OOM 就完全排除日志证据。

根据证据定容,而不是套比例

应覆盖正常流量、发布、批处理及恢复过程采集代表性数据。计算历史分位数需要持续监控;metrics-server 与 kubectl top 提供近期资源指标,不是内建的一周 p95 档案。余量要根据负载波动和失败代价选择,不能把统一百分比当成普遍适用的容量公式,短时测试也未必包含恢复峰值。

如果显式较小的 request 不变,单纯提高 limit 通常不会额外占用调度容量;提高 request 才会减少放置余量。分析其他 Pod Pending 时应区分这两种变更。还要考虑 HPA 利用率目标,因为改变 CPU request 会改变分母,即使真实使用量不变,伸缩建议也可能跟着改变,资源调整需要联合审阅。

在传统每容器 QoS 规则下,Guaranteed 要求所有相关容器同时满足 CPU 请求等于限制、内存请求等于限制。只让内存相等不足以获得该类别。类别也不是资源故障免疫证明,固定请求比例不能代替真实需求测量与故障测试。选择配置的目标是服务行为可靠,而不是追求一个看起来更强的标签。

坏掉的样子

OOM 循环可能来自余量不足、泄漏、不适当的堆配置或意外输入。节流可能来自过紧配额,但也应结合请求延迟和需求解释。任何单项观察都不自动意味着应该增加上限;增加可能把压力转移给其他工作负载,或掩盖真正的应用问题。先建立原因与后果,再决定调整配额还是修正程序。

同样,没有节流也不能证明 request 应降低。请求还影响争用时份额,而观察窗口可能没有覆盖原先要保障的需求。告警应采用负载特定的预警窗口;一个使用率阈值无法承诺在突然分配峰值前提前几天通知。重新评估时还应考虑默认值、配额和节点容量,避免只修改一个数字就期待整体风险消失。

快速验证

以下保留的只读命令本轮没有重新执行。应选择获准测试上下文,以及实际名为 prod 的目标命名空间;这个示例名称不代表可以读取未知生产集群。命令只提供初步快照,不是完整的逐容器用量比较,也没有创建受控超限条件来验证执行效果。

kubectl top pods -n prod --sort-by=memory | head
kubectl get pods -n prod -o custom-columns=NAME:.metadata.name,REQ:.spec.containers[*].resources.requests.memory,LIM:.spec.containers[*].resources.limits.memory --no-headers | head -n 15
kubectl get events -n prod --field-selector reason=OOMKilling --sort-by=.lastTimestamp | tail -n 5

Top 默认展示 Pod 合计,逐容器输出需要另行选择。自定义列列出多个容器值却没有名称,OOMKilling 事件也不保证存在或长期保留。事件为空不能成为没有 OOM 的反证。结论需要结合准入资源、终止原因、控制组计数与历史使用量,成功列出对象不等于限制已经经过运行验证。

来源