k8s的資源管理

QoS

k8s中對容器的資源分配有三種策略:node

  • Guaranteed 。該策略下,pod.spec.containers[].resources中會存在cpu或memory的request和limit。顧名思義是該容器對資源的最低要求和最高使用量限制。若是咱們配置了limit,沒有配置request,默認會以limit的值來定義request。具體的配置能夠參考之前的這篇筆記
  • BestEffort。當pod的描述文件中沒有resource.limit、resource.request相關的配置時,意味着這個容器想跑多少資源就跑多少資源,其資源使用上限實際上即所在node的capacity。
  • Burstable。當resource.limit和resource.request以上述兩種方式之外的形式配置的時候,就會採用本模式。

QoS目前只用cpu和memory來描述,其中cpu可壓縮資源,當一個容器的cpu使用率超過limit時會被進行流控,而當內存超過limit時則會被oom_kill。這裏kubelet是經過本身計算容器的oom_score,確認相應的linux進程的oom_adj,oom_adj最高的進程最早被oom_kill。
Guaranteed模式的容器oom_score最小:-998,對應的oom_adj爲0或1,BestEffort模式則是1000,Burstable模式的oom_score隨着其內存使用情況浮動,但會處在2-1000之間。linux

所以咱們能夠看出,當某個node內存被嚴重消耗時,BestEffort策略的pod會最早被kubelet殺死,其次Burstable(該策略的pods若有多個,也是按照內存使用率來由高到低地終止),再其次Guaranteed。segmentfault

kubelet的eviction機制

徹底依賴於oom_kill並非一個很好的方案,一來對於cpu要求高的容器沒有做用,二來單純將pod殺死,並不能根本上解決困局,好比pod佔用node絕大部份內存,加入pod被kill後再次調度到這個node上,oom的狀況還會復現。因此kubelet增長了一套驅逐機制。
eviction機制適用於:
memory.available 、nodefs.available 、nodefs.inodesFree 、imagefs.available 、imagefs.inodesFree
分別對應於node目前可用內存、node上用於kubelet運行日誌、容器掛載磁盤所使用的的文件系統的餘量和inode餘量、node上用於存放容器鏡像和讀寫層的文件系統的餘量、inode餘量。spa

eviction中要設置觸發驅逐的閾值Eviction Thresholds,這個閾值的配置能夠是一個定值或一個百分比。如:
memory.available<10%
memory.available<1Gi日誌

Soft Eviction Thresholds

軟驅逐機制表示,當node的內存/磁盤空間達到必定的閾值後,我要觀察一段時間,若是改善到低於閾值就不進行驅逐,若這段時間一直高於閾值就進行驅逐。
這裏閾值經過參數--eviction-soft配置,樣例如上;觀察時間經過參數--eviction-soft-grace-period進行配置,如1m30s
另外還有一個參數eviction-max-pod-grace-period,該參數會影響到要被驅逐的pod的termination time,即終止該pod的容器要花費的時間。code

Hard Eviction Thresholds

強制驅逐機制則簡單的多,一旦達到閾值,馬上把pod從本地kill,驅逐eviction-hard參數配置,樣例亦如上。blog

pod eviction

當資源使用狀況觸發了驅逐條件時,kubelet會啓動一個任務去輪流中止運行中的pod,直到資源使用情況恢復到閾值如下。以硬驅逐爲例,總體流程是:排序

  • 每隔一段時間從cadvisor中獲取資源使用狀況,發現觸發了閾值;
  • 從運行中的pod裏找到QoS策略最開放的一個,好比策略爲bestEffort的一個pod(即使這個pod沒有吃多少內存,大部份內存是另外一個策略爲burstable,但內存使用率也很高的pod),kubelet中止該pod對應的全部容器,而後將pod狀態更新爲Failed。若是該pod長時間沒有被成功kill掉,kubelet會再找一個pod進行驅逐。
  • 檢查內存用量是否恢復到閾值如下,若是沒有,則重複第二步(這裏就要幹掉那個罪魁禍首了)。一直到內存使用狀況恢復到閾值如下爲止。

有幾個要注意的點是:進程

  • kubelet挑選pod進行驅逐的策略,就是按照QoS的策略開放度排序,而同一個QoS的多個pod中,kubelet會優先驅逐使用觸發指標資源最多的一個。
  • 磁盤的使用不像memory有經過request和limit進行配置,磁盤用量能夠認爲是一種QoS策略爲BestEffort的資源。當觸發磁盤資源不足時,kubelet會作一些額外的工做,好比清理已經dead的pod的容器日誌,清理沒有被使用的容器鏡像,固然kubelet也會挑磁盤使用量(包括掛載本地volume空間+容器log大小,如果imagefs指標超額,此處還要加上容器運行時讀寫層的文件大小)最大的一個pod進行驅逐。

node condition

clipboard.png
如上圖,當軟驅逐或者硬驅逐觸發時,kubelet會嘗試幹掉一個pod,而且會將自身的狀態從驅逐的指標信息中映射過來,好比內存使用超標觸發驅逐,node的condtion就會變成memoryPressure,這個condition伴隨的kubelet定時的心跳報文上傳到master,記錄在etcd中。在調度器進行調度時,會以這些condition做爲調度條件的參考。好比,處於diskPressure的node,調度器就不會再將任何pod調度上去。不然一旦磁盤空間用滿,node上的容器可能會嚴重崩潰。ip

但若是node的內存在閾值上下波動,condition被反覆更新爲pressure或正常,那麼pod被誤調度到node上也會很耽誤事,因此用eviction-pressure-transition-period參數指定觸發eviction後condition更新一次後要保留改狀態的最小時長。在這個時長範圍內即使資源使用降低到閾值如下,condition也不會恢復。

其餘

Minimum eviction reclaim 咱們擔憂node可能驅逐了一個小pod後,指標就只是稍低於閾值,那麼一旦其餘pod的指標稍一上來,該node就又要進行eviction。因此用這個參數:
--eviction-minimum-reclaim(值如"memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi")進行限定,一旦發生了eviction,必需要保證node的某指標用量低於(該指標閾值-本參數指定的該指標值)才認爲node恢復正常,不然還要接着驅逐pod。
簡單的說,該參數表示的是node進行驅逐工做後要達到的效果是低於閾值多少

相關文章
相關標籤/搜索