跳至主要内容

Resources - Resource Management

LimitRange 用於設置 Namespace 中容器的資源請求和限制(如 CPU 和記憶體的最小值和最大值),保證資源分配合理並防止極端配置。

ResourceQuota 則控制整個 Namespace 的資源配額,限制該 Namespace 中的資源總量(如 Pod 數量、CPU 和記憶體總量)。

resource-namespace

LimitRange

定義

LimitRange 是 Kubernetes 提供的一種資源限制策略,用於控制特定 Namespace 中每個 Container 的資源請求與限制範圍。它的主要目的是避免極端的資源配置,確保資源使用的合理性與集群穩定性。

LimitRange 可以針對以下資源進行配置:

  • CPU:限制單個 Container 可使用的處理能力。
  • 記憶體:限制單個 Container 可分配的記憶體空間。
  • 儲存空間:限制單個 PersistentVolumeClaim 的儲存大小。

特性

  1. 資源請求與限制範圍
    • 定義 Container 的資源請求(Request)和限制(Limit)的最大與最小範圍。
    • Request 是應用保證獲得的最低資源。
    • Limit 是應用最多可使用的資源上限。
  2. 自動化預設值
    • 當使用者未明確設定資源請求或限制時,LimitRange 提供自動填充的預設值(Default)。
    • 預設值確保資源配置合理,避免 Container 啟動時出現無法預測的行為。
  3. 避免資源浪費與爭奪
    • 通過設置資源請求下限,防止應用分配過低的資源,導致性能不佳。
    • 通過設置資源限制上限,防止單個應用佔用過多資源,影響集群其他應用的穩定性。
  4. 細粒度控制
    • 作用於單個 Container 的資源單位,適合精確控制應用的資源使用行為。

使用情境

  • 多租戶環境中的穩定性管理
    • 避免不同應用使用極端配置(例如,無限大的資源請求或無資源限制)。
  • 應用程式預設資源配置
    • 對開發者未指定資源需求的應用提供合理的預設資源限制,減少手動設置的工作量。
  • 防止資源爭奪
    • 在共享環境中限制單個 Container 的資源使用上限,保證其他應用的運行。

實作一個 LimitRange

  1. 首先我們建立一個要限制的 LimitRange 的 Nampspace,叫做 limit-namespace
kubectl.exe create ns limit-namespace
---

namespace/limit-namespace created
  1. 接著宣告一個 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
  1. 接著透過指令來建立 LimitRange。
kubectl.exe apply -f limit-range.yaml
---

limitrange/limit-range created
  1. 我們也可以透過指令查看建立的詳細內容。
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 -
  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)
  1. 宣告一個沒有 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
  1. 接著我們透過指令觀察,會發現他預設幫我們設定了 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)
...後面省略...
  1. 接著我們試著如果我們建立一個超過最大限制的 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]
  1. 接著我們試著如果我們建立一個不滿足 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 對象的數量。

特性

  1. 全域資源限制
    • 為 Namespace 設置資源的總消耗上限,包括 CPU、記憶體、Pod 數量等。
    • ResourceQuota 規定了 Namespace 的資源分配範圍,避免資源被單個 Namespace 獨占。
  2. 資源公平性
    • 在多租戶環境中,確保每個團隊或應用擁有明確的資源配額,實現資源的公平使用。
  3. 管理靈活性
    • ResourceQuota 支援多種資源類型的配額限制,根據需求調整 Namespace 資源使用策略。
  4. 防止資源枯竭
    • 限制資源總量,避免特定 Namespace 無限消耗,確保整個集群的資源供應穩定。
  5. 結合 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 的儲存資源。

4. 物件計數配額 (Object Count Quotas)

物件計數配額限制 Namespace 中的 Kubernetes 物件數量,包括:

  • Secrets:此配額限制 Namespace 中可創建的 Secret 物件數量。Secret 主要用於存儲敏感資訊,如密碼、憑證等。

例如,Secrets: 10 配額意味著每個 Namespace 最多只能創建 10 個 Secret。

實作一個 ResourceQuota

  1. 首先我們建立一個 Namespace,叫做quota-namespace
kubectl.exe create ns quota-namesapce
---

namespace/quota-namesapce created
  1. 接著宣告一個 ResourceQuota,並且設定 namespace 為 quota-namespace,接著設定命名空間下的總資源上限。
resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
namespace: quota-namesapce
name: resource-quota
spec:
hard:
requests.cpu: '1'
requests.memory: '1Gi'
limits.cpu: '2'
limits.memory: '2Gi'
  1. 接著透過指令來建立 ResourceQuota。
kubectl.exe apply -f resource-quota.yaml
---

resourcequota/resource-quota created
  1. 我們也可以透過指令查看建立的詳細內容。
kubectl.exe describe resourcequotas -n quota-namesapce resource-quota
---

Name: resource-quota
Namespace: quota-namesapce
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
requests.cpu 0 1
requests.memory 0 1Gi
  1. 建立 ResourceQuota 後,在這個 namespace 底下建立 Pod 或 PersistentVolumeClaims(PVC) 的時候,超出限制的資源時,kubernetes 就會阻止。

  2. 我們試著如果建立一個超過最大限制的 Pod,並且 namespace 要在 quota-namespace 底下才會被套用。

over-quota-range-pod.yaml
apiVersion: v1
kind: Pod
metadata:
namespace: quota-namesapce
name: over-quota-range-pod
spec:
containers:
- name: over-quota-range-pod
image: nginx
resources:
requests:
cpu: '1200m' # ResourceQuota的Request上限是1個單位的CPU
memory: '1500Mi' # ResourceQuota的Request上限是1GB的Memory
limits:
cpu: '2200m' # ResourceQuota的Limit上限是2個單位的CPU
memory: '2500Mi' # ResourceQuota的Limit上限是2GB的Memory
  1. 在建立的時候會發現 kubernetes 會阻擋。
kubectl.exe apply -f .\over-quota-range-pod.yaml
---

Error from server (Forbidden): error when creating ".\\over-quota-range-pod.yaml": pods "over-quota-range-pod" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=2200m,limits.memory=2500Mi,requests.cpu=1200m,requests.memory=1500Mi, used: limits.cpu=0,limits.memory=0,requests.cpu=0,requests.memory=0, limited: limits.cpu=2,limits.memory=2Gi,requests.cpu=1,requests.memory=1Gi

LimitRange 與 ResourceQuota 比較

特性LimitRangeResourceQuota
作用範圍單個 Container 的資源範圍。整個 Namespace 的資源總量。
控制對象CPU、記憶體、儲存單位的最小/最大範圍。Pod 數量、計算資源、儲存總量等整體限制。
管理粒度微觀:關注單一資源單位的限制。宏觀:關注整體資源分配的控制。
主要用途限制極端資源配置,確保資源分配合理性。控制資源總量,實現公平性與全局管理。
適用場景單個 Container 的資源配置與合理性保護。多租戶環境下的資源分配公平性與控制。

結論

  • LimitRange 強調針對單一應用的資源配置進行精細化管理,適合用於單個 Pod 或 Container 的資源控制場景。
  • ResourceQuota 則著眼於全局,實現 Namespace 級別的資源分配與限制,適用於多租戶環境或集群資源整體管理。