服務質量(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的資源佔用,從而節省大量成本。