您好,登錄后才能下訂單哦!
這篇文章主要講解了“Kubernetes Eviction Manager工作機(jī)制是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Kubernetes Eviction Manager工作機(jī)制是什么”吧!
首先,我們來談一下kubelet通過OOM Killer來回收資源的缺點:
System OOM events本來就是對資源敏感的,它會stall這個Node直到完成了OOM Killing Process。
當(dāng)OOM Killer干掉某些containers之后,kubernetes Scheduler可能很快又會調(diào)度一個新的Pod到該Node上或者container 直接在node上restart,馬上又會觸發(fā)該Node上的OOM Killer啟動OOM Killing Process,事情可能會沒完沒了的進(jìn)行,這可不妙啊。
我們再來看看Kubelet Eviction有何不同:
Kubelet通過pro-actively監(jiān)控并阻止Node上資源的耗盡,一旦觸發(fā)Eviction Signals,就會直接Fail一個或者多個Pod以回收資源,而不是通過Linux OOM Killer這樣本身耗資源的組件進(jìn)行回收。
這樣的Eviction Signals的可配置的,可以做到Pro-actively。
另外,被Evicted Pods會在其他Node上重新調(diào)度,而不會再次觸發(fā)本Node上的再次Eviction。
下面,我們具體來研究一下Kubelet Eviction Policy的工作機(jī)制。
kubelet預(yù)先監(jiān)控本節(jié)點的資源使用,并且阻止資源被耗盡,這樣保證node的穩(wěn)定性。
kubelet會預(yù)先Fail N(>= 1)個Pod以回收出現(xiàn)緊缺的資源。
kubelet會Fail一個Node時,會將Pod內(nèi)所有Containners都kill掉,并把PodPhase設(shè)為Failed。
kubelet通過事先人為設(shè)定Eviction Thresholds來觸發(fā)Eviction動作以回收資源。
支持如下Eviction Signals:
Eviction Signal | Description |
---|---|
memory.available | memory.available := node.status.capacity[memory] - node.stats.memory.workingSet |
nodefs.available | nodefs.available := node.stats.fs.available |
nodefs.inodesFree | nodefs.inodesFree := node.stats.fs.inodesFree |
imagefs.available | imagefs.available := node.stats.runtime.imagefs.available |
imagefs.inodesFree | imagefs.inodesFree := node.stats.runtime.imagefs.inodesFree |
kubelet目前支持一下兩種filesystem,其中imagefs為可選的。Kubelet通過cAdvisor來自動發(fā)現(xiàn)這些filesystem。
nodefs - Kubelet用來存儲volume,logs等數(shù)據(jù)。
imagefs - 容器運(yùn)行時(dockerd/rkt等)用來存放鏡像和容器的Writable Layer。
前面也提到,kubelet通過事先人為設(shè)定Eviction Thresholds來觸發(fā)Eviction動作以回收資源。
Eviction Thresholds的形式為:<eviction-signal><operator><quantity>
quantity
支持絕對值和相對百分比兩種形式,比如:
memory.available<10%
memory.available<1Gi
Soft Eviction Thresholds
是什么意思? 它指的是,當(dāng)Eviction Signal中值達(dá)到Soft Eviction Thresholds
配置的值時,并不會馬上觸發(fā)Kubelet去Evict Pods,而是會等待一個用戶配置的grace period之后,再觸發(fā)。相關(guān)的配置有三個,如下:
eviction-soft
- (e.g. memory.available<1.5Gi) 觸發(fā)Soft Eviction的Evication Signal閾值。
eviction-soft-grace-period
- (e.g. memory.available=1m30s) 當(dāng)Eviction Signal的值達(dá)到配置eviction-soft
值后,需要等待grace period,注意這期間,每10s會重新獲取監(jiān)控數(shù)據(jù)并維護(hù)Threshold的值。如果grace period最后一次監(jiān)控數(shù)據(jù)仍然觸發(fā)了閾值,才會再觸發(fā)Evict Pods。這個參數(shù)就是配置這個grace period的。
eviction-max-pod-grace-period
- (e.g. memory.available=30s) 這個是配置Evict Pods時,Pod Termination的Max Grace Period。如果待Evict的Pod指定了pod.Spec.TerminationGracePeriodSeconds
,則取min(eviction-max-pod-grace-period, pod.Spec.TerminationGracePeriodSeconds)
作為Pod Termination真正的Grace Period。
因此,從kubelet監(jiān)控到的Eviction Signal達(dá)到指定的Soft Eviction Thresholds
開始,到Pod真正被Kill,總共所需要的時間為: sum(eviction-soft-grace-period + min(eviction-max-pod-grace-period, pod.Spec.TerminationGracePeriodSeconds))
理解了Soft Eviction Thresholds
,那么Hard Eviction Thresholds
就很簡單了,它是指:當(dāng)Eviction Signal中值達(dá)到Hard Eviction Thresholds
配置的值時,會立刻觸發(fā)Kubelet去Evict Pods,并且也不會有Pod Termination Grace Period,而是立刻kill Pods,即使待Evict的Pod指定了pod.Spec.TerminationGracePeriodSeconds
。
總之,Hard Eviction Thresholds
就是來硬的,一旦觸發(fā),kubelet立刻馬上kill相關(guān)的pods。
因此,kubelet關(guān)于Hard Eviction Thresholds
的配置也只有一個:
eviction-hard
- (e.g. memory.available<1Gi) 這個值,要設(shè)置的比eviction-soft
更低才有意義。
kubelet會通過監(jiān)控Eviction Signal的值,當(dāng)達(dá)到配置的閾值時,就會觸發(fā)Evict Pods。 kubelet對應(yīng)的監(jiān)控周期,就通過cAdvisor的housekeeping-interval
配置的,默認(rèn)10s。
當(dāng)Hard Eviction Thresholds
或Soft Eviction Thresholds
被觸及后,Kubelet會將對應(yīng)的Eviction Signals映射到對應(yīng)的Node Conditions,其映射關(guān)系如下:
Node Condition | Eviction Signal | Description |
---|---|---|
MemoryPressure | memory.available | Available memory on the node has satisfied an eviction threshold |
DiskPressure | nodefs.available, nodefs.inodesFree, imagefs.available, or imagefs.inodesFree | Available disk space and inodes on either the node's root filesystem or image filesystem has satisfied an eviction threshold |
kubelet映射了Node Condition之后,會繼續(xù)按照--node-status-update-frequency
(default 10s)配置的時間間隔,周期性的與kube-apiserver進(jìn)行node status updates。
想象一下,如果一個Node上監(jiān)控到的Soft Eviction Signals
的值,一直在eviction-soft
水平線上下波動,那么Kubelet就會將該Node對應(yīng)的Node Condition在true和false頻繁切換。這可不是什么好事,它可能會帶來kube-scheduler做出錯誤的調(diào)度決定。kubelet是怎么處理這種情況的呢?
很簡單,Kubelet通過添加參數(shù)eviction-pressure-transition-period
(default 5m0s)配置,使Kubelet在解除由Evicion Signal映射的Node Pressure之前,必須等待這么長的時間。
因此,邏輯就變成這樣了:
Soft Evction Singal
高于Soft Eviction Thresholds
時,Kubelet還是會立刻設(shè)置對應(yīng)的MemoryPressure Or DiskPressure為True。
當(dāng)MemoryPressure Or DiskPressure為True的前提下,發(fā)生了Soft Evction Singal
低于Soft Eviction Thresholds
的情況,則需要等待eviction-pressure-transition-period
(default 5m0s)配置的這么長時間,才會將condition pressure切換回False。
一句話總結(jié):Node Condition Pressure成為True容易,切換回False則要等
eviction-pressure-transition-period
。
Kubelet的Eviction流程概括如下:
在每一個監(jiān)控周期內(nèi),如果Eviction Thresholds被觸及,則:
獲取候選Pod
Fail the Pod
等待該P(yáng)od被Terminated 如果該P(yáng)od由于種種原因沒有被成功Terminated,Kubelet將會再選一個Pod進(jìn)行Fail Operation。其中,F(xiàn)ail Pod的時候,Kubelet是通過調(diào)用容器運(yùn)行時的KillPod接口,如果接口返回True,則認(rèn)為Fail Pod成功,否則視為失敗。
kubelet根據(jù)Pod的QoS Class實現(xiàn)了一套默認(rèn)的Evication策略,內(nèi)容見我的另外一篇博文Kubernetes Resource QoS機(jī)制解讀中介紹的“如何根據(jù)不同的QoS回收Resource”,這里不再贅述。
下面給出Eviction Strategy的圖解:
有些情況下,eviction pods可能只能回收一小部分的資源就能使得Evication Signal
的值低于Thresholds。但是,可能隨著資源使用的波動或者新的調(diào)度Pod使得在該Node上很快又會觸發(fā)evict pods的動作,eviction畢竟是耗時的動作,所以應(yīng)該盡量避免這種情況的發(fā)生。
Kubelet是通過--eviction-minimum-reclaim
(e.g. memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi)來控制每次Evict Pods后,Node上對應(yīng)的Resource不僅要比Eviction Thresholds低,還要保證最少比Eviction Thresholds低--eviction-minimum-reclaim
中配置的數(shù)量。
正常情況下,但Node上資源利用率很高時,Node的資源回收是會通過Kubelet Eviction觸發(fā)完成。但是存在這么一種情況,Kubelet配置的Soft/Hard memory.available還沒觸發(fā),卻先觸發(fā)了Node上linux kernel oom_killer,這時回收內(nèi)存資源的請求就被kernel oom_killer處理了,而不會經(jīng)過Kubelet Eviction去完成。
我的博文Kubernetes Resource QoS機(jī)制解讀中介紹過,Kubelet根據(jù)Pod QoS給每個container都設(shè)置了oom_score_adj,整理如下:
Quality of Service | oom_score_adj |
---|---|
Guaranteed | -998 |
BestEffort | 1000 |
Burstable | min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) |
oom_killer
根據(jù)container使用的內(nèi)存占Node總內(nèi)存的百分比計算得到該container的oom_score,然后再將該oom_sore和前面對應(yīng)的oom_score_adj相加作為最終的oom_score,Node上所有containers的最終oom_score進(jìn)行排名,將oom_score得分最高的container kill掉。通過如此方式進(jìn)行資源回收。
oom_killer這樣做的目標(biāo)就是干掉QoS低的又消耗最多內(nèi)存(相對request值)的容器首先被kill掉,如此回收內(nèi)存。
不同于Kubelet Evict Pods的是,Node OOM Behavior存在一個缺點:如果Pod中某個容器被oom_killer干掉之后,會根據(jù)該容器的RestartPolicy決定是否restart這個容器。如果這是個有問題的容器,restart之后,可能又很快消耗大量內(nèi)存進(jìn)而觸發(fā)了再次Node OOM Behavior,如此循環(huán)反復(fù),該Node沒有真正的回收到內(nèi)存資源。
前面提到,Kubelet會定期的將Node Condition傳給kube-apiserver并存于etcd。kube-scheduler watch到Node Condition Pressure之后,會根據(jù)以下策略,阻止更多Pods Bind到該Node。
Node Condition | Scheduler Behavior |
---|---|
MemoryPressure | No new BestEffort pods are scheduled to the node. |
DiskPressure | No new pods are scheduled to the node. |
感謝各位的閱讀,以上就是“Kubernetes Eviction Manager工作機(jī)制是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Kubernetes Eviction Manager工作機(jī)制是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。