Skip to content

antony@notes:~/misc$ cat "Pod-Priority-and-Preemption.md"

Pod Priority and Preemption

2025-01-26· misc

Pod Priority and Preemption

Pod 可以有 priority (優先順序)。 優先順序表示 Pod 相對於其他 Pod 的重要性。 如果 Pod 無法排程,scheduler 會嘗試先佔用 (驅逐) 優先順序較低的 Pod,使待排程 Pod 的排程成為可能。

:::danger 在並非所有使用者都受到信任的群集中,惡意使用者可能會以最高的優先順序建立 Pod,導致其他 Pod 被驅逐/無法排程。 管理員可以使用 ResourceQuota 防止使用者以高優先順序建立 Pod。 :::

How to use priority and preemption

要使用 priority 和 preemption:

  1. 新增一個或多個 PriorityClasses
  2. 建立 Pod,並將 PriorityClassName 設定為新增的 PriorityClasses 其中的一個。 當然,不需要直接建立 Pod;通常會將 priorityClassName 加入集合物件(如 Deployment)的 Pod 模版。

PriorityClass

PriorityClass 是一個 non-namespaced 的 Object,定義了從優先級名稱到優先級整數值的映射。 名稱在 PriorityClass 物件元資料的 name 欄位中指定。 值在必填 value 欄位中指定。 值越大,優先順序越高。 PriorityClass 物件的名稱必須是有效的 DNS subdomain name,且不能以 system- 為前綴。

PriorityClass 物件可以有任何小於或等於 10 億的 32 位元整數值。 這表示 PriorityClass 物件的 values 範圍為 -21474836481000000000(含 1000000000)。 更大的數字保留給代表關鍵系統 Pod 的內建 PriorityClass。 叢集管理員應該為他們想要的每個此類映射建立一個 PriorityClass 物件。

PriorityClass 也有兩個可選欄位:globalDefaultdescriptionglobalDefault 欄位表示此 PriorityClass 的值應該用於沒有 priorityClassName 的 Pod。 系統中只能存在一個 globalDefault 設為 truePriorityClass。 如果沒有設定 globalDefaultPriorityClass,則沒有 priorityClassName 的 Pod 的優先順序為零。

description 欄位是任意字串。 它是用來告訴叢集使用者何時應該使用此 PriorityClass。

PodPriority 與現有叢集的注意事項

  • 如果您升級現有的叢集,但沒有此功能,現有 Pod 的優先順序實際上為零。
  • 增加 GlobalDefault 設為 truePriorityClass 不會改變現有 Pod 的優先順序。
  • 如果刪除 PriorityClass,使用已刪除 PriorityClass 名稱的現有 Pod 將維持不變,但無法建立更多使用已刪除 PriorityClass 名稱的 Pod。

Example PriorityClass

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."

Non-preempting PriorityClass

具有 preemptionPolicy: Never 的 Pod 會排在較低優先順序的 Pod 之前進入排程佇列,但它們無法優先排程其他 Pod。 等待排程的非優先 Pod 會留在排程佇列中,直到有足夠的可用資源,可以進行排程為止。 非優先排程的 Pod 和其他 Pod 一樣,都會受到排程器後關的限制。 這表示如果排程器嘗試這些 Pod 但無法排程,它們會以較低的頻率重新嘗試,讓其他優先順序較低的 Pod 在它們之前排程。

preemptionPolicy 預設為 PreemptLowerPriority,這會允許該 PriorityClass 的 Pod 搶先佔用較低優先順序的 Pod (現有的預設行為)。如果 preemptionPolicy 設定為 Never,則該 PriorityClass 中的 Pod 將不會優先處理。

資料科學工作負載的使用範例。 使用者可能會提交一項工作,希望其優先順序高於其他 workloads,但不希望因為搶先執行 Pod 而丟棄現有工作。 具有 preemptionPolicy: Never 的高優先順序工作,只要有足夠的叢集資源「自然地」空出來,就會排在其他已排隊的 Pod 之前。

Example Non-preempting PriorityClass

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority-nonpreempting
value: 1000000
preemptionPolicy: Never
globalDefault: false
description: "This priority class will not cause other pods to be preempted."

Pod priority

有了一個或多個 PriorityClass 之後,就可以建立 Pod,在規格中指定其中一個 PriorityClass 名稱。 priority admission controller 會使用 priorityClassName 欄位,並填入優先順序的整數值。 如果找不到 PriorityClass,Pod 就會被拒絕。 以下 YAML 是 Pod 設定的範例,使用了前面範例中建立的 PriorityClass。 優先順序允許控制器會檢查規格,並將 Pod 的優先順序解析為 1000000

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  priorityClassName: high-priority