跳至主要内容

Resources - Resource

Kubernetes Resource 設定包括 Request(最小資源)和 Limit(最大資源)。這有助於優化 資源分配 和確保 資源公平性, 並透過 ResourceQuotaLimitRange 控制命名空間層級的資源使用。


Request 與 Limit 的關係

在 Kubernetes 中,RequestLimit 是資源管理的兩個重要概念,用於控制 Pod 和容器使用的計算資源(如 CPU 和記憶體)。

resources:
requests:
cpu: '50m'
memory: '50Mi'
limits:
cpu: '100m'
memory: '100Mi'
  • Request: 表示容器運行所需的最小資源量。Kubernetes 調度器根據 Request 來決定將 Pod 安排在哪個節點。
  • Limit: 表示容器可以使用的最大資源量。當容器嘗試使用超過 Limit 的資源時:
    • 對於 CPU,超過部分會被節流(throttled)。
    • 對於記憶體,超過部分會導致容器被終止(OOMKilled)。

resources-resource

可以總結成以下兩條公式

  1. 資源請求與節點可分配資源的關係 0RequestNodeAllocatable0 \leq \text{Request} \leq \text{NodeAllocatable}

    說明:Request 必須是非負數,且不能超過節點上可用的分配資源(Node Allocatable)。

  2. Request 與 Limit 的大小關係 RequestLimit\text{Request} \leq \text{Limit} \leq \infty

    說明:Request 必須小於或等於 Limit。如果未設定 Limit,某些情況下可能為無限制(取決於環境設定)。


基本資源與單位

CPU

  • 單位:以核心(core)為單位,支持毫核(millicores),1 CPU = 1000m。 例如:1 表示 1 個核心,500m 表示 0.5 個核心。
  • 特性
    • 可壓縮:容器超出可用 CPU 時,性能會下降,但不會被終止(節流機制)。
    • 共享性:多容器可共享 CPU,動態分配資源。

Memory

  • 單位:以字節(Bytes)為基礎,支持簡化單位(如 Gi、Mi)。 例如:512Mi 表示 512 MiB 記憶體。
  • 特性
    • 不可壓縮:超出可用記憶體時,容器會被終止(OOMKilled)。
    • 專用性:記憶體不能像 CPU 一樣共享。

Pod 的服務品質 (QoS)

resource-qos

Kubernetes 根據資源的 Request 和 Limit,將 Pod 分為以下三種 服務品質 (Quality of Service, QoS) 等級

1. Guaranteed (保證)

  • 條件:
    • 一個 Pod 中每個容器的 Memory 和 CPU 的 Request 和 Limit 都被設置,並且相等
  • 特點:
    • 獲得最高的資源優先級,適合高優先級或關鍵應用。
    • 不容易被驅逐。

2. Burstable (突發型)

  • 條件:
    • 不是 Guaranteed Pod。
    • Pod 內至少有一個容器設定了 Memory 或 Cpu 的 Limit 或 Request。
  • 特點:
    • 資源利用率彈性較大,但可能在資源緊張時被驅逐。

3. BestEffort (最優)

  • 條件:
    • 一個 Pod 中所有容器 都未設置任何 Request 和 Limit
  • 特點:
    • 資源優先級最低,適合非關鍵或低優先級應用,容易被驅逐。

Resource 設定的排列組合

設定情境Request 設定Limit 設定描述與應用
只設定 RequestKubernetes 保證至少分配設定的 Request 資源,不限制容器的最大資源使用。適用於資源需求隨負載波動的應用,如 Web 應用或測試應用。
只設定 LimitKubernetes 預設將 Request 設為 Limit,確保容器的資源使用不超過設定的 Limit 且提供穩定性,QoS 等級為 Guaranteed,適合對資源有固定需求且不需彈性調整的應用。
設定 Request 和 LimitKubernetes 保證至少分配 Request 資源並限制資源使用不超過 Limit,提供資源彈性且防止過度使用,適用於需要穩定且可彈性調整資源的應用,如 Web 應用和 API 服務。
不設定 Request 和 Limit容器無限制地使用資源,QoS 等級為 BestEffort,不保證資源分配穩定,適用於非關鍵性應用或開發測試環境。

每種情況的敘述與應用

  1. 只設定 Request
    • 描述:當只設定 Request 時,Kubernetes 會保證容器至少獲得設定的 Request 資源,但不限制其最大資源使用。這樣可以確保容器在資源需求高峰時不會因為資源不足而出現問題,但仍可隨負載增加而動態使用更多資源。
    • 應用:適用於資源需求會隨時間或流量波動的應用(如 Web 應用、測試環境),這些應用需要基礎的資源保證,但希望能靈活應對流量波動。
  2. 只設定 Limit
    • 描述:只設定 Limit 時,Kubernetes 預設將 Request 設為 Limit,這樣容器的資源使用不會超過設定的 Limit,並且其 QoS 等級為 Guaranteed。容器的資源使用被嚴格限制在設定的 Limit 範圍內,提供高穩定性,但會使資源分配效率降低,因為容器可能無法利用超過 Limit 的資源。
    • 應用:適用於需要固定、穩定資源使用的應用(如後端服務、資料庫服務),這些應用通常需要確保運行不會因資源不足而中斷,但不一定需要高彈性。
  3. 設定 Request 和 Limit
    • 描述:同時設定 Request 和 Limit,Kubernetes 保證至少分配 Request 資源,並限制資源使用不超過 Limit。這樣設定提供了資源的彈性使用,同時限制資源過度消耗,避免資源浪費或衝突,保證應用在負載高峰時仍能正常運行。
    • 應用:適合需要高穩定性和彈性資源的應用(如 Web 應用、API 服務),這些應用需要動態擴展或收縮資源,並且需要確保資源不會過度使用。
  4. 不設定 Request 和 Limit
    • 描述:若不設定 Request 和 Limit,容器可以自由使用節點上的所有可用資源,QoS 等級為 BestEffort。這表示容器不會獲得任何資源保障,並且在資源競爭激烈時可能會被終止或延遲。
    • 應用:適用於對資源不敏感的應用(如開發、測試環境或非關鍵應用),這些應用能容忍資源分配不穩定,並且不需要固定的資源保障。

命名空間範圍內的資源限制

ResourceQuota

ResourceQuota 是一個命名空間範圍內的限制,用於限制集群中的資源使用量。管理員可以通過設定 ResourceQuota 控制在特定命名空間內使用的資源量。

功能

  • 限制命名空間內可創建的 Pod、Service、PVC 數量。
  • 限制命名空間內可使用的 CPU、記憶體存儲 總量。
  • 防止資源濫用,實現資源公平分配。

範例

apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: my-namespace
spec:
hard:
pods: 10 # 最大 Pod 數量
requests.cpu: '4' # 總 Request 的 CPU 限制
requests.memory: '8Gi' # 總 Request 的記憶體限制
limits.cpu: '8' # 總 Limit 的 CPU 限制
limits.memory: '16Gi' # 總 Limit 的記憶體限制
services: '5' # 最大 Service 數量
persistentvolumeclaims: '5' # 最大 PVC 數量

描述

  • Pods、Services、PVC:限制命名空間內創建的 Pod、Service 和 PVC 數量。
  • requests.cpu 和 requests.memory:限制命名空間內所有 Pod 的 CPU 和記憶體請求總量。
  • limits.cpu 和 limits.memory:限制命名空間內所有 Pod 的最大 CPU 和記憶體使用量。

LimitRange

LimitRange 用於設定命名空間範圍內的容器資源預設值,通常用於防止過大的資源請求。

功能

  • 限制單個容器的 Request 和 Limit
  • 設定資源的預設值,避免容器未指定資源時,導致不合理的資源使用。
  • 有助於統一資源管理,確保容器的資源配置在合理範圍內。

範例

apiVersion: v1
kind: LimitRange
metadata:
name: resource-limits
namespace: my-namespace
spec:
limits:
- type: Container
max:
cpu: '2' # 單個容器最大 CPU 使用量
memory: '4Gi' # 單個容器最大記憶體使用量
min:
cpu: '100m' # 單個容器最小 CPU 使用量
memory: '128Mi' # 單個容器最小記憶體使用量
default:
cpu: '500m' # 單個容器的預設 CPU
memory: '1Gi' # 單個容器的預設記憶體
defaultRequest:
cpu: '250m' # 單個容器的預設 Request CPU
memory: '512Mi' # 單個容器的預設 Request 記憶體

描述

  • max: 設定單個容器最大可用的 CPU 和記憶體數量。
  • min: 設定單個容器最小的資源請求量,避免資源過小導致容器無法正常運行。
  • default: 若容器未指定資源,則使用這些預設值作為容器的資源配置。
  • defaultRequest: 當容器未設定資源請求時,使用此作為預設的 Request 資源。

實際開發經驗

resource-namespace

kubernetes 建議在始終在工作負載上設置 Request 和 Limit,但是要準確評估使用那些值是非常不容易的。這是一個長期調整的過程,但仍有一些小建議:

  1. 盡可能的設定 Request 和 Limit,否則在檢視資源利用率的時候,將會是意義不大的 100%。
  2. 對不熟悉的應用設定較寬鬆的預設值。
  3. 可以設定 Namespace 下的 ResourceQuota 和 LimitRange,或者使用第三方服務監控或者資源推薦服務,例如利用 kubecost、Opencost 來定期檢視資源利用率是否健康。
  4. 同樣的應用,在利用資源率低和高之間,可能代表兩台主機的差距,也是成本優化巨大的關鍵。
  5. Helm 上的服務資源預設值可能不符合自身需求的資源分配,像在測試環境中的 ELK 服務並不需要預設那麼高的資源分配。
  6. 可以多多利用各種工具找出在叢集中無人維護的服務。

結論

  • Request 與 Limit 控制 Pod 的資源分配和限制,影響調度與執行行為。
  • QoS 等級 決定 Pod 的優先級和穩定性。
  • ResourceQuota 控制命名空間的整體資源使用量。
  • LimitRange 控制命名空間下所有容器的資源使用範圍。
  • 透過合理配置資源限制與分配,確保 Kubernetes 集群資源高效且穩定運行。