掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
當多個用戶或團隊共享具有固定節(jié)點數(shù)目的集群時,人們會擔心有人使用超過其基于公平原則所分配到的資源量。

資源配額是幫助管理員解決這一問題的工具。
資源配額,通過 ?ResourceQuota ?對象來定義,對每個命名空間的資源消耗總量提供限制。 它可以限制命名空間中某種類型的對象的總數(shù)目上限,也可以限制命令空間中的 Pod 可以使用的計算資源的總上限。
資源配額的工作方式如下:
cpu ?和 ?memory?)的配額被啟用,則用戶必須為 這些資源設(shè)定請求值(request)和約束值(limit),否則配額系統(tǒng)將拒絕 Pod 的創(chuàng)建。 提示: 可使用 ?LimitRanger ?準入控制器來為沒有設(shè)置計算資源需求的 Pod 設(shè)置默認值。ResourceQuota 對象的名稱必須是合法的 DNS 子域名。
下面是使用命名空間和配額構(gòu)建策略的示例:
在集群容量小于各命名空間配額總和的情況下,可能存在資源競爭。資源競爭時,Kubernetes 系統(tǒng)會遵循先到先得的原則。
不管是資源競爭還是配額的修改,都不會影響已經(jīng)創(chuàng)建的資源使用對象。
資源配額的支持在很多 Kubernetes 版本中是默認啟用的。 當 API 服務(wù)器 的命令行標志 ?--enable-admission-plugins=? 中包含 ?ResourceQuota ?時, 資源配額會被啟用。
當命名空間中存在一個 ResourceQuota 對象時,對于該命名空間而言,資源配額就是開啟的。
用戶可以對給定命名空間下的可被請求的 計算資源 總量進行限制。
配額機制所支持的資源類型:
| 資源名稱 | 描述 |
|---|---|
limits.cpu | 所有非終止狀態(tài)的 Pod,其 CPU 限額總量不能超過該值。 |
limits.memory | 所有非終止狀態(tài)的 Pod,其內(nèi)存限額總量不能超過該值。 |
requests.cpu | 所有非終止狀態(tài)的 Pod,其 CPU 需求總量不能超過該值。 |
requests.memory | 所有非終止狀態(tài)的 Pod,其內(nèi)存需求總量不能超過該值。 |
hugepages- | 對于所有非終止狀態(tài)的 Pod,針對指定尺寸的巨頁請求總數(shù)不能超過此值。 |
cpu | 與 requests.cpu 相同。 |
memory | 與 requests.memory 相同。 |
除上述資源外,在 Kubernetes 1.10 版本中,還添加了對 擴展資源 的支持。
由于擴展資源不可超量分配,因此沒有必要在配額中為同一擴展資源同時指定 ?requests ?和 ?limits?。 對于擴展資源而言,目前僅允許使用前綴為 ?requests.? 的配額項。
以 GPU 拓展資源為例,如果資源名稱為 ?nvidia.com/gpu?,并且要將命名空間中請求的 GPU 資源總數(shù)限制為 4,則可以如下定義配額:
requests.nvidia.com/gpu: 4 ?用戶可以對給定命名空間下的存儲資源 總量進行限制。
此外,還可以根據(jù)相關(guān)的存儲類(Storage Class)來限制存儲資源的消耗。
| 資源名稱 | 描述 |
|---|---|
requests.storage | 所有 PVC,存儲資源的需求總量不能超過該值。 |
persistentvolumeclaims | 在該命名空間中所允許的 PVC 總量。 |
| 在所有與 相關(guān)的持久卷申領(lǐng)中,存儲請求的總和不能超過該值。 |
| 在與 storage-class-name 相關(guān)的所有持久卷申領(lǐng)中,命名空間中可以存在的持久卷申領(lǐng)總數(shù)。 |
例如,如果一個操作人員針對 ?gold ?存儲類型與 ?bronze ?存儲類型設(shè)置配額, 操作人員可以定義如下配額:
gold.storageclass.storage.k8s.io/requests.storage: 500Gi ?bronze.storageclass.storage.k8s.io/requests.storage: 100Gi?在 Kubernetes 1.8 版本中,本地臨時存儲的配額支持已經(jīng)是 Alpha 功能:
| 資源名稱 | 描述 |
|---|---|
requests.ephemeral-storage | 在命名空間的所有 Pod 中,本地臨時存儲請求的總和不能超過此值。 |
limits.ephemeral-storage | 在命名空間的所有 Pod 中,本地臨時存儲限制值的總和不能超過此值。 |
ephemeral-storage | 與 requests.ephemeral-storage 相同。 |
Note:
如果所使用的是 CRI 容器運行時,容器日志會被計入臨時存儲配額。 這可能會導(dǎo)致存儲配額耗盡的 Pods 被意外地驅(qū)逐出節(jié)點。
你可以使用以下語法對所有標準的、命名空間域的資源類型進行配額設(shè)置:
count/. ?:用于非核心(core)組的資源count/?:用于核心組的資源這是用戶可能希望利用對象計數(shù)配額來管理的一組資源示例。
count/persistentvolumeclaims ?count/services ?count/secrets ?count/configmaps ?count/replicationcontrollers ?count/deployments.apps ?count/replicasets.apps ?count/statefulsets.apps ?count/jobs.batch ?count/cronjobs.batch?相同語法也可用于自定義資源。 例如,要對 ?example.com? API 組中的自定義資源 ?widgets ?設(shè)置配額,請使用 ?count/widgets.example.com?。
當使用 ?count/*? 資源配額時,如果對象存在于服務(wù)器存儲中,則會根據(jù)配額管理資源。 這些類型的配額有助于防止存儲資源耗盡。例如,用戶可能想根據(jù)服務(wù)器的存儲能力來對服務(wù)器中 Secret 的數(shù)量進行配額限制。 集群中存在過多的 Secret 實際上會導(dǎo)致服務(wù)器和控制器無法啟動。 用戶可以選擇對 Job 進行配額管理,以防止配置不當?shù)?nbsp;CronJob 在某命名空間中創(chuàng)建太多 Job 而導(dǎo)致集群拒絕服務(wù)。
對有限的一組資源上實施一般性的對象數(shù)量配額也是可能的。 此外,還可以進一步按資源的類型設(shè)置其配額。
支持以下類型:
| 資源名稱 | 描述 |
|---|---|
configmaps | 在該命名空間中允許存在的 ConfigMap 總數(shù)上限。 |
persistentvolumeclaims | 在該命名空間中允許存在的 PVC 的總數(shù)上限。 |
pods | 在該命名空間中允許存在的非終止狀態(tài)的 Pod 總數(shù)上限。Pod 終止狀態(tài)等價于 Pod 的 .status.phase in (Failed, Succeeded) 為真。 |
replicationcontrollers | 在該命名空間中允許存在的 ReplicationController 總數(shù)上限。 |
resourcequotas | 在該命名空間中允許存在的 ResourceQuota 總數(shù)上限。 |
services | 在該命名空間中允許存在的 Service 總數(shù)上限。 |
services.loadbalancers | 在該命名空間中允許存在的 LoadBalancer 類型的 Service 總數(shù)上限。 |
services.nodeports | 在該命名空間中允許存在的 NodePort 類型的 Service 總數(shù)上限。 |
secrets | 在該命名空間中允許存在的 Secret 總數(shù)上限。 |
例如,?pods ?配額統(tǒng)計某個命名空間中所創(chuàng)建的、非終止狀態(tài)的 ?Pod ?個數(shù)并確保其不超過某上限值。 用戶可能希望在某命名空間中設(shè)置 ?pods ?配額,以避免有用戶創(chuàng)建很多小的 Pod, 從而耗盡集群所能提供的 Pod IP 地址。
每個配額都有一組相關(guān)的 ?scope?(作用域),配額只會對作用域內(nèi)的資源生效。 配額機制僅統(tǒng)計所列舉的作用域的交集中的資源用量。
當一個作用域被添加到配額中后,它會對作用域相關(guān)的資源數(shù)量作限制。 如配額中指定了允許(作用域)集合之外的資源,會導(dǎo)致驗證錯誤。
| 作用域 | 描述 |
|---|---|
Terminating | 匹配所有 spec.activeDeadlineSeconds 不小于 0 的 Pod。 |
NotTerminating | 匹配所有 spec.activeDeadlineSeconds 是 nil 的 Pod。 |
BestEffort | 匹配所有 Qos 是 BestEffort 的 Pod。 |
NotBestEffort | 匹配所有 Qos 不是 BestEffort 的 Pod。 |
PriorityClass | 匹配所有引用了所指定的優(yōu)先級類的 Pods。 |
CrossNamespacePodAffinity | 匹配那些設(shè)置了跨名字空間 (反)親和性條件的 Pod。 |
?BestEffort ?作用域限制配額跟蹤以下資源:
pods ??Terminating?、?NotTerminating?、?NotBestEffort ?和 ?PriorityClass ?這些作用域限制配額跟蹤以下資源:
pods ?cpu ?memory ?requests.cpu ?requests.memory ?limits.cpu ?limits.memory?需要注意的是,你不可以在同一個配額對象中同時設(shè)置 ?Terminating ?和 ?NotTerminating ?作用域,你也不可以在同一個配額中同時設(shè)置 ?BestEffort ?和 ?NotBestEffort ?作用域。
?scopeSelector ?支持在 ?operator ?字段中使用以下值:
In ?NotIn ?Exists ?DoesNotExist?定義 ?scopeSelector ?時,如果使用以下值之一作為 ?scopeName ?的值,則對應(yīng)的 ?operator ?只能是 ?Exists?。
Terminating ?NotTerminating ?BestEffort ?NotBestEffort?如果 ?operator ?是 ?In ?或 ?NotIn ?之一,則 ?values ?字段必須至少包含一個值。 例如:
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values:
- middle如果 ?operator ?為 ?Exists ?或 ?DoesNotExist?,則不可以設(shè)置 ?values ?字段。
FEATURE STATE: Kubernetes v1.17 [stable]
Pod 可以創(chuàng)建為特定的優(yōu)先級。 通過使用配額規(guī)約中的 ?scopeSelector ?字段,用戶可以根據(jù) Pod 的優(yōu)先級控制其系統(tǒng)資源消耗。
僅當配額規(guī)范中的 ?scopeSelector ?字段選擇到某 Pod 時,配額機制才會匹配和計量 Pod 的資源消耗。
如果配額對象通過 ?scopeSelector ?字段設(shè)置其作用域為優(yōu)先級類,則配額對象只能 跟蹤以下資源:
pods ?cpu ?memory ?ephemeral-storage ?limits.cpu ?limits.memory ?limits.ephemeral-storage ?requests.cpu ?requests.memory ?requests.ephemeral-storage?本示例創(chuàng)建一個配額對象,并將其與具有特定優(yōu)先級的 Pod 進行匹配。 該示例的工作方式如下:
將以下 YAML 保存到文件 ?quota.yml? 中。
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? 命令運行以下操作。
kubectl create -f ./quota.yml
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創(chuàng)建優(yōu)先級為 "high" 的 Pod。 將以下 YAML 保存到文件 ?high-priority-pod.yml? 中。
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.yml
確認 "high" 優(yōu)先級配額 ?pods-high? 的 "Used" 統(tǒng)計信息已更改,并且其他兩個配額未更改。
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
FEATURE STATE: Kubernetes v1.24 [stable]
集群運維人員可以使用 ?CrossNamespacePodAffinity ?配額作用域來 限制哪個名字空間中可以存在包含跨名字空間親和性規(guī)則的 Pod。 更為具體一點,此作用域用來配置哪些 Pod 可以在其 Pod 親和性規(guī)則 中設(shè)置 ?namespaces ?或 ?namespaceSelector ?字段。
禁止用戶使用跨名字空間的親和性規(guī)則可能是一種被需要的能力,因為帶有 反親和性約束的 Pod 可能會阻止所有其他名字空間的 Pod 被調(diào)度到某失效域中。
使用此作用域操作符可以避免某些名字空間(例如下面例子中的 ?foo-ns?)運行 特別的 Pod,這類 Pod 使用跨名字空間的 Pod 親和性約束,在該名字空間中創(chuàng)建 了作用域為 ?CrossNamespaceAffinity ?的、硬性約束為 0 的資源配額對象。
apiVersion: v1
kind: ResourceQuota
metadata:
name: disable-cross-namespace-affinity
namespace: foo-ns
spec:
hard:
pods: "0"
scopeSelector:
matchExpressions:
- scopeName: CrossNamespaceAffinity如果集群運維人員希望默認禁止使用 ?namespaces ?和 ?namespaceSelector?,而 僅僅允許在特定名字空間中這樣做,他們可以將 ?CrossNamespaceAffinity ?作為一個 被約束的資源。方法是為 ?kube-apiserver? 設(shè)置標志 ?--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: CrossNamespaceAffinity基于上面的配置,只有名字空間中包含作用域為 ?CrossNamespaceAffinity ?且 硬性約束大于或等于使用 ?namespaces ?和 ?namespaceSelector ?字段的 Pods 個數(shù)時,才可以在該名字空間中繼續(xù)創(chuàng)建在其 Pod 親和性規(guī)則中設(shè)置 ?namespaces ?或 ?namespaceSelector ?的新 Pod。
分配計算資源時,每個容器可以為 CPU 或內(nèi)存指定請求和約束。 配額可以針對二者之一進行設(shè)置。
如果配額中指定了 ?requests.cpu? 或 ?requests.memory? 的值,則它要求每個容器都顯式給出對這些資源的請求。 同理,如果配額中指定了 ?limits.cpu? 或 ?limits.memory? 的值,那么它要求每個容器都顯式設(shè)定對應(yīng)資源的限制。
Kubectl 支持創(chuàng)建、更新和查看配額:
kubectl create namespace myspace
cat < 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 < 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 2kubectl 還使用語法 ?count/? 支持所有標準的、命名空間域的資源的對象計數(shù)配額:
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
ResourceQuota 與集群資源總量是完全獨立的。它們通過絕對的單位來配置。 所以,為集群添加節(jié)點時,資源配額不會自動賦予每個命名空間消耗更多資源的能力。
有時可能需要資源配額支持更復(fù)雜的策略,比如:
這些策略可以通過將資源配額作為一個組成模塊、手動編寫一個控制器來監(jiān)控資源使用情況, 并結(jié)合其他信號調(diào)整命名空間上的硬性資源配額來實現(xiàn)。
注意:資源配額對集群資源總體進行劃分,但它對節(jié)點沒有限制:來自不同命名空間的 Pod 可能在同一節(jié)點上運行。
有時候可能希望當且僅當某名字空間中存在匹配的配額對象時,才可以創(chuàng)建特定優(yōu)先級 (例如 "cluster-services")的 Pod。
通過這種機制,操作人員能夠?qū)⑾拗颇承└邇?yōu)先級類僅出現(xiàn)在有限數(shù)量的命名空間中, 而并非每個命名空間默認情況下都能夠使用這些優(yōu)先級類。
要實現(xiàn)此目的,應(yīng)設(shè)置 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"]現(xiàn)在在 ?kube-system? 名字空間中創(chuàng)建一個資源配額對象:
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
在這里,當以下條件滿足時可以創(chuàng)建 Pod:
priorityClassName ?priorityClassName ?設(shè)置值不是 ?cluster-services ?priorityClassName ?設(shè)置值為 ?cluster-services?,它將被創(chuàng)建于 ?kube-system? 名字空間中,并且它已經(jīng)通過了資源配額檢查。 如果 Pod 的 ?priorityClassName ?設(shè)置為 ?cluster-services?,但要被創(chuàng)建到 ?kube-system? 之外的別的名字空間,則 Pod 創(chuàng)建請求也被拒絕。

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流