Kubernetes的服務質量保證(QoS)
Kubernetes需要整體統籌平台資源使用情況、公平合理的將資源分配給相關pod容器使用,並且要保證容器生命周期內有足夠的資源來保證其運行。 與此同時,由於資源發放的獨占性,即資源已經分配給了某容器,同樣的資源不會在分配給其他容器,對於資源利用率相對較低的容器來說,占用資源卻沒有實際使用(比如CPU、內存)造成了嚴重的資源浪費,Kubernetes需從優先級與公平性等角度綜合考慮來提高資源的利用率。為了在資源被有效調度和分配的同時提高資源利用率,Kubernetes針對不同服務質量的預期,通過QoS(Quality of Service)來對pod進行服務質量管理,提供了個采用requests和limits兩種類型對資源進行分配和使用限制。對於一個pod來說,服務質量體現在兩個為2個具體的指標: CPU與內存。實際過程中,當NODE節點上內存資源緊張時,kubernetes會根據預先設置的不同QoS類別進行相應處理。
設置資源限制的原因
如果未做過節點 nodeSelector,親和性(node affinity)或pod親和、反親和性(pod affinity/anti-affinity)等Pod高級調度策略設置,我們沒有辦法指定服務部署到指定機器上,如此可能會造成cpu或內存等密集型的pod全部都被分配到相同的Node上,造成資源競爭。另一方面,如果未對資源進行限制,一些關鍵的服務可能會因為資源競爭因OOM(Out of Memory)等原因被kill掉,或者被限制CPU使用。
資源需求(Requests)和限制( Limits)
對於每一個資源,container可以指定具體的資源需求(requests)和限制(limits),requests申請范圍是0到node節點的最大配置,而limits申請范圍是requests到無限,即0 <= requests <=Node Allocatable, requests <= limits <= Infinity。
對於CPU,如果pod中服務使用CPU超過設置的limits,pod不會被kill掉但會被限制。如果沒有設置limits,pod可以使用全部空閑的cpu資源。
對於內存,當一個pod使用內存超過了設置的limits,pod中container的進程會被kernel因OOM kill掉。當container因為OOM被kill掉時,系統傾向於在其原所在的機器上重啟該container或本機或其他重新創建一個pod。
QoS分類
Kubelet提供QoS服務質量管理,支持系統級別的OOM控制。在Kubernetes中,pod的QoS級別包括:Guaranteed, Burstable與 Best-Effort。下面對各級別分別進行相應說明:
Guaranteed:pod中的所有容器都必須對cpu和memory同時設置limits,如果有一個容器要設置requests,那么所有容器都要設置,並設置參數同limits一致,那么這個pod的QoS就是Guaranteed級別。
注:如果一個容器只指明limit而未設定request,則request的值等於limit值。
Guaranteed舉例1:容器只指明了limits而未指明requests)。
containers:
name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
name: bar
resources:
limits:
cpu: 100m
memory: 100Mi
Guaranteed舉例2:requests與limit均指定且值相等。
containers:
name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
requests:
cpu: 10m
memory: 1Gi
name: bar
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
Burstable: pod中只要有一個容器的requests和limits的設置不相同,該pod的QoS即為Burstable(即可能會停服)。舉例如下:
Container bar沒有指定resources
containers:
name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
requests:
cpu: 10m
memory: 1Gi
name: bar
Burstable舉例2:pod中只要有一個容器沒有對cpu或者memory中的request和limits都沒有明確指定。
containers:
name: foo
resources:
limits:
memory: 1Gi
name: bar
resources:
limits:
cpu: 100m
Burstable舉例3:Container foo沒有設置limits,而bar requests與 limits均未設置。
containers:
name: foo
resources:
requests:
cpu: 10m
memory: 1Gi
name: bar
Best-Effort:如果對於全部的resources來說requests與limits均未設置,該pod的QoS即為Best-Effort。舉例如下:
containers:
name: foo
resources:
name: bar
resources:
可壓縮資源與不可壓縮資源
Kubernetes根據資源能否伸縮進行分類,划分為可壓縮資源和不可以壓縮資源2種。
CPU資源是目前支持的一種可壓縮資源,而內存資源和磁盤資源為目前所支持的不可壓縮資源。
QoS優先級
3種QoS優先級從有低到高(從左向右):
Best-Effort pods -> Burstable pods -> Guaranteed pods
靜態pod
在Kubernetes中有一種DaemonSet類型pod,此類pod可以常駐在某個Node上運行,由該Node上kubelet服務直接管理而無需api server介入。靜態pod也無需關聯任何RC,完全由kubelet服務來監控,當kubelet發現靜態pod停止時,kubelet會重新啟動靜態pod。
資源回收策略
當kubernetes集群中某個節點上可用資源比較小時,kubernetes提供了資源回收策略保證被調度到該節點pod服務正常運行。當節點上的內存或者CPU資源耗盡時,可能會造成該節點上正在運行的pod服務不穩定。Kubernetes通過kubelet來進行回收策略控制,保證節點上pod在節點資源比較小時可以穩定運行。
可壓縮資源:CPU
在壓縮資源部分已經提到CPU屬於可壓縮資源,當pod使用超過其設置的limits值時,pod中的進程會被限制使用cpu,但不會被kill。
不可壓縮資源:內存
Kubernetes通過cgroup給pod設置QoS級別,當資源不足時先kill優先級低的pod,在實際使用過程中,通過OOM分數值來實現,OOM分數值從0-1000。
OOM分數值根據OOM_ADJ參數計算得出,對於Guaranteed級別的pod,OOM_ADJ參數設置成了-998,對於BestEffort級別的pod,OOM_ADJ參數設置成了1000,對於Burstable級別的POD,OOM_ADJ參數取值從2到999。對於kubernetes保留資源,比如kubelet,docker,OOM_ADJ參數設置成了-999,表示不會被OOM kill掉。OOM_ADJ參數設置的越大,通過OOM_ADJ參數計算出來OOM分數越高,表明該pod優先級就越低,當出現資源競爭時會越早被kill掉,對於OOM_ADJ參數是-999的表示kubernetes永遠不會因為OOM而被kill掉。
QoS pods被kill掉的場景與順序
- Best-Effort 類型的pods:系統用完了全部內存時,該類型pods會最先被kill掉。
- Burstable類型pods:系統用完了全部內存,且沒有Best-Effort container可以被kill時,該類型pods會被kill掉。
- Guaranteed pods:系統用完了全部內存、且沒有Burstable與Best-Effort container可以被kill,該類型的pods會被kill掉。
注:如果pod進程因使用超過預先設定的limites而非Node資源緊張情況,系統傾向於在其原所在的機器上重啟該container或本機或其他重新創建一個pod, 即自動遷移服務。
使用建議
- 如果資源充足,可將QoS pods類型均設置為Guaranteed。用計算資源換業務性能和穩定性,減少排查問題時間和成本。
- 如果想更好的提高資源利用率,業務服務可以設置為Guaranteed,而其他服務根據重要程度可分別設置為Burstable或Best-Effort,例如filebeat。
已知問題
不支持swap,當前的QoS策略假設swap已被禁止。
參考資料
轉自http://dockone.io/article/2592並進行了修改
Resource Quality of Service in Kubernetes: https://github.com/kubernetes/ ... os.md
Introduction to Quality Of Service and Service Level Agreement: http://www.loriotpro.com/Produ ... N.htm
Kubelet pod level resource management: https://github.com/kubernetes/ ... nt.md
Kubelet - Eviction Policy: https://github.com/kubernetes/ ... on.md