参考文档:资源配额 | Kubernetes
1.Resource Quotas:资源配额管理
当多个用户或团队共享具有固定节点数目的集群时,人们会担心有人使用超过其基于公平原则所分配到的资源量。
资源配额是帮助管理员解决这一问题的工具。
资源配额,通过ResourceQuota
对象来定义,对每个命名空间的资源消耗总量提供限制。 它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命名空间中的Pod可以使用的计算资源的总上限。
资源配额的工作方式如下:
-
不同的团队可以在不同的命名空间下工作。这可以通过 RBAC 强制执行。
-
集群管理员可以为每个命名空间创建一个或多个 ResourceQuota 对象。
-
当用户在命名空间下创建资源(如 Pod、Service 等)时,Kubernetes 的配额系统会跟踪集群的资源使用情况, 以确保使用的资源用量不超过 ResourceQuota 中定义的硬性资源限额。
-
如果资源创建或者更新请求违反了配额约束,那么该请求会报错(HTTP 403 FORBIDDEN), 并在消息中给出有可能违反的约束。
-
如果命名空间下的计算资源 (如
cpu
和memory
)的配额被启用, 则用户必须为这些资源设定请求值(request)和约束值(limit),否则配额系统将拒绝 Pod 的创建。 提示: 可使用LimitRanger
准入控制器来为没有设置计算资源需求的 Pod 设置默认值。
在使用资源配额时,需要注意以下两点:
1.如果集群中总的可用资源小于各命名空间中资源配额额总和,那么可能会导致资源竞争。在发生资源竞争的情况下,Kubernetes遵循先到先得的原则
2.不管是资源竞争还是配额修改,都不会影响已创建额资源使用对象
2. 资源配额选型开启
资源配额的支持在很多 Kubernetes 版本中是默认启用的。 当 API 服务器 的命令行标志 --enable-admission-plugins=
中包含 ResourceQuota
时, 资源配额会被启用。
当命名空间中存在一个 ResourceQuota 对象时,对于该命名空间而言,资源配额就是开启的
1.计算机资源配额(Computer Resource Quota)
用户可以对给定命名空间下的可被请求的 计算资源 总量进行限制
资源名称 | 描述 |
---|---|
limits.cpu |
所有非终止状态的 Pod,其 CPU 限额总量不能超过该值。 |
limits.memory |
所有非终止状态的 Pod,其内存限额总量不能超过该值。 |
requests.cpu |
所有非终止状态的 Pod,其 CPU 需求总量不能超过该值。 |
requests.memory |
所有非终止状态的 Pod,其内存需求总量不能超过该值。 |
hugepages-<size> |
对于所有非终止状态的 Pod,针对指定尺寸的巨页请求总数不能超过此值。 |
cpu |
与 requests.cpu 相同。 |
memory |
与 requests.memory 相同。 |
2.存储资源配额(Volume Count Quota)
用户可以对给定命名空间下的存储资源 总量进行限制。
资源名称 | 描述 |
---|---|
requests.storage |
所有 PVC,存储资源的需求总量不能超过该值。 |
persistentvolumeclaims |
在该命名空间中所允许的 PVC 总量。 |
<storage-class-name>.storageclass.storage.k8s.io/requests.storage |
在所有与 <storage-class-name> 相关的持久卷申领中,存储请求的总和不能超过该值。 |
<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims |
在与 storage-class-name 相关的所有持久卷申领中,命名空间中可以存在的持久卷申领总数。 |
3.对象数量配额(Object Count Quota)
用户可以对指定类型的对象数量进行限制
资源名称 | 描述 |
---|---|
configmaps |
在该命名空间中允许存在的 ConfigMap 总数上限。 |
persistentvolumeclaims |
在该命名空间中允许存在的 PVC 的总数上限。 |
pods |
在该命名空间中允许存在的非终止状态的 Pod 总数上限。Pod 终止状态等价于 Pod 的 .status.phase in (Failed, Succeeded) 为真。 |
replicationcontrollers |
在该命名空间中允许存在的 ReplicationController 总数上限。 |
resourcequotas |
在该命名空间中允许存在的 ResourceQuota 总数上限。 |
services |
在该命名空间中允许存在的 Service 总数上限。 |
services.loadbalancers |
在该命名空间中允许存在的 LoadBalancer 类型的 Service 总数上限。 |
services.nodeports |
在该命名空间中允许存在的 NodePort 类型的 Service 总数上限。 |
secrets |
在该命名空间中允许存在的 Secret 总数上限。 |
3.配额的作用域
每个配额都有一组相关的 scope
(作用域),配额只会对作用域内的资源生效。 配额机制仅统计所列举的作用域的交集中的资源用量。
当一个作用域被添加到配额中后,它会对作用域相关的资源数量作限制。 如配额中指定了允许(作用域)集合之外的资源,会导致验证错误。
作用域 | 描述 |
---|---|
Terminating |
匹配所有 spec.activeDeadlineSeconds 不小于 0 的 Pod。 |
NotTerminating |
匹配所有 spec.activeDeadlineSeconds 是 nil 的 Pod。 |
BestEffort |
匹配所有 Qos 是 BestEffort 的 Pod。 |
NotBestEffort |
匹配所有 Qos 不是 BestEffort 的 Pod。 |
PriorityClass |
匹配所有引用了所指定的优先级类的 Pods。 |
CrossNamespacePodAffinity |
匹配那些设置了跨名字空间 (反)亲和性条件的 Pod。 |
其中,BestEffort作用域可以限定资源配额来追踪Pod资源的使用;而Terminating、NotTerm inating、NotBestEffort和PriorityC!ass除了可以追踪Pod,还可以追踪CPU、limits.cpu、limits.memory、memory、requests.cpu、requests.memory等资源的使用情况。
4.基于优先级类(PriorityClass)来设置资源配额
Pod 可以创建为特定的优先级。 通过使用配额规约中的 scopeSelector
字段,用户可以根据 Pod 的优先级控制其系统资源消耗。
仅当配额规范中的 scopeSelector
字段选择到某 Pod 时,配额机制才会匹配和计量 Pod 的资源消耗。
如果配额对象通过 scopeSelector
字段设置其作用域为优先级类
下面就举个例子,从创建配额对象,并且将其与具有特定优先级的 Pod 进行匹配。 该示例的工作方式如下:
-
集群中的 Pod 可取三个优先级类之一,即 "low"、"medium"、"high"。
-
为每个优先级创建一个配额对象。
#1.创建资源配额
[root@k8s-master qos_test]# cat 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"]
[root@k8s-master qos_test]# kubectl create -f quota.yml
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created
#2.查看资源配额
[root@k8s-master qos_test]# kubectl describe quota
Name: pods-high
Namespace: default
Resource Used Hard
cpu 0 1k
memory 0 200Gi
pods 0 10Name: pods-low
Namespace: default
Resource Used Hard
cpu 0 5
memory 0 10Gi
pods 0 10Name: pods-medium
Namespace: default
Resource Used Hard
cpu 0 10
memory 0 20Gi
pods 0 10
#3.创建优先级为高的pod
[root@k8s-master qos_test]# cat 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[root@k8s-master qos_test]# kubectl create -f high-priority-pod.yml
#4.确认"high"优先级配额 pods-high 的 "Used" 统计信息已更改,并且其他两个配额未更改
[root@k8s-master qos_test]# kubectl describe quota
Name: pods-high
Namespace: default
Resource Used Hard
cpu 500m 1k
memory 10Gi 200Gi
pods 1 10Name: pods-low
Namespace: default
Resource Used Hard
cpu 0 5
memory 0 10Gi
pods 0 10Name: pods-medium
Namespace: default
Resource Used Hard
cpu 0 10
memory 0 20Gi
pods 0 10 - apiVersion: v1