CPU和内存是节点重要的资源,分配不当时可能导致容器频繁重启或者被驱赶,甚至导致节点宕机。特别是内存这类不可压缩的资源。
Kubernetes 将运行的 Pod 分为不同的 QoS 类,QoS 类由 Pod 中容器的资源请求(request)和限制(limit)决定。当 Node 资源不足时,Kubernetes 会根据 QoS 类驱逐可驱逐的 Pod。此外,Pod 或因超过限制(limit)被 kubelet 终止,或因没有限制而导致节点 OOM。
Kubernetes QoS 类有Guaranteed、Burstable、BestEffort。
Guaranteed
Guaranteed Pod 具有最严格的资源限制,且最不可能被驱逐。在这些 Pod 未超过其资源的limit,或没有可从 Node 抢占的低优先级 Pod 之前,它们不会被kill。即它们只能使用其指定的资源限制。Pod 被赋予 Guaranteed QoS 类的几个判断:
- Pod 中的每个容器必须有 CPU 和内存的 request 和 limit
- 对于 Pod 中的每个容器,CPU 和内存的 limit 必须分别等于 CPU 和内存的 request
Burstable
Burstable Pod 具有基于请求的资源下限保证,但不需要资源限制。如果未指定资源limit,则默认为节点容量。这允许 Burstable Pod 在资源可用时灵活地增加其资源。在由于节点资源压力导致 Pod 被驱逐的情况下,Burstable
Pod 只会在所有 BestEffort Pod 被驱逐后才会被驱逐。Burstable Pod 可以包括没有资源 limit 或 request 的容器,因此可以尝试使用任意数量的节点资源。
- Pod 不满足 QoS 类 Guaranteed 的判定依据
- Pod 中至少一个容器有CPU或内存的 request 或 limit
BestEffort
BestEffort Pod 可以使用未分配给其他 QoS 类 Pod 的节点资源。在节点遇到资源压力时,kubelet 将优先驱逐 BestEffort Pod。
- Pod 中所有的容器都没有 CPU 和内存的 request 和 limit
场景一
节点内存超过了预留的上限,导致节点 OOMkill。
解决方法:
- 升级节点的规格
- 迁移 Pod 至其他资源充足的节点
场景二
Pod 的内存 limit 设置过低,导致容器在使用内存超过限制时触发了OOMkill。此时,kubelet 会重启容器,但由于内存限制仍未改变,容器将再次超过限制并被终止。这种情况会导致容器反复重启,影响应用程序的稳定性。
解决方法:
- 扩大容器的内存 limit 设置