目錄

Kubernetes 資源調度與使用量限制

Requests、Limits、LimitRange、ResourceQuota、QoS、Eviction

Requests 與  Limits

當節點資源不夠時,沒有設定 requests 和 limits 的 pod 會優先被趕走  !

Requests

K8s Scheduler 會根據 requests 的值尋找資源夠用的節點,並將 Pod 分配給它,但不等於 Pod 啟動時的初始資源,只是會影響 Scheduler 的分配

Requests 沒有設定,則 Scheduler 有可能將 Pod 集中到某同一節點

Limits

若 Pod 中的 process 要求的資源量超過 limits 的值,將終止 process

Limits 沒有設定,則 Pod 可使用的資源為無上限;

如果只設其中一個?

1. 有 Requests ,沒 Limits

Scheduler 會根據 Requests,尋找資源夠用的節點分配,但使用量無上限;

2. 有 Limits,沒 Requests

預設會將 Requests 等同於 Limits

LimitRange

每個 Pod 都要設很麻煩,可以批次設定嗎? 答案就是 LimitRange。可用來限制 namespace 下所有資源,包含:

  • 預設的 requests、limits 值 如果 Pod 沒有設定資源限制,將套用預設值

  • 限制 Pod 的資源上下限。如果 Pod 的 limits、requests 設定不滿足 LimitRange,則無法啟動

  • 限制每個 PVC 的最小、最大空間

  • 限制 Pod 的 requests 、limits 比例 ( maxLimitRequestRatio、minLimitRequestRatio )

以下為一個 LimitRange 範例,限制 namespace 下的 Pod,memory 的上下限分別是 4G、1G。因此 Pod 的 requests 不得小於 1G,limits 不得超過 4G,否則無法啟動。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: LimitRange
metadata:
  name: limit-range
  namespace: my-namespace
spec:
  limits:
    - default:
        memory: 1Gi
      defaultRequest:
        memory: 1Gi
      max:
        memory: 4Gi
      min:
        memory: 1Gi
  type: Container

QoS

Guaranteed

requests 和 limits 相同,是最保險的設定,確保資源一定足夠

BestEffort

可得到最佳效能,讓資源吃到飽,requests 與 limits 皆不設定

Burstable

除了以上兩種都是 Burstable,表示有可能會因底層資源不足而被 K8s 搬到其他節點 (Pod 會被重啟)

Eviction

kubelet 預設每 10 秒監控一次 container,當發生資源不足,會將節點的 MemoryPressure /DiskPressure /PIDPressure 狀態改為 True,並將 Pod 驅逐。 預設的 eviction threshold 如下

  • memory.available<100Mi
  • nodefs.available<10%
  • imagefs.available<15%

若要修改 kubelet 設定,可參考官方文件,不建議直接修改 kubelet config map

結論

1. 所有服務都設定 requests,避免分配不均

2. 最好採用 Guaranteed QoS

3. DaemonSet 不要產生 BestEffort 的 Pod,因為當資源不夠時,BestEffort Pod 會最先被調度,但 DaemonSet 被移除之後會立即被重建到相同的節點

4. 盡量把 requests/limits 設小,透過 replica set 水平擴充,而非一昧增加資源給特定的 Pod

5. 透過 Affinity 設定,可讓 Pod 優先分配到有特定特徵的節點(例如 DB 服務分配到高 I/O 的節點)