服务质量(QoS)类是Kubernetes的概念,它确定Pod的调度和驱逐优先级。 Kubernetes调度程序使用QoS类来做出有关将Pod调度到节点上的决策。
Kubelet使用它来管理驱逐pod的顺序,以及使用高级CPU管理策略允许更复杂的pod调度决策。
QoS类由Kubernetes本身分配给Pod。但是,DevOps可以通过处理Pod内各个容器的资源请求和限制来控制分配给容器的QoS类。
在kubernetes 中存在三种QoS类:
- Guaranteed
- Burstable
- BestEffort
让我们看一下不同的QoS类,看看它们如何与Kubernetes Scheduler和Kubelet一起工作。
Guaranteed
如何分配Pod的QoS Guaranteed 等级?
要将Pod置于“Guaranteed QoS”类中,该Pod中的每个容器都必须具有CPU和内存限制。 Kubernetes将自动为该Pod内的容器分配CPU和内存请求值(等于CPU和内存限制值),并将其分配为Guaranteed QoS类。
对于CPU请求和限制以及内存请求和限制,具有明确且相等值的Pod也放置在Guaranteed QoS类中。
Kubernetes Scheduler如何处理Guaranteed Pods?
Kubernetes调度程序仅将 Guaranteed Pod分配给具有足够资源来满足其CPU和内存请求的节点。调度程序通过确保所有容器(正在运行和新调度的)的内存和CPU请求的总和低于节点的总容量,来实现此目的。
可以为 Guaranteed Pod分配专用的CPU内核吗?
Kubernetes的默认CPU管理策略为“无”。根据此策略,Guaranteed Pod在节点上的共享CPU池中运行。共享CPU池包含节点上的所有CPU资源,减去使用--kube-reserved或--system-reserved的Kubelet保留的CPU资源。
但是,可以通过静态CPU管理策略为 Guaranteed Pod分配CPU内核的独占使用权。要在此策略下被授予CPU内核的独占使用权,Guaranteed Pod还必须具有整数形式的CPU请求值。具有保证CPU请求值的 Guaranteed Pod仍将在静态CPU管理策略下在共享CPU池中运行。
是什么阻止了Guaranteed Pod调度到节点上?
无法将Guaranteed Pod调度到Kubelet报告DiskPressure节点状况的节点上。 DiskPressure是节点条件,当节点的根文件系统或映像文件系统上的可用磁盘空间和inode达到逐出阈值时,就会触发该条件。当节点报告DiskPressure状况时,调度程序将停止将任何新的 Guaranteed Pod调度到该节点上。
Burstable
如何为Pod分配burstable的QoS类?
如果该容器中的至少一个容器具有内存或CPU请求,则为该容器分配Burstable QoS类。
Kubernetes Scheduler如何处理 burstable Pods?
Kubernetes调度程序将无法确保将Burstable Pod放置在具有足够资源的节点上。
可以为Burstable Pod分配专用的CPU内核吗?
在默认的“无” CPU管理策略下,Burstable Pod与BestEffort和Guaranteed Pod一起在节点的共享资源池中运行。无法将专用CPU内核分配给Burstable Pod。
是什么阻止了Burstable Pod被调度到节点上?
与Guaranteed Pod一样,Burstable Pod也无法调度到DiskPressure下的节点上。 Kubernetes调度程序不会将任何新的Burstable Pod调度到条件为DiskPressure的节点上。
BestEffort
如何为Pod分配BestEffort QoS类?
如果Pod的容器中没有一个容器具有CPU或内存请求和限制,则会为其分配BestEffort QoS类。
Kubernetes Scheduler如何处理BestEffort Pod?
不能保证BestEffort Pods调度到具有足够资源的节点上。但是,它们能够使用节点上任何数量的可用CPU和内存资源。有时这可能导致与其他Pod争用资源,BestEffort Pod在其中浪费资源,而没有为其他Pod留出足够的资源余量以消耗资源限制内的资源。
可以为BestEffort Pod分配专用的CPU内核吗?
与具有Burstable QoS类的Pod一样,BestEffort Pod也运行在节点上的共享资源池中,并且不能被授予独占的CPU资源使用率。
是什么阻止BestEffort Pod调度到节点上?
无法将BestEffort Pod安排在DiskPressure和MemoryPressure下的节点上。如果节点的可用内存级别低于预定义的阈值,那么它将报告MemoryPressure条件。 Kubernetes Scheduler会停止将任何新的BestEffort Pod调度到该节点上。
接下来,我们将研究Kubelet如何处理所有三个QoS类的Pod的驱逐。我们还将看到当节点内存不足时,pod的QOS类如何影响它所发生的事情。
可压缩资源与不可压缩资源
Kubernetes根据资源能否伸缩进行分类,划分为可压缩资源和不可以压缩资源2种。CPU资源是目前支持的一种可压缩资源,而内存资源和磁盘资源为目前所支持的不可压缩资源。
QoS优先级
3种QoS优先级从有低到高(从左向右):
Best-Effort pods -> Burstable pods -> Guaranteed pods
可压缩资源:CPU
在压缩资源部分已经提到CPU属于可压缩资源,当pod使用超过设置的limits值,pod中进程使用cpu会被限制,但不会被kill。
不可压缩资源:内存
Kubelet 如何驱逐 Guaranteed, Burstable 和 BestEffort Pods?
当节点开始耗尽计算资源时,由Kubelet启动Pod驱逐。这些驱逐旨在回收资源,以避免发生系统内存不足(OOM)事件。
Pod的QoS类确实会影响Kubelet选择将其驱逐的顺序。 Kubelet首先驱逐超出请求的资源消耗量的BestEffort和Burstable Pod。驱逐的顺序取决于分配给每个Pod的优先级以及超出请求的资源消耗量。
最后驱逐超出请求资源消耗量的Guaranteed对象和Burstable对象。
资源使用量低于请求数量的Guaranteed 和 Burstable Pod都不会因为另一个Pod的资源使用而被逐出。
但是当系统daemon (例如kubelet
,docker
, 和journald
)消耗资源超过了system-reserved
或是 kube-reserved
预留资源,资源使用量低于请求数量的Guaranteed 和 Burstable Pod也会被驱逐,驱逐顺序按照优先级从低到高。
响应DiskPressure节点条件时,Kubelet首先驱逐BestEffort Pod,然后驱逐Burstable Pod。仅当没有BestEffort或Burstable Pod时,才驱逐Guaranteed Pod。
节点OOM时如何处理Guaranteed, Burstable 和 BestEffort Pods?
如果节点在Kubelet可以回收之前耗尽了内存,即节点发生了oom,则oom_killer会根据其oom_score终止容器。 oom_score由oom_killer为每个容器计算,并基于该容器在节点上使用的内存与其请求的内存相比的百分比加上oom_score_adj分数。
每个容器的 oom_score_adj 由其所属的Pod的QoS类控制。对于“Guaranteed” Pod中的容器,oom_score_adj为“ -998”,对于“BestEffort” Pod中的容器,其为“ 1000”,Burstable Pod中的容器,值为“ min(max(2,1000-(1000 * memoryRequestBytes)/ machineMemoryCapacityBytes),999” )”。
oom_killer首先终止QoS等级最低,且超过请求资源最多的容器。这意味着与burstable或BestEffort QoS类别的容器相比,具有更好QoS类别(如“Guaranteed”)的容器被杀死的可能性更低。
但是,并非所有情况都如此。由于oom_killer还考虑了内存使用量与请求的关系,因此,由于内存使用量过多,具有更好QoS类的容器可能具有更高的oom_score,因此可能首先被杀死。
资源请求和限制的最佳做法
这有一些重要的含义:
- 为Deployment设置匹配的请求/限制,将为您提供guaranteed 状态,并防止驱逐。
- 由于始终将DaemonSet调度为重新部署到同一节点,因此通常建议为它们提供Guaranteed的状态,以防止在Pod连续地重新调度到同一节点时在该节点上发生抖动。
总结
QOS类确定Kubernetes调度程序调度Pod的顺序以及Kubelet驱逐Pod的顺序。 DevOps可以通过将资源限制和请求分配给属于该Pod的各个容器来影响Pod的QOS类。
Pod的QOS类在某些情况下会影响单个节点的资源利用率。由于资源请求和限制主要是基于猜测来设置的,因此在某些情况下,“Guaranteed”和“Burstable”的QOS Pod的资源占用要远远大于所需的资源占用。这可能导致Pod无法有效利用请求的资源的情况。
可以分析历史资源的请求,使用情况和利用率,以向Kubernetes管理员和IT经理提供可行的优化建议。然后,IT经理可以调整基础架构的大小,并优化各个Pod的资源占用,从而节省大量成本。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。