資源配額

當多個使用者或團隊共享一個擁有固定數量節點的叢集時,可能會出現一個團隊使用超過其公平份額的資源的情況。

資源配額是管理員解決此問題的一種工具。

資源配額由 ResourceQuota 物件定義,它提供了限制每個名稱空間中聚合資源消耗的約束。ResourceQuota 還可以限制按 API 型別在名稱空間中可建立物件的數量,以及名稱空間中 API 物件可能消耗的基礎設施資源的總量。

Kubernetes 資源配額如何工作

資源配額的工作原理如下:

  • 不同的團隊在不同的名稱空間中工作。這種分離可以透過RBAC或任何其他授權機制來強制執行。

  • 叢集管理員為每個名稱空間至少建立一個 ResourceQuota。

    • 為確保執行得到持續的強制執行,叢集管理員還應限制刪除或更新該 ResourceQuota 的訪問許可權;例如,透過定義驗證准入策略
  • 使用者在名稱空間中建立資源(pod、service 等),配額系統會跟蹤使用情況,以確保其不超過 ResourceQuota 中定義的硬資源限制。

    您可以將範圍應用於 ResourceQuota,以限制其適用範圍。

  • 如果建立或更新資源違反了配額約束,控制平面將以 HTTP 狀態碼 403 Forbidden 拒絕該請求。錯誤訊息將解釋將要違反的約束。

  • 如果在名稱空間中為 cpumemory資源啟用了配額,使用者在定義 Pod 時必須指定這些值的請求或限制;否則,配額系統可能會拒絕 pod 建立。

    資源配額演練展示瞭如何避免此問題的示例。

您通常不直接建立 Pod;例如,您通常會建立工作負載管理物件,如Deployment。如果您建立的 Deployment 試圖使用比可用資源更多的資源,那麼 Deployment(或其他工作負載管理物件)的建立將成功,但 Deployment 可能無法使其管理的所有 Pod 都存在。在這種情況下,您可以檢查 Deployment 的狀態,例如使用 kubectl describe,以檢視發生了什麼。

  • 對於 cpumemory 資源,ResourceQuotas 強制要求該名稱空間中所有(新)pod 都為該資源設定限制。如果您在名稱空間中為 cpumemory 強制執行資源配額,您和其他客戶端必須為每個新提交的 Pod 指定該資源的 requestslimits。如果您不這樣做,控制平面可能會拒絕該 Pod 的准入。
  • 對於其他資源:ResourceQuota 會生效,並將忽略名稱空間中沒有為該資源設定限制或請求的 pod。這意味著,如果名稱空間的臨時儲存配額受到限制,您可以建立一個新的 pod 而不設定臨時儲存的限制/請求。

您可以使用LimitRange來自動設定這些資源的預設請求。

ResourceQuota 物件的名稱必須是有效的DNS 子域名

可以使用名稱空間和配額建立的策略示例包括:

  • 在記憶體為 32 GiB,核心為 16 個的叢集中,讓 A 團隊使用 20 GiB 和 10 個核心,B 團隊使用 10 GiB 和 4 個核心,並保留 2 GiB 和 2 個核心用於未來分配。
  • 將“testing”名稱空間限制為使用 1 個核心和 1 GiB 記憶體。讓“production”名稱空間使用任意數量。

如果叢集的總容量小於名稱空間配額的總和,可能會出現資源爭用。這種情況按先到先得的原則處理。

啟用資源配額

資源配額支援在許多 Kubernetes 發行版中預設啟用。當API 伺服器--enable-admission-plugins= 標誌將 ResourceQuota 作為其引數之一時,它會被啟用。

當某個名稱空間中有 ResourceQuota 時,該名稱空間中的資源配額就會生效。

資源配額的型別

ResourceQuota 機制允許您強制執行不同型別的限制。本節介紹您可以強制執行的限制類型。

基礎設施資源配額

您可以限制給定名稱空間中可以請求的計算資源的總和。

支援以下資源型別:

資源名稱描述
limits.cpu在所有非終結狀態的 pod 中,CPU 限制的總和不能超過此值。
limits.memory在所有非終結狀態的 pod 中,記憶體限制的總和不能超過此值。
requests.cpu在所有非終結狀態的 pod 中,CPU 請求的總和不能超過此值。
requests.memory在所有非終結狀態的 pod 中,記憶體請求的總和不能超過此值。
hugepages-<size>在所有非終結狀態的 pod 中,指定大小的 huge page 請求數量不能超過此值。
cpurequests.cpu 相同
memoryrequests.memory 相同

擴充套件資源配額

除了上面提到的資源之外,在 1.10 版本中,還增加了對擴充套件資源的配額支援。

由於擴充套件資源不允許超額分配,因此在配額中為同一個擴充套件資源同時指定 requestslimits 沒有意義。因此,對於擴充套件資源,只允許帶有 requests. 字首的配額項。

以 GPU 資源為例,如果資源名稱是 nvidia.com/gpu,並且您想將名稱空間中請求的 GPU 總數限制為 4,則可以定義如下配額:

  • requests.nvidia.com/gpu: 4

有關更多詳細資訊,請參閱檢視和設定配額

儲存配額

您可以限制給定名稱空間中可以請求的卷儲存的總和。

此外,您可以根據關聯的StorageClass來限制儲存資源的消耗。

資源名稱描述
requests.storage在所有持久卷宣告中,儲存請求的總和不能超過此值。
persistentvolumeclaims名稱空間中可以存在的PersistentVolumeClaims的總數。
<storage-class-name>.storageclass.storage.k8s.io/requests.storage在所有與 <storage-class-name> 關聯的持久卷宣告中,儲存請求的總和不能超過此值。
<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims在所有與 <storage-class-name> 關聯的持久卷宣告中,名稱空間中可以存在的持久卷宣告的總數。

例如,如果您想單獨對 gold StorageClass 和 bronze StorageClass 的儲存進行配額,可以定義如下配額:

  • gold.storageclass.storage.k8s.io/requests.storage: 500Gi
  • bronze.storageclass.storage.k8s.io/requests.storage: 100Gi

本地臨時儲存配額

特性狀態: Kubernetes v1.8 [alpha]
資源名稱描述
requests.ephemeral-storage在名稱空間的所有 pod 中,本地臨時儲存請求的總和不能超過此值。
limits.ephemeral-storage在名稱空間的所有 pod 中,本地臨時儲存限制的總和不能超過此值。
ephemeral-storagerequests.ephemeral-storage 相同。

物件數量配額

您可以使用以下語法為 Kubernetes API 中一個特定資源型別設定配額:

  • count/<resource>.<group> 用於非核心 API 組的資源
  • count/<resource> 用於核心 API 組的資源

例如,PodTemplate API 屬於核心 API 組,因此如果您想限制名稱空間中 PodTemplate 物件的數量,則使用 count/podtemplates

這類配額有助於防止控制平面儲存耗盡。例如,您可能希望限制伺服器中 Secret 的數量,因為它們的體積很大。叢集中過多的 Secret 實際上會阻止伺服器和控制器啟動。您可以為 Jobs 設定配額,以防止配置錯誤的 CronJob。在名稱空間中建立過多 Jobs 的 CronJobs 可能導致拒絕服務。

如果以這種方式定義配額,它將應用於 API 伺服器的 Kubernetes API,以及由 CustomResourceDefinition 支援的任何自定義資源。例如,要對 example.com API 組中的 widgets 自定義資源設定配額,請使用 count/widgets.example.com。如果您使用API 聚合新增未定義為 CustomResourceDefinitions 的附加自定義 API,則核心 Kubernetes 控制平面不會強制執行對聚合 API 的配額。如果這對自定義 API 是合適的,擴充套件 API 伺服器將負責提供配額強制執行。

通用語法

以下是您可能希望使用物件數量配額進行管理的常見物件型別的示例列表,按您將使用的配置字串列出:

  • count/pods
  • count/persistentvolumeclaims
  • count/services
  • count/secrets
  • count/configmaps
  • count/deployments.apps
  • count/replicasets.apps
  • count/statefulsets.apps
  • count/jobs.batch
  • count/cronjobs.batch
專用語法

還有另一種語法,僅用於設定同一種類型的配額,該語法僅適用於某些 API 型別。支援以下型別:

資源名稱描述
configmaps名稱空間中可以存在的 ConfigMaps 的總數。
persistentvolumeclaims名稱空間中可以存在的PersistentVolumeClaims的總數。
Pod(pods)名稱空間中可以存在的非終結狀態 Pod 的總數。如果 .status.phase in (Failed, Succeeded) 為 true,則 pod 處於終結狀態。
replicationcontrollers名稱空間中可以存在的 ReplicationControllers 的總數。
resourcequotas名稱空間中可以存在的 ResourceQuotas 的總數。
服務(services)名稱空間中可以存在的 Services 的總數。
services.loadbalancers名稱空間中可以存在的 LoadBalancer 型別 Service 的總數。
services.nodeports分配給 NodePortLoadBalancer 型別 Service 的 NodePorts 在名稱空間中可用的總數。
secrets名稱空間中可以存在的 Secrets 的總數。

例如,pods 配額計算並強制執行單個名稱空間中建立的非終結 pod 的最大數量。您可能希望在名稱空間上設定 pods 配額,以避免使用者建立許多小型 pod 並耗盡叢集的 Pod IP 供應。

您可以在檢視和設定配額中找到更多示例。

配額範圍

每個配額都可以關聯一組 scopes。只有當資源與列舉範圍的交集匹配時,配額才會衡量該資源的用法。

當範圍新增到配額時,它會將支援的資源數量限制為與該範圍相關的資源。配額中指定的、超出允許範圍的資源會導致驗證錯誤。

範圍描述
Terminating匹配 .spec.activeDeadlineSeconds >= 0 的 Pod
NotTerminating匹配 .spec.activeDeadlineSecondsnil 的 Pod
BestEffort匹配具有最佳努力服務質量的 Pod。
NotBestEffort匹配不具有最佳努力服務質量的 Pod。
PriorityClass匹配引用指定優先順序類的 Pod。
CrossNamespacePodAffinity匹配具有跨名稱空間 Pod(反)親和性項的 Pod。
VolumeAttributesClass匹配引用指定卷屬性類的 PersistentVolumeClaims。

BestEffort 範圍將配額限制為跟蹤以下資源:

  • Pod(pods)

TerminatingNotTerminatingNotBestEffortPriorityClass 範圍將配額限制為跟蹤以下資源:

  • Pod(pods)
  • cpu
  • memory
  • requests.cpu
  • requests.memory
  • limits.cpu
  • limits.memory

請注意,您不能在同一個配額中同時指定 TerminatingNotTerminating 範圍,也不能在同一個配額中同時指定 BestEffortNotBestEffort 範圍。

scopeSelector 支援 operator 欄位中的以下值:

  • In
  • NotIn
  • Exists
  • DoesNotExist

當使用以下值之一作為 scopeName 來定義 scopeSelector 時,operator 必須是 Exists

  • Terminating
  • NotTerminating
  • BestEffort
  • NotBestEffort

如果 operatorInNotInvalues 欄位必須至少有一個值。例如:

  scopeSelector:
    matchExpressions:
      - scopeName: PriorityClass
        operator: In
        values:
          - middle

如果 operatorExistsDoesNotExist,則必須不指定 values 欄位。

按優先順序類劃分的資源配額

功能狀態: `Kubernetes v1.17 [穩定]`

Pod 可以以特定的優先順序建立。您可以透過在配額規範中使用 scopeSelector 欄位來根據 Pod 的優先順序控制其系統資源消耗。

只有當配額規範中的 scopeSelector 選擇該 Pod 時,才會匹配並消耗該配額。

當使用 scopeSelector 欄位為優先順序類設定配額範圍時,配額物件僅限於跟蹤以下資源:

  • Pod(pods)
  • cpu
  • memory
  • ephemeral-storage
  • limits.cpu
  • limits.memory
  • limits.ephemeral-storage
  • requests.cpu
  • requests.memory
  • requests.ephemeral-storage

此示例建立了一個配額物件,並將其與特定優先順序的 Pod 匹配。示例工作如下:

  • 叢集中的 Pod 具有“low”、“medium”、“high”三個優先順序類之一。
  • 為每個優先順序建立一個配額物件。

將以下 YAML 儲存到名為 quota.yaml 的檔案中。

apiVersion: v1
kind: List
items:
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: pods-high
  spec:
    hard:
      cpu: "1000"
      memory: "200Gi"
      pods: "10"
    scopeSelector:
      matchExpressions:
      - operator: In
        scopeName: PriorityClass
        values: ["high"]
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: pods-medium
  spec:
    hard:
      cpu: "10"
      memory: "20Gi"
      pods: "10"
    scopeSelector:
      matchExpressions:
      - operator: In
        scopeName: PriorityClass
        values: ["medium"]
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: pods-low
  spec:
    hard:
      cpu: "5"
      memory: "10Gi"
      pods: "10"
    scopeSelector:
      matchExpressions:
      - operator: In
        scopeName: PriorityClass
        values: ["low"]

使用 kubectl create 應用 YAML。

kubectl create -f ./quota.yaml
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created

使用 kubectl describe quota 驗證 Used 配額是否為 0

kubectl describe quota
Name:       pods-high
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     1k
memory      0     200Gi
pods        0     10


Name:       pods-low
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     5
memory      0     10Gi
pods        0     10


Name:       pods-medium
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     10
memory      0     20Gi
pods        0     10

建立具有“high”優先順序的 Pod。將以下 YAML 儲存到名為 high-priority-pod.yaml 的檔案中。

apiVersion: v1
kind: Pod
metadata:
  name: high-priority
spec:
  containers:
  - name: high-priority
    image: ubuntu
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello; sleep 10;done"]
    resources:
      requests:
        memory: "10Gi"
        cpu: "500m"
      limits:
        memory: "10Gi"
        cpu: "500m"
  priorityClassName: high

使用 kubectl create 應用。

kubectl create -f ./high-priority-pod.yaml

驗證“high”優先順序配額 pods-high 的“Used”統計資訊已更改,而其他兩個配額未更改。

kubectl describe quota
Name:       pods-high
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         500m  1k
memory      10Gi  200Gi
pods        1     10


Name:       pods-low
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     5
memory      0     10Gi
pods        0     10


Name:       pods-medium
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     10
memory      0     20Gi
pods        0     10

跨名稱空間 Pod 親和性配額

特性狀態: Kubernetes v1.24 [stable]

操作員可以使用 CrossNamespacePodAffinity 配額範圍來限制哪些名稱空間允許具有跨名稱空間親和性項的 pod。具體來說,它控制哪些 pod 允許在 pod 親和性項中設定 namespacesnamespaceSelector 欄位。

阻止使用者使用跨名稱空間親和性項可能是可取的,因為具有反親和性約束的 pod 會阻止來自所有其他名稱空間的 pod 在故障域中獲得排程。

使用此範圍,操作員可以透過在該名稱空間中建立具有 CrossNamespacePodAffinity 範圍和硬限制為 0 的資源配額物件來防止某些名稱空間(如下例中的 foo-ns)擁有使用跨名稱空間 Pod 親和性的 Pod。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: disable-cross-namespace-affinity
  namespace: foo-ns
spec:
  hard:
    pods: "0"
  scopeSelector:
    matchExpressions:
    - scopeName: CrossNamespacePodAffinity
      operator: Exists

如果操作員希望預設情況下禁止使用 namespacesnamespaceSelector,而只允許在特定名稱空間中使用,則可以透過將 kube-apiserver 標誌 --admission-control-config-file 設定為以下配置檔案的路徑來將 CrossNamespacePodAffinity 配置為受限資源:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
  configuration:
    apiVersion: apiserver.config.k8s.io/v1
    kind: ResourceQuotaConfiguration
    limitedResources:
    - resource: pods
      matchScopes:
      - scopeName: CrossNamespacePodAffinity
        operator: Exists

使用上述配置,只有當 pod 建立所在名稱空間具有 CrossNamespacePodAffinity 範圍且硬限制大於或等於使用這些欄位的 pod 數量的資源配額物件時,pod 才能使用 pod 親和性中的 namespacesnamespaceSelector

按 VolumeAttributesClass 劃分的資源配額

特性狀態: Kubernetes v1.34 [穩定] (預設啟用:true)

PersistentVolumeClaims 可以使用特定的卷屬性類建立,並且可以在建立後修改。您可以透過在配額規範中使用 scopeSelector 欄位,根據關聯的卷屬性類來控制 PVC 對儲存資源的消耗。

PVC 透過以下欄位引用關聯的卷屬性類:

  • spec.volumeAttributesClassName
  • status.currentVolumeAttributesClassName
  • status.modifyVolumeStatus.targetVolumeAttributesClassName

只有當配額規範中的 scopeSelector 選擇 PVC 時,才會匹配並消耗該配額。

當使用 scopeSelector 欄位為卷屬性類設定配額範圍時,配額物件僅限於跟蹤以下資源:

  • persistentvolumeclaims
  • requests.storage

此示例建立了一個配額物件,並將其與特定卷屬性類的 PVC 匹配。示例工作如下:

  • 叢集中的 PVC 至少具有“gold”、“silver”、“copper”三個卷屬性類之一。
  • 為每個卷屬性類建立一個配額物件。

將以下 YAML 儲存到名為 quota-vac.yaml 的檔案中。

apiVersion: v1
kind: List
items:
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: pvcs-gold
  spec:
    hard:
      requests.storage: "10Gi"
      persistentvolumeclaims: "10"
    scopeSelector:
      matchExpressions:
      - operator: In
        scopeName: VolumeAttributesClass
        values: ["gold"]
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: pvcs-silver
  spec:
    hard:
      requests.storage: "20Gi"
      persistentvolumeclaims: "10"
    scopeSelector:
      matchExpressions:
      - operator: In
        scopeName: VolumeAttributesClass
        values: ["silver"]
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: pvcs-copper
  spec:
    hard:
      requests.storage: "30Gi"
      persistentvolumeclaims: "10"
    scopeSelector:
      matchExpressions:
      - operator: In
        scopeName: VolumeAttributesClass
        values: ["copper"]

使用 kubectl create 應用 YAML。

kubectl create -f ./quota-vac.yaml
resourcequota/pvcs-gold created
resourcequota/pvcs-silver created
resourcequota/pvcs-copper created

使用 kubectl describe quota 驗證 Used 配額是否為 0

kubectl describe quota
Name:                   pvcs-gold
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     10Gi


Name:                   pvcs-silver
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     20Gi


Name:                   pvcs-copper
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     30Gi

建立一個具有“gold”卷屬性類的 pvc。將以下 YAML 儲存到名為 gold-vac-pvc.yaml 的檔案中。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gold-vac-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  storageClassName:  # change this to the name of the storage class you want to use
  volumeAttributesClassName: gold

使用 kubectl create 應用。

kubectl create -f ./gold-vac-pvc.yaml

驗證“gold”卷屬性類配額 pvcs-gold 的“Used”統計資訊已更改,而其他兩個配額未更改。

kubectl describe quota
Name:                   pvcs-gold
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   10Gi


Name:                   pvcs-silver
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     20Gi


Name:                   pvcs-copper
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     30Gi

PVC 繫結後,允許修改所需的卷屬性類。讓我們使用 kubectl patch 將其更改為“silver”。

kubectl patch pvc gold-vac-pvc --type='merge' -p '{"spec":{"volumeAttributesClassName":"silver"}}'

驗證“silver”卷屬性類配額 pvcs-silver 的“Used”統計資訊已更改,pvcs-copper 未更改,而 pvcs-gold 可能未更改或已釋放,具體取決於 PVC 的狀態。

kubectl describe quota
Name:                   pvcs-gold
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   10Gi


Name:                   pvcs-silver
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   20Gi


Name:                   pvcs-copper
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     30Gi

讓我們使用 kubectl patch 將其更改為“copper”。

kubectl patch pvc gold-vac-pvc --type='merge' -p '{"spec":{"volumeAttributesClassName":"copper"}}'

驗證“copper”卷屬性類配額 pvcs-copper 的“Used”統計資訊已更改,pvcs-silverpvcs-gold 可能未更改或已釋放,具體取決於 PVC 的狀態。

kubectl describe quota
Name:                   pvcs-gold
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   10Gi


Name:                   pvcs-silver
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   20Gi


Name:                   pvcs-copper
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   30Gi

使用以下命令列印 PVC 的清單。

kubectl get pvc gold-vac-pvc -o yaml

它可能顯示以下輸出:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gold-vac-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  storageClassName: default
  volumeAttributesClassName: copper
status:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 2Gi
  currentVolumeAttributesClassName: gold
  phase: Bound
  modifyVolumeStatus:
    status: InProgress
    targetVolumeAttributesClassName: silver
  storageClassName: default

稍等片刻,卷修改完成後,再次驗證配額。

kubectl describe quota
Name:                   pvcs-gold
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     10Gi


Name:                   pvcs-silver
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     10
requests.storage        0     20Gi


Name:                   pvcs-copper
Namespace:              default
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  1     10
requests.storage        2Gi   30Gi

請求與限制的比較

在分配計算資源時,每個容器都可以為 CPU 或記憶體指定請求和限制值。配額可以配置為配額任一值。

如果配額為 requests.cpurequests.memory 指定了值,那麼它要求每個傳入的容器都明確請求這些資源。如果配額為 limits.cpulimits.memory 指定了值,那麼它要求每個傳入的容器都明確指定這些資源的限制。

檢視和設定配額

kubectl 支援建立、更新和檢視配額。

kubectl create namespace myspace
cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
spec:
  hard:
    requests.cpu: "1"
    requests.memory: "1Gi"
    limits.cpu: "2"
    limits.memory: "2Gi"
    requests.nvidia.com/gpu: 4
EOF
kubectl create -f ./compute-resources.yaml --namespace=myspace
cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-counts
spec:
  hard:
    configmaps: "10"
    persistentvolumeclaims: "4"
    pods: "4"
    replicationcontrollers: "20"
    secrets: "10"
    services: "10"
    services.loadbalancers: "2"
EOF
kubectl create -f ./object-counts.yaml --namespace=myspace
kubectl get quota --namespace=myspace
NAME                    AGE
compute-resources       30s
object-counts           32s
kubectl describe quota compute-resources --namespace=myspace
Name:                    compute-resources
Namespace:               myspace
Resource                 Used  Hard
--------                 ----  ----
limits.cpu               0     2
limits.memory            0     2Gi
requests.cpu             0     1
requests.memory          0     1Gi
requests.nvidia.com/gpu  0     4
kubectl describe quota object-counts --namespace=myspace
Name:                   object-counts
Namespace:              myspace
Resource                Used    Hard
--------                ----    ----
configmaps              0       10
persistentvolumeclaims  0       4
pods                    0       4
replicationcontrollers  0       20
secrets                 1       10
services                0       10
services.loadbalancers  0       2

kubectl 還支援所有標準名稱空間資源的物件數量配額,使用語法 count/<resource>.<group>

kubectl create namespace myspace
kubectl create quota test --hard=count/deployments.apps=2,count/replicasets.apps=4,count/pods=3,count/secrets=4 --namespace=myspace
kubectl create deployment nginx --image=nginx --namespace=myspace --replicas=2
kubectl describe quota --namespace=myspace
Name:                         test
Namespace:                    myspace
Resource                      Used  Hard
--------                      ----  ----
count/deployments.apps        1     2
count/pods                    2     3
count/replicasets.apps        1     4
count/secrets                 1     4

配額與叢集容量

ResourceQuotas 與叢集容量無關。它們以絕對單位表示。因此,如果您向叢集新增節點,這不會自動使每個名稱空間消耗更多資源的能力。

有時可能需要更復雜的策略,例如:

  • 在多個團隊之間按比例分配叢集總資源。
  • 允許每個租戶按需增長資源使用量,但設定一個慷慨的限制以防止意外的資源耗盡。
  • 檢測一個名稱空間的需求,新增節點,並增加配額。

這些策略可以作為構建塊使用 ResourceQuotas 來實現,透過編寫一個“控制器”來監視配額使用情況並根據其他訊號調整每個名稱空間的配額硬限制。

請注意,資源配額分割了叢集的總資源,但它沒有對節點施加限制:來自多個名稱空間的 pod 可能會執行在同一個節點上。

預設限制優先順序類消耗

可能需要允許特定優先順序(例如“cluster-services”)的 pod 在某個名稱空間中存在,前提是存在匹配的配額物件。

透過這種機制,操作員能夠將某些高優先順序類的使用限制為有限數量的名稱空間,而不是每個名稱空間預設都能消耗這些優先順序類。

為實現此目的,應使用 kube-apiserver 標誌 --admission-control-config-file 來傳遞以下配置檔案的路徑:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
  configuration:
    apiVersion: apiserver.config.k8s.io/v1
    kind: ResourceQuotaConfiguration
    limitedResources:
    - resource: pods
      matchScopes:
      - scopeName: PriorityClass
        operator: In
        values: ["cluster-services"]

然後,在 kube-system 名稱空間中建立一個資源配額物件:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: pods-cluster-services
spec:
  scopeSelector:
    matchExpressions:
      - operator : In
        scopeName: PriorityClass
        values: ["cluster-services"]
kubectl apply -f https://k8s.io/examples/policy/priority-class-resourcequota.yaml -n kube-system
resourcequota/pods-cluster-services created

在這種情況下,pod 建立將被允許,如果:

  1. Pod 的 priorityClassName 未指定。
  2. Pod 的 priorityClassName 被指定為 cluster-services 以外的值。
  3. Pod 的 priorityClassName 被設定為 cluster-services,它將在 kube-system 名稱空間中建立,並且它已透過資源配額檢查。

如果 Pod 的 priorityClassName 被設定為 cluster-services 並且它將在 kube-system 以外的名稱空間中建立,則 Pod 建立請求將被拒絕。

下一步

最後修改日期:2025 年 8 月 13 日下午 1:13 PST:更新資源配額文件連結 (47b7523d29)