服务质量(QoS)类是Kubernetes的概念,它肯定Pod的调度和驱逐优先级。 Kubernetes调度程序使用QoS类来作出有关将Pod调度到节点上的决策。node
Kubelet使用它来管理驱逐pod的顺序,以及使用高级CPU管理策略容许更复杂的pod调度决策。docker
QoS类由Kubernetes自己分配给Pod。可是,DevOps能够经过处理Pod内各个容器的资源请求和限制来控制分配给容器的QoS类。架构
在kubernetes 中存在三种QoS类:优化
让咱们看一下不一样的QoS类,看看它们如何与Kubernetes Scheduler和Kubelet一块儿工做。spa
要将Pod置于“Guaranteed QoS”类中,该Pod中的每一个容器都必须具备CPU和内存限制。 Kubernetes将自动为该Pod内的容器分配CPU和内存请求值(等于CPU和内存限制值),并将其分配为Guaranteed QoS类。3d
对于CPU请求和限制以及内存请求和限制,具备明确且相等值的Pod也放置在Guaranteed QoS类中。code
Kubernetes调度程序仅将 Guaranteed Pod分配给具备足够资源来知足其CPU和内存请求的节点。调度程序经过确保全部容器(正在运行和新调度的)的内存和CPU请求的总和低于节点的总容量,来实现此目的。对象
Kubernetes的默认CPU管理策略为“无”。根据此策略,Guaranteed Pod在节点上的共享CPU池中运行。共享CPU池包含节点上的全部CPU资源,减去使用--kube-reserved或--system-reserved的Kubelet保留的CPU资源。blog
可是,能够经过静态CPU管理策略为 Guaranteed Pod分配CPU内核的独占使用权。要在此策略下被授予CPU内核的独占使用权,Guaranteed Pod还必须具备整数形式的CPU请求值。具备保证CPU请求值的 Guaranteed Pod仍将在静态CPU管理策略下在共享CPU池中运行。进程
没法将Guaranteed Pod调度到Kubelet报告DiskPressure节点情况的节点上。 DiskPressure是节点条件,当节点的根文件系统或映像文件系统上的可用磁盘空间和inode达到逐出阈值时,就会触发该条件。当节点报告DiskPressure情况时,调度程序将中止将任何新的 Guaranteed Pod调度到该节点上。
若是该容器中的至少一个容器具备内存或CPU请求,则为该容器分配Burstable QoS类。
Kubernetes调度程序将没法确保将Burstable Pod放置在具备足够资源的节点上。
在默认的“无” CPU管理策略下,Burstable Pod与BestEffort和Guaranteed Pod一块儿在节点的共享资源池中运行。没法将专用CPU内核分配给Burstable Pod。
与Guaranteed Pod同样,Burstable Pod也没法调度到DiskPressure下的节点上。 Kubernetes调度程序不会将任何新的Burstable Pod调度到条件为DiskPressure的节点上。
若是Pod的容器中没有一个容器具备CPU或内存请求和限制,则会为其分配BestEffort QoS类。
不能保证BestEffort Pods调度到具备足够资源的节点上。可是,它们可以使用节点上任何数量的可用CPU和内存资源。有时这可能致使与其余Pod争用资源,BestEffort Pod在其中浪费资源,而没有为其余Pod留出足够的资源余量以消耗资源限制内的资源。
与具备Burstable QoS类的Pod同样,BestEffort Pod也运行在节点上的共享资源池中,而且不能被授予独占的CPU资源使用率。
没法将BestEffort Pod安排在DiskPressure和MemoryPressure下的节点上。若是节点的可用内存级别低于预约义的阈值,那么它将报告MemoryPressure条件。 Kubernetes Scheduler会中止将任何新的BestEffort Pod调度到该节点上。
接下来,咱们将研究Kubelet如何处理全部三个QoS类的Pod的驱逐。咱们还将看到当节点内存不足时,pod的QOS类如何影响它所发生的事情。
Kubernetes根据资源可否伸缩进行分类,划分为可压缩资源和不能够压缩资源2种。CPU资源是目前支持的一种可压缩资源,而内存资源和磁盘资源为目前所支持的不可压缩资源。
3种QoS优先级从有低到高(从左向右):
Best-Effort pods -> Burstable pods -> Guaranteed pods
在压缩资源部分已经提到CPU属于可压缩资源,当pod使用超过设置的limits值,pod中进程使用cpu会被限制,但不会被kill。
当节点开始耗尽计算资源时,由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。
若是节点在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,所以可能首先被杀死。
这有一些重要的含义:
QOS类肯定Kubernetes调度程序调度Pod的顺序以及Kubelet驱逐Pod的顺序。 DevOps能够经过将资源限制和请求分配给属于该Pod的各个容器来影响Pod的QOS类。
Pod的QOS类在某些状况下会影响单个节点的资源利用率。因为资源请求和限制主要是基于猜想来设置的,所以在某些状况下,“Guaranteed”和“Burstable”的QOS Pod的资源占用要远远大于所需的资源占用。这可能致使Pod没法有效利用请求的资源的状况。
能够分析历史资源的请求,使用状况和利用率,以向Kubernetes管理员和IT经理提供可行的优化建议。而后,IT经理能够调整基础架构的大小,并优化各个Pod的资源占用,从而节省大量成本。