资源配额
当多个用户或团队共享一个节点数量固定的集群时,他们可能会担心某个团队使用的资源会超过其应得的份额。
资源配额是管理员解决这个担忧的工具。
资源配额由一个 ResourceQuota
对象定义,它提供了限制每个命名空间总资源消耗的约束。它可以按类型限制可在命名空间中创建的对象数量,以及该命名空间中资源可能消耗的计算资源总量。
资源配额工作原理如下
不同的团队在不同的命名空间中工作。这可以通过 RBAC 来强制执行。
管理员为每个命名空间创建一个 ResourceQuota。
用户在命名空间中创建资源(Pod、Service 等),配额系统跟踪资源使用情况,以确保它不超过 ResourceQuota 中定义的硬性资源限制。
如果创建或更新资源违反了配额约束,该请求将以 HTTP 状态码
403 FORBIDDEN
失败,并伴随一条消息解释被违反的约束。如果在命名空间中为
cpu
和memory
等计算资源启用了配额,用户必须为这些值指定请求或限制;否则,配额系统可能会拒绝 Pod 创建。提示:使用LimitRanger
准入控制器为未提出计算资源需求的 Pod 强制设定默认值。参阅演练,了解如何避免此问题的示例。
注意
- 对于
cpu
和memory
资源,ResourceQuota 会强制要求该命名空间中的每个(新建)Pod 都为其设置一个限制。如果你在命名空间中对cpu
或memory
强制执行资源配额,你和其他客户端在提交每个新 Pod 时必须指定该资源的requests
或limits
。如果你不这样做,控制平面可能会拒绝该 Pod 的准入。 - 对于其他资源:ResourceQuota 工作正常,并将忽略命名空间中未为此类资源设置限制或请求的 Pod。这意味着如果资源配额限制了该命名空间的临时存储,你仍然可以创建一个未设置临时存储限制/请求的新 Pod。
你可以使用 LimitRange 为这些资源自动设置默认的请求值。
ResourceQuota 对象的名称必须是合法的 DNS 子域名。
可以使用命名空间和配额创建的策略示例如下:
- 在一个容量为 32 GiB RAM 和 16 核的集群中,让团队 A 使用 20 GiB 和 10 核,团队 B 使用 10 GiB 和 4 核,并保留 2 GiB 和 2 核以备将来分配。
- 将“testing”命名空间的资源使用限制为 1 核和 1 GiB RAM。允许“production”命名空间使用任意数量的资源。
在集群总容量小于命名空间配额总和的情况下,可能会出现资源争用。这种情况按照先到先得的原则处理。
资源争用和配额变更都不会影响已经创建的资源。
启用资源配额
对于许多 Kubernetes 发行版,ResourceQuota 支持默认是启用的。当 API 服务器 的 --enable-admission-plugins=
标志的参数之一包含 ResourceQuota
时,该功能就被启用。
当命名空间中存在 ResourceQuota 对象时,资源配额在该特定命名空间中强制执行。
计算资源配额
你可以限制在给定命名空间中可以请求的计算资源总量。
支持以下资源类型:
资源名称 | 描述 |
---|---|
limits.cpu | 在所有非终止状态的 Pod 中,CPU limits 的总和不能超过此值。 |
limits.memory | 在所有非终止状态的 Pod 中,memory limits 的总和不能超过此值。 |
requests.cpu | 在所有非终止状态的 Pod 中,CPU requests 的总和不能超过此值。 |
requests.memory | 在所有非终止状态的 Pod 中,memory requests 的总和不能超过此值。 |
hugepages-<size> | 在所有非终止状态的 Pod 中,指定大小的 huge page 请求数量不能超过此值。 |
cpu | 与 requests.cpu 相同 |
memory | 与 requests.memory 相同 |
扩展资源的资源配额
除了上面提到的资源外,在 1.10 版本中增加了对扩展资源的配额支持。
由于扩展资源不允许过度承诺 (overcommit),因此在配额中为同一扩展资源同时指定 requests
和 limits
没有意义。因此,对于扩展资源,只允许带有 requests.
前缀的配额项。
以 GPU 资源为例,如果资源名称是 nvidia.com/gpu
,并且你想将命名空间中请求的 GPU 总数限制为 4,可以按如下方式定义配额:
requests.nvidia.com/gpu: 4
参阅查看和设置配额了解更多详情。
存储资源配额
你可以限制在给定命名空间中可以请求的存储资源总量。
此外,你还可以根据相关的 StorageClass 限制存储资源的消耗。
资源名称 | 描述 |
---|---|
requests.storage | 在所有 PersistentVolumeClaim 中,存储请求的总和不能超过此值。 |
persistentvolumeclaims | 可在命名空间中存在的PersistentVolumeClaims 总数。 |
<storage-class-name>.storageclass.storage.k8s.io/requests.storage | 与 <storage-class-name> 相关的所有 PersistentVolumeClaim 中,存储请求的总和不能超过此值。 |
<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims | 与 <storage-class-name> 相关的所有 PersistentVolumeClaim 中,可在命名空间中存在的PersistentVolumeClaim 总数。 |
例如,如果你想将使用 gold
StorageClass 的存储与使用 bronze
StorageClass 的存储分开配额,可以按如下方式定义配额:
gold.storageclass.storage.k8s.io/requests.storage: 500Gi
bronze.storageclass.storage.k8s.io/requests.storage: 100Gi
在 1.8 版本中,对本地临时存储的配额支持作为 Alpha 特性添加
资源名称 | 描述 |
---|---|
requests.ephemeral-storage | 在命名空间中的所有 Pod 中,本地临时存储请求的总和不能超过此值。 |
limits.ephemeral-storage | 在命名空间中的所有 Pod 中,本地临时存储 limits 的总和不能超过此值。 |
ephemeral-storage | 与 requests.ephemeral-storage 相同。 |
注意
使用 CRI 容器运行时时,容器日志会占用临时存储配额。这可能导致耗尽存储配额的 Pod 被意外逐出。有关详细信息,请参阅日志架构。对象数量配额
可以使用以下语法为 Kubernetes API 中某个特定资源类型的对象总数设置配额:
count/<resource>.<group>
用于非核心组中的资源count/<resource>
用于核心组中的资源
以下是用户可能希望纳入对象数量配额控制的资源示例集:
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
如果你通过这种方式定义配额,它适用于作为 API 服务器一部分的 Kubernetes API,以及由 CustomResourceDefinition 支持的任何自定义资源。如果你使用API 聚合来添加未定义为 CustomResourceDefinition 的额外自定义 API,核心 Kubernetes 控制平面不会对聚合的 API 强制执行配额。如果自定义 API 适合,则期望扩展 API 服务器提供配额强制执行。例如,要在 example.com
API 组中对 widgets
自定义资源创建配额,请使用 count/widgets.example.com
。
使用这种资源配额(几乎适用于所有对象类型)时,如果对象类型在控制平面中存在(已定义),则该对象会被计入配额。这类配额对于防止存储资源耗尽非常有用。例如,考虑到 Secrets 的大小较大,你可能希望限制服务器中 Secrets 的数量。集群中过多的 Secrets 实际上会阻止服务器和控制器启动。你可以为 Job 设置配额,以防止配置不当的 CronJob。在命名空间中创建过多 Job 的 CronJob 可能导致拒绝服务。
还有另一种语法,仅用于为某些特定资源设置相同类型的配额。支持以下类型:
资源名称 | 描述 |
---|---|
configmaps | 可在命名空间中存在的 ConfigMaps 总数。 |
persistentvolumeclaims | 可在命名空间中存在的PersistentVolumeClaims 总数。 |
pods | 可在命名空间中存在的非终止状态的 Pod 总数。如果 .status.phase in (Failed, Succeeded) 为真,则 Pod 处于终止状态。 |
replicationcontrollers | 可在命名空间中存在的 ReplicationControllers 总数。 |
resourcequotas | 可在命名空间中存在的 ResourceQuotas 总数。 |
services | 可在命名空间中存在的 Services 总数。 |
services.loadbalancers | 可在命名空间中存在的类型为 LoadBalancer 的 Services 总数。 |
services.nodeports | 可在命名空间中存在的分配给类型为 NodePort 或 LoadBalancer 的 Services 的 NodePort 总数。 |
secrets | 可在命名空间中存在的 Secrets 总数。 |
例如,pods
配额统计并强制执行单个命名空间中创建的非终止状态 pods
的最大数量。你可能希望对命名空间设置 pods
配额,以避免用户创建许多小型 Pod 并耗尽集群的 Pod IP 供应的情况。
你可以在查看和设置配额中找到更多示例。
配额范围
每个配额都可以有一组相关的 scopes
。配额仅在匹配所列范围的交集时才会衡量资源的用量。
当一个范围被添加到配额中时,它将配额支持的资源数量限制在与该范围相关的那些资源上。在配额中指定的资源如果超出允许的集合,将导致验证错误。
范围 | 描述 |
---|---|
Terminating | 匹配 .spec.activeDeadlineSeconds >= 0 的 Pod |
NotTerminating | 匹配 .spec.activeDeadlineSeconds 为 nil 的 Pod |
BestEffort | 匹配服务质量为 BestEffort 的 Pod。 |
NotBestEffort | 匹配服务质量不为 BestEffort 的 Pod。 |
PriorityClass | 匹配引用了指定优先级类的 Pod。 |
CrossNamespacePodAffinity | 匹配具有跨命名空间 Pod (反)亲和性条目的 Pod。 |
VolumeAttributesClass | 匹配引用了指定卷属性类的 PersistentVolumeClaim。 |
BestEffort
范围将配额限制为跟踪以下资源:
pods
Terminating
、NotTerminating
、NotBestEffort
和 PriorityClass
范围将配额限制为跟踪以下资源:
pods
cpu
memory
requests.cpu
requests.memory
limits.cpu
limits.memory
请注意,你不能在同一个配额中同时指定 Terminating
和 NotTerminating
范围,也不能同时指定 BestEffort
和 NotBestEffort
范围。
scopeSelector
在 operator
字段中支持以下值:
In
NotIn
Exists
DoesNotExist
在定义 scopeSelector
时,如果使用以下值之一作为 scopeName
,则 operator
必须是 Exists
。
Terminating
NotTerminating
BestEffort
NotBestEffort
如果 operator
是 In
或 NotIn
,则 values
字段必须至少包含一个值。例如:
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values:
- middle
如果 operator
是 Exists
或 DoesNotExist
,则 不得 指定 values
字段。
每个 PriorityClass 的资源配额
Kubernetes v1.17 [stable]
Pod 可以创建时指定优先级。你可以通过在配额规约中使用 scopeSelector
字段,根据 Pod 的优先级控制 Pod 对系统资源的消耗。
配额只有在配额规约中的 scopeSelector
选择了该 Pod 时才匹配并被消耗。
当使用 scopeSelector
字段将配额限制在优先级类范围时,配额对象仅限于跟踪以下资源:
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 亲和性条目中设置 namespaces
或 namespaceSelector
字段。
可能需要阻止用户使用跨命名空间亲和性条目,因为具有反亲和性约束的 Pod 可能会阻止来自所有其他命名空间的 Pod 在故障域中被调度。
通过在此范围中创建一个 ResourceQuota 对象,将其范围设为 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
如果操作员想默认禁止使用 namespaces
和 namespaceSelector
,仅允许特定命名空间使用,则可以通过将 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 亲和性中使用 namespaces
和 namespaceSelector
。
每个 VolumeAttributesClass 的资源配额
Kubernetes v1.31 [beta]
(默认禁用)PersistentVolumeClaim 可以创建时指定特定的卷属性类,并在创建后可能被修改。你可以通过在配额规约中使用 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-silver
和 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 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
Requests 与 Limits 对比
在分配计算资源时,每个容器可以为 CPU 或内存指定一个请求值和一个限制值。配额可以配置为对任一值生效。
如果配额为 requests.cpu
或 requests.memory
指定了值,则要求每个进入的容器明确请求这些资源。如果配额为 limits.cpu
或 limits.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
作为构建块来实现此类策略,具体方法是编写一个“控制器”,该控制器监控配额使用情况并根据其他信号调整每个命名空间的配额硬限制。
请注意,资源配额划分了集群总资源,但它对节点没有施加限制:来自多个命名空间的 Pods 可以运行在同一个节点上。
默认限制优先级类 (Priority Class) 的使用
可能需要,只有当存在一个匹配的配额对象时,才允许具有特定优先级(例如 "cluster-services")的 Pods 进入某个命名空间。
通过此机制,运维人员能够将某些高优先级类的使用限制在有限数量的命名空间内,并且默认情况下不是每个命名空间都能使用这些优先级类。
为了强制执行此操作,应使用 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:
- Pod 的
priorityClassName
未指定。 - Pod 的
priorityClassName
指定的值不是cluster-services
。 - Pod 的
priorityClassName
被设置为cluster-services
,并且它将在kube-system
命名空间中创建,并且它通过了资源配额检查。
如果 Pod 创建请求的 priorityClassName
被设置为 cluster-services
,并且它将在不是 kube-system
的命名空间中创建,则该请求将被拒绝。
下一步
- 参阅 ResourceQuota 设计文档 以获取更多信息。
- 参阅 如何使用资源配额的详细示例。
- 阅读 优先级类配额支持设计文档。
- 参阅 LimitedResources。