Resources - Resource
Kubernetes Resource 設定包括 Request(最小資源)和 Limit(最大資源)。這有助於優化 資源分配 和確保 資源公平性, 並透過 ResourceQuota 和 LimitRange 控制命名空間層級的資源使用。
Request 與 Limit 的關係
在 Kubernetes 中,Request
和 Limit
是資源管理的兩個重要概念,用於控制 Pod 和容器使用的計算資源(如 CPU 和記憶體)。
resources:
requests:
cpu: '50m'
memory: '50Mi'
limits:
cpu: '100m'
memory: '100Mi'
- Request: 表示容器運行所需的最小資源量。Kubernetes 調度器根據 Request 來 決定將 Pod 安排在哪個節點。
- Limit: 表示容器可以使用的最大資源量。當容器嘗試使用超過 Limit 的資源時:
- 對於 CPU,超過部分會被節流(throttled)。
- 對於記憶體,超過部分會導致容器被終止(OOMKilled)。
可以總結成以下兩條公式
- 資源請求與節點可分配資源的關係:
說明:Request 必須是非負數,且不能超過節點上可用的分配資源(Node Allocatable)。
- Request 與 Limit 的大小關係:
說明: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)
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 設定 | 描述與應用 |
---|---|---|---|
只設定 Request | 是 | 否 | Kubernetes 保證至少分配設定的 Request 資源,不限制容器的最大資源使用。適用於資源需求隨負載 波動的應用,如 Web 應用或測試應用。 |
只設定 Limit | 否 | 是 | Kubernetes 預設將 Request 設為 Limit,確保容器的資源使用不超過設定的 Limit 且提供穩定性,QoS 等級為 Guaranteed,適合對資源有固定需求且不需彈性調整的應用。 |
設定 Request 和 Limit | 是 | 是 | Kubernetes 保證至少分配 Request 資源並限制資源使用不超過 Limit,提供資源彈性且防止過度使用,適用於需要穩定且可彈性調整資源的應用,如 Web 應用和 API 服務。 |
不設定 Request 和 Limit | 否 | 否 | 容器無限制地使用資源,QoS 等級為 BestEffort,不保證資源分配穩定,適用於非關鍵性應用或開發測試環境。 |
每種情況的敘述與應用
- 只設定 Request:
- 描述:當只設定 Request 時,Kubernetes 會保證容器至少獲得設定的 Request 資源,但不限制其最大資源使用。這樣可以確保容器在資源需求高峰時不會因為資源不足而出現問題,但仍可隨負載增加而動態使用更多資源。
- 應用:適用於資源需求會隨時間或流量波動的應用(如 Web 應用、測試環境),這些應用需要基礎的資源保證,但希望能靈活應對流量波動。
- 只設定 Limit:
- 描述:只設定 Limit 時,Kubernetes 預設將 Request 設為 Limit,這樣容器的資源使用不會超過設定的 Limit,並且其 QoS 等級為 Guaranteed。容器的資源使用被嚴格限制在設定的 Limit 範圍內,提供高穩定性,但會使資源分配效率降低,因為容器可能無法利用超過 Limit 的資源。
- 應用:適用於需要固定、穩定資源使用的應用(如後端服務、資料庫服務),這些應用通常需要確保運行不會因資源不足而中斷,但不一定需要高彈性。
- 設定 Request 和 Limit:
- 描述:同時設定 Request 和 Limit,Kubernetes 保證至少分配 Request 資源,並限制資源使用不超過 Limit。這樣設定提供了資源的彈性使用,同時限制資源過度消耗,避免資源浪費或衝突,保證應用在負載高峰時仍能正常運行。
- 應用:適合需要高穩定性和彈性資源的應用(如 Web 應用、API 服務),這些應用需要動態擴展或收縮資源,並且需要確保資源不會過度使用。
- 不設定 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 資源。
實際開發經驗
kubernetes 建議在始終在工作負載上設置 Request 和 Limit,但是要準 確評估使用那些值是非常不容易的。這是一個長期調整的過程,但仍有一些小建議:
- 盡可能的設定 Request 和 Limit,否則在檢視資源利用率的時候,將會是意義不大的 100%。
- 對不熟悉的應用設定較寬鬆的預設值。
- 可以設定 Namespace 下的 ResourceQuota 和 LimitRange,或者使用第三方服務監控或者資源推薦服務,例如利用 kubecost、Opencost 來定期檢視資源利用率是否健康。
- 同樣的應用,在利用資源率低和高之間,可能代表兩台主機的差距,也是成本優化巨大的關鍵。
- Helm 上的服務資源預設值可能不符合自身需求的資源分配,像在測試環境中的 ELK 服務並不需要預設那麼高的資源分配。
- 可以多多利用各種工具找出在叢集中無人維護的服務。
結論
- Request 與 Limit 控制 Pod 的資源分配和限制,影響調度與執行行為。
- QoS 等級 決定 Pod 的優先級和穩定性。
- ResourceQuota 控制命名空間的整體資源使用量。
- LimitRange 控制命名空間下所有容器的資源使用範圍。
- 透過合理配置資源限制與分配,確保 Kubernetes 集群資源高效且穩定運行。