Kubernetes资源配额管理(Resource Quotas)

资源配额管理(Resource Quotas)通过 ResourceQuota 对象,可以定义资源配额,这个资源配额可以为每个命名空间都提供一个总体的资源限制:它可以限制命名空间中某种类型的对象的总数量上限,也可以设置命名空间中 Pod 可以使用的计算资源的总上限。

在使用资源配额时,需要注意以下两点:

  1. 如果集群中总的可用资源小于各命名空间中资源配额的总和,那么可能会导致资源竞争。在发生资源竞争时,Kubernetes 系统会遵循先到先得的原则。
  2. 不管是资源竞争还是配额修改,都不会影响已创建的资源使用对象。

1. 在 Master 中开启资源配额选型

资源配额可以通过在 kube-apiserver 的--admission-control参数值中添加ResourceQuota参数进行开启。如果在某个命名空间的定义中存在 ResourceQuota,那么对于该命名空间而言,资源配额就是默认开启的。一个命名空间可以有多个ResourceQuota 配置项。(重启服务的时候会提示:–admission-control has been deprecated, Use --enable-admission-plugins or --disable-admission-plugins instead. Will be removed in a future version.)更换使用--enable-admission-plugins即可。

1 计算资源配额(Compute Resource Quota)

资源配额可以限制一个命名空间中所有 Pod 的计算资源的总和。ResourceQuota 目前支持闲置的计算资源类型如表:

资源名称 描述
cpu 所有非终止状态的 Pod,CPU Requests 的总和不能超过该值
requests.cpu 所有非终止状态的 Pod,CPU Requests 的总和不能超过该值
limits.cpu 所有非终止状态的 Pod,CPU Limits 的总和不能超过该值
memory 所有非终止状态的 Pod,内存 Requests 的总和不能超过该值
requests.memory 所有非终止状态的 Pod,内存 Requests 的总和不能超过该值
limits.memory 所有非终止状态的 Pod,内存 Limits 的总和不能超过该值

2. 存储资源配额(Volume Count Quota)

可以在给定的命名空间中限制所使用的存储资源(Storage Resources)的总量,目前支持的存储资源名称如表:

资源名称 描述
requests.storage 所有 PVC,存储资源的需求总量不能超过该值
persistentvolumeclaims 在该命名空间中所允许的 PVC 总量
<storage-class-name>.storageclass.storage.k8s.io/requests.storage 在所有与 <storage-class-name> 相关的 PVC 请求的存储总量都不能超过该值,例如gold.storageclass.storage.k8s.io/requests.storage: 500Gi表示类型为 gold 的 storageClass 对应的 PVC 的申请存储总量最多可达 500Gi
<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims 所有与 <storage-class-name> 相关的 PVC 总数都不超过该值。
ephemeral-storage、requests.ephemeral-storage、limits.ephemeral-storage 本地临时存储(ephemeral-storage)的总量限制

3. 对象数量配额(Object Count Quota)

指定类型的对象数量可以被限制,例如,可以通过资源配额来限制在命名空间中创建的 Pod 的最大数量。这种配置可以防止某些用户大量创建 Pod 而迅速耗尽整个集群的 Pod IP 和计算资源。下表列出 ResourceQuota 支持限制的对象类型。

资源名称 描述
configmaps 在该命名空间中允许存在的 ConfigMap 总数上限。
pods 在该命名空间中能存在的非终止状态 Pod 的总数上限。Pod 的终止状态等价于 Pod 的 status.phase in (Failed, Successded) = true
replicationcontrollers 在该命名空间中能存在的 RC 的总数上限。
resourcequotas 在该命名空间中能存在的资源配额的总数上限。
services 在该命名空间中能存在的 Service 的总数上限。
services.loadbalancers 在该命名空间中能存在的 LoadBalancer 类型的 Service 总数上限。
services.nodeports 在该命名空间中能存在的 NodePort 类型的 Service 总数上限。
secrets 在该命名空间中能存在的 Secret 的总数上限。

具体表示如下:

  • count/<resource>.<group>: 用于非核心(core)组成的资源,例如count/deployments.appscount/cronjobs.batch
  • count/resource: 用于核心组的资源,例如count/servicescount/pods

2. 配额的作用域(Quota Scopes)

对每项资源配额都可以单独配置一组作用域,配置了作用域的资源配额只会对符合其作用域的资源使用情况进行计量和限制,作用域范围超出了资源配额的请求都会被报验证错误。下表列出了ResourceQuota的4种作用域。

作用域 说明
Terminating 匹配所有 spec.activeDeadlineSeconds 不小于 0 的 Pod
NotTerminating 匹配所有 spec.activeDeadlineSeconds 是 nil 的 Pod
BestEffort 匹配所有 Qos 是 BestEffort 的 Pod
NotBestEffort 匹配所有 Qos 不是 BestEffort 的 Pod
PriorityClass 匹配所有引用了所指定的优先级类的 Pods

其中:

  • BestEffort 作用域可以限定资源配额来追踪 Pod 资源的使用。
  • 而 Terminating、NotTerminating、NotBestEffort、PriorityClass 除了可以追踪 Pod,还可以追踪 CPU、Limits.cpu、Limits.memory、memory、requests.cpu、 requests.memory 等资源的使用情况。

3. 在资源配额(ResourceQuota)中设置 Requests 和 Limits

在资源配额中也可以设置 Requests 和 Limits。如果在资源配额中指定了 requests.cpu 或 limits.cpu ,那么它会强制要求每个容器都配置自己的 CPU Requests 或 CPU Limits(可使用 LimitRange 提供的默认值)。同理,如果在资源配额中指定了 requests.memory 或 limits.memory,那么它也会强制要求每个容器都配置自己的内存 Requests 或内存 Limits(可使用 LimitRange 提供的默认值)。

4. 资源配额的定义

通过例子对资源配额进行设置和应用。

与 LimitRange 相似,ResourceQuota 也被设置在命名空间中。创建名为 myspace 的命名空间:

[root@master1 ~]# kubectl create namespace myspace
namespace/myspace created

创建 ResourceQuota 配置文件 compute-resource.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
spec:
  hard:
    pods: "4"
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

创建该项的资源配额:

[root@master1 ]# kubectl create -f compute-resource.yaml --namespace=myspace 
resourcequota/compute-resources created

创建另一个名为 object-counts.yaml 的文件,用于设置对象数量的配额:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-counts
spec:
  hard:
    configmaps: "10"
    persistentvolumeclaims: "4"
    replicationcontrollers: "20"
    secrets: "10"
    services: "10"
    services.loadbalancers: "2"

创建该 ResourceQuota:

[root@master1 ]# kubectl create -f object-counts.yaml --namespace=myspace 
resourcequota/object-counts created

查看各 ResourceQuota 的详细信息:

[root@master1 ]# kubectl describe quota compute-resources --namespace=myspace 
Name:            compute-resources
Namespace:       myspace
Resource         Used  Hard
--------         ----  ----
limits.cpu       0     2
limits.memory    0     2Gi
pods             0     4
requests.cpu     0     1
requests.memory  0     1Gi
[root@master1 ]# kubectl describe quota object-counts --namespace=myspace 
Name:                   object-counts
Namespace:              myspace
Resource                Used  Hard
--------                ----  ----
configmaps              0     10
persistentvolumeclaims  0     4
replicationcontrollers  0     20
secrets                 1     10
services                0     10
services.loadbalancers  0     2

5. 资源配额与集群资源总量的关系

资源配额与集群资源总量是完全独立的。资源配额是通过绝对的单位来配置的,这也就意味着如果在集群中新添加了节点,那么资源配额不会自动更新,而该资源配额所对应的命名空间中的对象也不能自动增加资源上限。

参考:《Kubernetes权威指南(第五版)》