Resources - Resource Management
LimitRange 用於設置 Namespace 中容器的資源請求和限制(如 CPU 和記憶體的最小值和最大值),保證資源分配合理並防止極端配置。
ResourceQuota 則控制整個 Namespace 的資源配額,限制該 Namespace 中的資源總量(如 Pod 數量、CPU 和記憶體總量)。
LimitRange
定義
LimitRange 是 Kubernetes 提供的一種資源限制策略,用於控制特定 Namespace 中每個 Container 的資源請求與限制範圍。它的主要目的是避免極端的資源配置,確保資源使用的合理性與集群穩定性。
LimitRange 可以針對以下資源進行配置:
- CPU:限制單個 Container 可使用的處理能力。
- 記憶體:限制單個 Container 可分配的記憶體空間。
- 儲存空間:限制單個 PersistentVolumeClaim 的儲存大小。
特性
- 資源請求與限制範圍
- 定義 Container 的資源請求(Request)和限制(Limit)的最大與最小範圍。
- Request 是應用保證獲得的最低資源。
- Limit 是應用最多可使用的資源上限。
- 自動化預設值
- 當使用者未明確設定資源請求或限制時,LimitRange 提供自動填充的預設值(Default)。
- 預設值確保資源配置合理,避免 Container 啟動時出現無法預測的行為。
- 避免資源浪費與爭奪
- 通過設置資源請求下限,防止應用分配過低的資源,導致性能不佳。
- 通過設置資源限制上限,防止單個應用佔用過多資源,影響集群其他應用的穩定性。
- 細粒度控制
- 作用於單個 Container 的資源單位,適合精確控制應用的資源使用行為。
使用情境
- 多租戶環境中的穩定性管理
- 避免不同應用使用極端配置(例如,無限大的資源請求或無資源限制)。
- 應用程式預設資源配置
- 對開發者未指定資源需求的應用提供合理的預設資源限制,減少手動設置的工作量。
- 防止資源爭奪
- 在共享環境中限制單個 Container 的資源使用上限,保證其他應用的運行。
實作一個 LimitRange
- 首先我們建立一個要限制的 LimitRange 的 Nampspace,叫做
limit-namespace
。
kubectl.exe create ns limit-namespace
---
namespace/limit-namespace created
- 接著宣告一個 LimitRange,並且設定 namespace 為
limit-namespace
,並且宣告預設資源配額。
limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:
namespace: limit-namespace
name: limit-range
spec:
limits:
- max:
cpu: 1000m
memory: 500Mi
min:
cpu: 100m
memory: 50Mi
type: Container
- 接著透過指令來建立 LimitRange。
kubectl.exe apply -f limit-range.yaml
---
limitrange/limit-range created
- 我們也可以透過指令查看建立的詳細內容。
kubectl.exe describe -n limit-namespace limitranges limit-range
---
Name: limit-range
Namespace: limit-namespace
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container memory 50Mi 500Mi 500Mi 500Mi -
Container cpu 100m 1 1 1 -
- 建立 LimitRange 後,在這個 namespace 底下建立 Pod 的時候,如果沒有特別宣告自己的資源請求設定,kubernetes 會依照 LimitRange 設定提供的預設值設定資源,如果有設定資源配額,但超過 LimitRange 的話,kubernetes 會阻止。
- 如果 Pod 內的任何容器沒有宣告自己的 Request 和 Limit,則該容器設置預設的 CPU 和 Memory 的 Request 和 Limit。
- 確保每個 Pod 中的容器宣告的 Request 至少大於等於 limits.defaultRequest (Default Request)
- 確保每個 Pod 中的容器宣告的 Request 至少小於等於 limits.default (Default Limit)
- 宣告一個沒有 Request 和 Limit 的 Pod,並用指令將他運行起來。
limit-range-pod.yaml
apiVersion: v1
kind: Pod
metadata:
namespace: limit-namespace
name: limit-range-pod
spec:
containers:
- name: default-limit-range-pod
image: nginx
kubectl.exe apply -f limit-range-pod.yaml
---
pod/limit-range-pod created
- 接著我們透過指令觀察,會發現他預設幫我們設定了 LimitRange 的預設 Request 和 Limit。
kubectl.exe describe pods -n limit-namespace limit-range-pod
---
Name: limit-range-pod
Namespace: limit-namespace
...中間省略
Containers:
default-limit-range-pod:
Container ID: docker://7bc18a2044e331294d274fb9a670ff6cc14409ca1f4b79f204bc093cb7639925
Image: nginx
Image ID: docker-pullable://nginx@sha256:0a399eb16751829e1af26fea27b20c3ec28d7ab1fb72182879dcae1cca21206a
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 24 Jan 2025 17:33:24 +0800
Ready: True
Restart Count: 0
Limits:
cpu: 1
memory: 500Mi
Requests:
cpu: 1
memory: 500Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8pbwv (ro)
...後面省略...
- 接著我們試著如果我們建立一個超過最大限制的 Pod,在建立的時候會發現 kubernetes 會阻擋。
over-limit-range-pod.yaml
apiVersion: v1
kind: Pod
metadata:
namespace: limit-namespace
name: limit-range-pod
spec:
containers:
- name: default-limit-range-pod
image: nginx
resources:
limits:
cpu: '1500m' # LimitRange的Limit是1個單位的CPU
memory: '1Gi' # LimitRange的Limit是500Mi的Memory
kubectl.exe apply -f over-limit-range-pod.yaml
---
Error from server (Forbidden): error when creating "over-limit-range-pod.yaml": pods "limit-range-pod" is forbidden: [maximum cpu usage per Container is 1, but limit is 1500m, maximum memory usage per Container is 500Mi, but limit is 1Gi]
- 接著我們試著如果我們建立一個不滿足 Request 的 Pod,在建立的時候會發現 kubernetes 會阻擋。
lower-request-range-pod.yaml
apiVersion: v1
kind: Pod
metadata:
namespace: limit-namespace
name: limit-range-pod
spec:
containers:
- name: default-limit-range-pod
image: nginx
resources:
requests:
cpu: "50m" # LimitRange的Request是100m的CPU
memory: "5Mi" # LimitRange的Request是50Mi的Memory
kubectl.exe apply -f lower-request-range-pod.yaml
---
Error from server (Forbidden): error when creating "lower-request-range-pod.yaml": pods "limit-range-pod" is forbidden: [minimum cpu usage per Container is 100m, but request is 50m, minimum memory usage per Container is 50Mi, but request is 5Mi]
ResourceQuota
定義
ResourceQuota 是 Kubernetes 提供的資源配額機制, 用於限制特定 Namespace 的總體資源使用量。 它的目的是防止單個 Namespace 過度消耗資源,實現多租戶環境中的公平資源分配和全域資源控制。
ResourceQuota 可以限制以下資源:
- 計算資源:如 CPU 和記憶體的總使用量(Request 和 Limit)。
- 儲存資源:如 PersistentVolumeClaim 的數量和總大小。
- 對象數量:如 Pod、Service、ConfigMap 等 Kubernetes 對象的數量。
特性
- 全域資源限制
- 為 Namespace 設置資源的總消耗上限,包括 CPU、記憶體、Pod 數量等。
- ResourceQuota 規定了 Namespace 的資源分配範圍,避免資源被單個 Namespace 獨占。
- 資源公平性
- 在多租戶環境中,確保每個團隊或應用擁有明確的資源配額,實現資源的公平使用。
- 管理靈活性
- ResourceQuota 支援多種資源類型的配額限制,根據需求調整 Namespace 資源使用策略。
- 防止資源枯竭
- 限制資源總量,避免特定 Namespace 無限消耗,確保整個集群的資源供應穩定。
- 結合 LimitRange 使用
- 通常與 LimitRange 配合使用:LimitRange 控制單個資源單位的範圍,而 ResourceQuota 則控制整體使用量,實現全局與局部資源管理的平衡。
使用情境
- 多租戶環境中的資源分配
- 為不同團隊或應用設定資源上限,確保公平分配,避免某一租戶消耗過多資源。
- 資源總量管理
- 控制整個 Namespace 的資源使用量,防止資源枯竭。
- 儲存資源限制
- 限制 Namespace 中 PersistentVolumeClaim 的總數量與總大小,防止磁碟空間被過度佔用。
限額功能
1. 運算資源配額 (Compute Resource Quotas)
運算資源配額限制 Namespace 中的 CPU 和記憶體資源,通常包括以下幾種設定:
- limits.cpu:限制所有容器的 CPU 上限,防止單個容器消耗過多的 CPU。
- limits.memory:限制所有容器的記憶體上限,防止單個容器消耗過多的記憶體。
- requests.cpu:設置容器的 CPU 請求,這是容器啟動時保證獲得的最低 CPU 資源。
- requests.memory:設置容器的記憶體請求,這是容器啟動時保證獲得的最低記憶體資源。
- hugepages-
<size>
:設定容器所需的巨大頁面記憶體(例如,hugepages-2Mi
),這對於需要大量記憶體的應用程序(如數據庫或科學計算)非常有用。
這些運算資源配額幫助確保集群中的每個 Namespace 不會因為資源超限而影響其 他應用的穩定性。
2. 擴展資源配額 (Extended Resource Quotas)
擴展資源配額用於管理標準 CPU 和記憶體之外的特殊資源,如 GPU。以下是一些示例:
- requests.nvidia.com/gpu:此資源配額控制 Namespace 中 GPU 的總數量。例如,如果設定
requests.nvidia.com/gpu: 4
,那麼該 Namespace 只能使用最多 4 個 GPU。這對於高效能計算和機器學習工作負載非常重要。
這樣的配額有助於合理分配 GPU 資源,避免單一應用佔用過多的計算資源。
3. 儲存資源配額 (Storage Resource Quotas)
儲存資源配額限制 Namespace 中的儲存資源,通常涉及以下幾種設定:
- requests.storage:此配額限制 Namespace 中所請求的總儲存空間。這對於確保儲存資源的合理分配和集群的穩定性至關重要。
例如,如果設定了 requests.storage: 100Gi
,那麼該 Namespace 可以請求最多 100Gi 的儲存資源。