圖文輕鬆說透 K8S Pod 各種驅逐場景

圖文輕鬆說透 K8S Pod 各種驅逐場景

Kubernetes Pod 被驅逐是什麼意思?

它們被終止,通常是沒有足夠資源的結果。但是爲什麼會這樣呢?

驅逐是指派給節點的Pod 被終止的過程。Kubernetes 中最常見的情況之一是Preemption,爲了在資源有限的節點中調度新的 Pod,需要終止另一個 Pod 以釋放資源。

此外,Kubernetes 會不斷檢查資源並在需要時驅逐 Pod,這個過程稱爲節點壓力驅逐

在本文中,您將發現:

Pod 被驅逐的原因:搶佔和節點壓力

在 Kubernetes 中發生 Pod 驅逐的原因有多種。最重要的是:

  • 搶佔
  • 節點壓力驅逐

搶佔式驅逐

搶佔是這樣一個過程:如果一個新的 Pod 需要被調度,但是沒有任何合適的節點擁有足夠的資源,那麼 kube-scheduler 將通過驅逐(終止)一些優先級較低的 Pod 來檢查新的 Pod 是否可以成爲那個節點的一部分。

我們先了解一下 Kubernetes 調度是如何工作的。

Pod 調度

Kubernetes調度是將 Pod分配給節點的過程。

默認情況下,有一個 Kubernetes 實體負責調度,稱爲kube-scheduler將在控制平面中運行。Pod 將以 Pending 狀態啓動,直到找到匹配的節點。

將 Pod 分配給節點的過程遵循以下順序:

  1. 過濾
  2. 計分

過濾

過濾步驟中, kube-scheduler將選擇當前 Pod 可能放置的所有節點。此處將考慮 Taints 和 Tolerations 等功能。完成後,它將有一個適合該 Pod 的節點列表。

計分

評分步驟中, kube-scheduler將獲取上一步的結果列表並爲每個節點分配一個分數。這樣,候選節點從最適合到最不適合排序。如果兩個節點的分數相同,kube-scheduler 會隨機對它們進行排序。

Filtering and Scoring process

但是,如果沒有適合 Pod 運行的節點怎麼辦?

在這種情況下,Kubernetes 將啓動搶佔過程,嘗試驅逐優先級較低的 Pod,以便分配新的 Pod。

Pod 優先級

在搶佔過程中如何防止特定 Pod 被驅逐?

很有可能,一個特定的 Pod 對你來說很重要,永遠不應該被終止。

這就是 Kubernetes 具有Priority Classes的原因。

優先級類是一個 Kubernetes 對象,它允許我們將數字優先級值映射到特定的 Pod。那些具有更高價值的 Pod 被歸類爲更重要並且不太可能被驅逐。

您可以使用以下方式查詢當前的優先級:

kubectl get priorityclasses
kubectl get pc

NAME                      VALUE        GLOBAL-DEFAULT   AGE
system-cluster-critical   2000000000   false            2d
system-node-critical      2000001000   false            2d

優先級示例

讓我們使用 Lovenstein 先生的 Berry Club 漫畫做一個實際的例子:

https://www.mrlovenstein.com/
https://tapas.io/episode/220482

共有三個 Pod 分別代表藍莓、樹莓和草莓:

NAME         READY   STATUS             RESTARTS   AGE
blueberry    1/1     Running            0          4h41m
raspberry    1/1     Running            0          58m
strawberry   1/1     Running            0          5h22m

並且有兩個優先等級:真莓和假莓。第一個將具有更高的值,表示更高的優先級。

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: trueberry
value: 1000000
globalDefault: false
description: "This fruit is a true berry"

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: falseberry
value: 5000
globalDefault: false
description: "This fruit is a false berry"
  • 藍莓 將具有 trueberry 優先級(值 = 1000000)
  • 樹莓和草莓都將具有 falseberry 優先級(值 = 5000)

這意味着在搶佔的情況下,樹莓和草莓更有可能被驅逐,爲更高優先級的 Pod 騰出空間。

然後通過將此添加到 Pod 定義來將優先級類分配給 Pod:

 priorityClassName: trueberry

現在讓我們嘗試再添加三種水果,但要稍加改動。所有新水果都將包含更高的優先級,稱爲trueberry

由於三個新水果有節點無法滿足的內存或 CPU 要求,kubelet驅逐所有優先級低於新水果的 Pod。Blueberry 保持運行,因爲它具有更高的優先級。

NAME         READY   STATUS             RESTARTS   AGE
banana       0/1     ContainerCreating  0          2s
blueberry    1/1     Running            0          4h42m
raspberry    0/1     Terminating        0          59m
strawberry   0/1     Terminating        0          5h23m
tomato       0/1     ContainerCreating  0          2s
watermelon   0/1     ContainerCreating  0          2s

Kubernetes Priority Classes 實例

這是最終結果:

NAME         READY   STATUS             RESTARTS   AGE
banana       1/1     Running            0          3s
blueberry    1/1     Running            0          4h43m
tomato       1/1     Running            0          3s
watermelon   1/1     Running            0          3s

節點壓力驅逐

除了搶佔,Kubernetes 還會不斷檢查節點資源,如磁盤壓力、CPU 或內存不足 (OOM)。

如果節點中的資源(如CPU內存)消耗達到某個閾值kubelet將開始驅逐 Pod 以釋放資源。將考慮服務質量 (QoS) 來確定驅逐順序。

服務質量等級

在 Kubernetes 中,Pod 提供三個QoS 類之一,這將定義在缺乏資源的情況下它們被驅逐的可能性,從不太可能到更有可能:

  • Guaranteed 有保證的
  • Burstable 可爆發的
  • BestEffort 盡最大努力

這些 QoS 等級是如何分配給 Pod 的?

這是基於對 CPU和內存的限制和請求。提醒一句:

  • Limits 限制:容器可以使用的最大資源量。
  • Requests 請求:容器運行所需的最小資源量。

有關限制和請求的更多信息,請查看通過示例瞭解 Kubernetes 限制和請求

https://sysdig.com/blog/kubernetes-limits-requests/

Kubernetes 中的 QoS 類

Guaranteed

如果滿足以下條件,Pod 將分配有保證的 QoS 等級:

  • Pod 中的所有容器都爲 CPU 和內存設置了限制和請求。
  • Pod 中的所有容器都具有相同的 CPU Limit 和 CPU Request 值。
  • Pod 中所有容器都具有相同的 memory Limit 和 memory Request 值

Guaranteed Pod 在正常情況下不會被驅逐。

Burstable

如果滿足以下條件,Pod 將分配有可突發的 QoS 等級:

  • 它沒有 Guaranteed QoS 等級。
  • 已爲 Pod 中的容器設置了 Limits 或 Requests 。

Burstable Pod 可以被驅逐,但比下一個類別更不可能。

BestEffort

如果出現以下情況,Pod 將分配有 BestEffort 的 QoS 等級:

  • Pod 中的任何容器都沒有設置限制和請求。

在發生節點壓力過程的情況下,BestEffort Pod 被驅逐的可能性最大。

重要提示:Limits 和 Requests 中可能還有其他資源,如 ephemeral-storage,但它們不用於 QoS Class 計算。

Quality of Service cheatsheet

如前所述,QoS 類將被考慮用於節點壓力驅逐。這是內部發生的過程。

kubelet 按照以下順序對要驅逐的 Pod 進行排序:

  1. BestEffort 或 Burstable使用量超過 requests 的 Pod
  2. Burstable使用量低於 requests 的 Pod 或者 GuaranteedPod

Kubernetes 將優先從第 1 組中驅逐 Pod,然後纔會嘗試在第 2 組驅逐。

上面的一些要點:

  • 如果您在容器中添加非常低的請求,它們的 Pod 可能會被分配到組 1,這意味着它更有可能被驅逐。
  • 你無法判斷哪個特定的 Pod 將被驅逐,只是 Kubernetes 會嘗試在第 2 組之前驅逐第 1 組中的 Pod。
  • GuaranteedPod 通常不會被驅逐:kubelet不會爲了安排其他 Pod 而驅逐它們。但是如果某些系統服務需要更多資源,kubelet 將在必要時終止Guaranteed Pod

其他類型的驅逐

本文重點介紹搶佔和節點壓力驅逐,但 Pod 也可以通過其他方式驅逐。例子包括:

API 發起的驅逐

可以使用 Kubernetes Eviction API 請求按需驅逐一個節點中的 Pod。

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#create-eviction-pod-v1-core

#公衆號:進擊雲原生 注:
請記住,Eviction API 不同於 Delete Pod,前者是 CREATE 動作,請求會創建 pods/eviction 子資源,後者是 DELETE 動作請求

基於污點的驅逐

藉助 Kubernetes Taints and Tolerations,您可以指導如何將 Pod 分配給節點。但是,如果您NoExecute對現有節點應用污點,所有不能容忍它的 Pod 將立即被驅逐。

node 級別排空(drain)

有時節點變得不可用或者不想再在這些節點上工作時。kubectl cordon命令會阻止在其上安排新的 Pod,運行kubectl drain nodename也可以一次完全清空所有當前節點上 Pod。節點中的所有 Pod 都將被驅逐,遵守其正常終止限期。

Prometheus 中的 Pod 驅逐監控

可以使用 Prometheus 通過執行以下操作輕鬆監控 Pod 驅逐:

kube_pod_status_reason{reason="Evicted"} > 0

Prometheus 監控中被驅逐的 Pod

這將顯示集羣中所有被驅逐的 Pod。您還可以將它與 kube_pod_status_phase{phase="Failed"}結合,以提醒那些在 Pod 出現故障後被驅逐的。

如果想深入挖掘,請查看以下有關在 Prometheus 中監控資源的文章:

結論

搶佔(preemption)期間,Kubernetes 將嘗試通過驅逐優先級較低的 Pod 釋放資源,來安排新的 Pod 。使用優先級類別(Priority Classes),可以控制哪些 Pod 在搶佔時更有可能繼續運行,因爲它們被驅逐的可能性較小。

在執行期間,Kubernetes 將檢查節點壓力並在需要時驅逐 Pod。使用 QoS classes,可以控制在節點壓力的情況下哪些 Pod 更有可能被驅逐。

內存和 CPU 是節點中的重要資源,您需要配置 Pod、容器和節點以使用適量的內存和 CPU。如果您合理地管理這些資源,不僅可以降低成本,還可以確保重要流程無論如何都能繼續運行。

說明

請關注 危 ❤ 工中號【進擊雲原生】,更有free資源供您學習

本文由mdnice多平臺發佈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章