4.8.4 Pod 的服务质量类比

前面曾提到过,Kubernetes 允许节点资源对 limits 的过载使用,这意味着节点无法同时满足其上的所有 Pod 对象以资源满载的方式运行。于是,在内存资源紧缺时,应该以何种次序先后终止哪些 Pod 对象?Kubernetes 无法自行对此作出决策,它需要借助于 Pod 对象的优先级完成判定。根据 Pod 对象的 requests 和 limits 属性,Kubernetes 将 Pod 对象归类到 BestEffort、Burstable 和 Guaranteed 三个服务质量(Quality of Service, QoS)类别下,具体说明如下。

  • Guaranteed:每个容器都为 CPU 资源设置了具有相同值的 requests 和 limits 属性,以及每个容器都为内存资源设置了具有相同值的 requests 和 limits 属性的 Pod 资源会自动归属于此类别,这类 Pod 资源具有最高优先级。
  • Burstable:至少有一个容器设置了 CPU 或内存资源的 requests 属性,但不满足 Guaranteed 类别要求的 Pod 资源将自动归属于此类别,它们具有中等优先级。
  • BestEffort:未为任何一个容器设置 requests 或 limits 属性的 Pod 资源将自动归属于此类别,它们的优先级为最低级别。

内存资源紧缺时,BestEffort 类别的容器将首当其冲地被终止,因为系统不为其提供任何级别的资源保证,但换来的好处是,它们能够在可用时做到尽可能多的占用资源。若已然不存在任何 BestEffort 类别的容器,则接下来是有着中等优先级的 Burstable 类别的 Pod 被终止。Guaranteed 类别的容器拥有最高优先级,它们不会被杀死,除非其内存资源需求超限,或者 OOM 时没有其他更低优先级的 Pod 资源存在。

每个运行状态容器都有其 OOM 得分,得分越高越会被优先杀死。OOM 得分主要根据两个纬度进行计算:由 Qos 类别继承而来的默认分值和容器的可用内存资源比例。同等类别的 Pod 资源的默认分值相同,下面的代码片段取自 pkg/kubelet/qos/policy.go 源码文件,它们定义的各种类别的 Pod 资源的 OOM 调节(Adjust)分值,即默认分值。其中,Guaranteed 类别的 Pod 资源的 Adjust 分值为 -998 分,而 BestEffort 分别时默认分值为 1000,Burstable 类别的 Pod 资源的 Adjust 分值则经由相应的算法计算得出:

const {
    PodinfraOOMAdj          int = -998
    KubeletOOMScoreAdj      int = -999
    DockerOOMScoreAdj       int = -999
    KubeProxyOOMScoreAdj    int = -999
    guaranteedOOMScoreAdj   int = -998
    besteffortOOMScoreAdj   int = 1000
}

因此,同等级别优先级的 Pod 资源在 OOM 时,与自身的 requests 属性相比,其内存占用比例最大的 Pod 对象将被首先杀死。例如,图 4-13 中的同属于 Burstable 类别的 Pod A 将先于 Pod B 被杀死,虽然其内存用量小,但与自身的 requests 值相比,它的占用比例 95% 要大于 Pod B 的 80%。

资源需求和资源限额及OOM
图 1.6.8.4 - 资源需求和资源限额及OOM

需要特别说明的是,OOM 是内存耗尽时的处理机制,它们与可压缩型资源 CPU 无关,因此 CPU 资源的需求无法得到保证时,Pod 仅仅是暂时获取不到相应的资源而已。

results matching ""

    No results matching ""