深究Kubernetes源碼-Kubelet-5 節(jié)點壓力驅(qū)逐Eviction流程分析
基于kubernetes1.26
1 功能和模塊
https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/
Node-Pressure Eviction是當(dāng)Kubelet所管理的Node節(jié)點出現(xiàn)資源壓力時,通過刪除Pod/Image回收部分資源的功能,資源包括節(jié)點CPU,Memory,F(xiàn)ilesystem Inode Free或Disk空間,當(dāng)Kubelet執(zhí)行Eviction時,將選中驅(qū)逐的Pod狀態(tài)設(shè)置為Failed,并刪除Pod。Kubelet Eviction不同于API Eviction,不受terminationGracePeriodSeconds和PDB影響,soft eviction會收到eviction-max-pod-grace-period配置項的影響。Pod被執(zhí)行Eviction從節(jié)點上驅(qū)逐之后,如果Pod上級控制器是StatefulSet/ReplicaSet等,則會重新創(chuàng)建Pod取代被驅(qū)逐Pod。
Eviction共處理6類觸發(fā)信號(eviction-signal):
memory.available:可用內(nèi)存capacity - workingset ,默認(rèn)100M
nodefs.available:可用磁盤空間, 默認(rèn)10%
nodefs.inodesFree:可用文件系統(tǒng)inode,默認(rèn)5%
imagefs.available:可用鏡像磁盤空間,默認(rèn)15%
imagefs.inodesFree:可用鏡像文件系統(tǒng)inode
pid.available:可用pid,rlimit.maxpid-rlimit.curproc
通過2個主要配置項控制:
--eviction-hard?or?--eviction-soft :驅(qū)逐出發(fā)閾值,格式為 <eviction-signal> <operator> <quantity>,例如 memory.available < 1G
--eviction-minimum-reclaim:執(zhí)行最少回收資源數(shù),避免頻繁觸發(fā)Eviction
其他相關(guān)配置項:
--housekeeping-interval:evction觸發(fā)間隔,默認(rèn)10s
--node-status-update-frequency:Kubelet更新Node狀態(tài)間隔
EvctionManager核心類圖分析,Manager主要包含ImageGC,ContainerGC和ThresholdNotifier三個模塊:

ImageCG,執(zhí)行鏡像回收
ContainerGC,執(zhí)行容器回收
ThresholdNotifitier,通過Memory CGroup反向觸發(fā)執(zhí)行Eviction,應(yīng)對突發(fā)Memory使用量高。
2 流程分析
在Kubelet啟動時以協(xié)程的方式運行,如果是Linux環(huán)境配置了KernelMemcgNotification,則額外啟動MemoryTheasholdNotifier監(jiān)聽Linux的反響觸發(fā)事件,如果沒有配置則啟動協(xié)程定期執(zhí)行synchronzie。

synchronize是evction的核心流程,首先判斷是否達(dá)到閾值觸發(fā)條件,如果達(dá)到則先執(zhí)行Node級別的資源回收reclaimNodeLevelResources,Node級別資源回收仍不滿足,則繼續(xù)執(zhí)行Pod驅(qū)逐evictPod。

reclaimNodeLevelResources,調(diào)用注冊的nodeReclaimFuncs,只能處理DiskPressure的情況,執(zhí)行的是磁盤空間和inode的回收,并不能回收Memory。分為是否支持ImageFs:
支持ImageFs,若觸發(fā)nodefs閾值,回收死亡的Pod和容器,若觸發(fā)imagefs閾值,回收未使用的鏡像
不支持imageFs,若觸發(fā)nodefs閾值,首先回收死亡的Pod和容器,然后刪除未使用的鏡像
evictPod,根據(jù)Pod的eviction排名,調(diào)用killPodFunc,evictPod核心在于對Pod進(jìn)行rank排序,rank函數(shù)也是通過調(diào)用buildSignalToRankFunc進(jìn)行注冊,主要是根據(jù)Pod優(yōu)先級以及資源占用情況進(jìn)行排序。
Pod回收排序參數(shù)如下:
Pod資源使用是否超過了Request值
Pod的Priority
Pod 相對于請求的資源使用情況
因此,kubelet 按以下順序排列和驅(qū)逐 Pod:
首先考慮資源使用量超過其請求的?BestEffort?或?Burstable?Pod。 這些 Pod 會根據(jù)它們的優(yōu)先級以及它們的資源使用級別超過其請求的程度被逐出。
資源使用量少于請求量的?Guaranteed?Pod 和?Burstable?Pod 根據(jù)其優(yōu)先級被最后驅(qū)逐。