系列目录 https://www.cnblogs.com/tylerzhou/p/10969041.html
当多个用户或者开发团队共享一个有固定节点的的 kubernetes 集群时, 一个团队或者一个用户使用的资源超过他应当使用的资源是需要关注的问题, 资源配额是管理员用来解决这个问题的一个工具.
资源配额, 通过 ResourceQuota 定义, 提供了对某一名称空间使用资源的总体约束. 它即可以限制这个名称空间下有多少个对象可以被创建, 也可以限制对计算机资源使用量的限制 (前面说到过, 计算机资源包括 CPU, 内存, 磁盘空间等资源)
资源配额通过以下类似方式工作:
不同的团队在不同的名称空间下工作. 当前 kubernetes 并没有强制这样做, 完全是自愿的, 但是 kubernetes 团队计划通过 acl 授权来达到强制这样做.
管理员对每一个名称空间创建一个 ResourceQuota(资源配额)
用户在一个名称空间下创建资源 (例如 pod,service 等), 配额系统跟踪资源使用量来保证资源的使用不超过 ResourceQuota 定义的量.
如果对一个资源的创建或者更新违反了资源配额约束, 则请求会返回失败, 失败的 http 状态码是 403 FORBIDDEN 并且有一条消息来解释哪个约束被违反.
如果一个名称空间下的计算机资源配额, 比如 CPU 和内存被启用, 则用户必须指定相应的资源申请或者限制的值, 否则配额系统可能会阻止 pod 的创建.
资源配额在某一名称空间下创建策略示例:
在一个有 32G 内存, 16 核 CPU 的集群, 让团队 A 使用 20G 内存和 10 核 CPU, 让团队 B 使用 10G 内存和 4 核 CPU, 剩余的 2G 内存和 2 核 cup 预留以备进一步分配
限制测试名称空间使用 1 核 1G, 让生产名称空间使用剩下的全部资源
当集群的容量小于所有名称空间下配额总和时, 将会出现资源竞争, 这种情况下 kubernetes 将会基于先到先分配的原则进行处理
不论是资源竞争或者是资源配额的修改都不会影响已经创建的资源
启用资源配额
很多 kubernetes 的发行版中资源配额支持默认是开启的, 当 ResourceQuota 作为 apiserver 的 --enable-admission-plugins = 的其中一个值时, 资源配额被开启.
当某一名称空间包含 ResourceQuota 对象时资源配额在这个名称空间下生效.
计算机资源配额
你可以限制一个名称空间下可以被申请的计算机资源的总和
kubernetes 支持以下资源类型:
Resource Name | Description |
---|---|
cpu | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. |
limits.cpu | Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value. |
limits.memory | Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value. |
memory | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. |
requests.cpu | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. |
requests.memory | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. |
扩展资源的资源配额
除了上面提到的, 在 kubernetes 1.10 里, 添加了对扩展资源的配额支持
存储资源配额
你可以限制某一名称空间下的存储空间总量的申请
此外, 你也可以你也可以根据关联的 storage-class 来限制存储空间资源的使用
Resource Name | Description |
---|---|
requests.storage | Across all persistent volume claims, the sum of storage requests cannot exceed this value. |
persistentvolumeclaims | The total number of persistent volume claims that can exist in the namespace. |
Across all persistent volume claims associated with the storage-class-name, the sum of storage requests cannot exceed this value. | |
Across all persistent volume claims associated with the storage-class-name, the total number of persistent volume claims that can exist in the namespace. |
例如, 一个 operator 想要想要使黄金和青铜单独申请存储空间, 那么这个 operator 可以像如下一样申请配额:
- gold.storageclass.storage.k8s.io/requests.storage: 500Gi
- bronze.storageclass.storage.k8s.io/requests.storage: 100Gi
在 1.8 版本里, 对 local ephemeral storage 配额的的支持被添加到 alpha 特征里.
Resource Name | Description |
---|---|
requests.ephemeral-storage | Across all pods in the namespace, the sum of local ephemeral storage requests cannot exceed this value. |
limits.ephemeral-storage | Across all pods in the namespace, the sum of local ephemeral storage limits cannot exceed this value. |
对象数量配额
1.9 版本通过以下语法加入了对所有标准名称空间资源类型的配额支持
count/<resource>.<group>
以下是用户可能想要设置对象数量配额的例子:
- 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
- count/deployments.extensions
当使用 count/* 类型资源配额, 服务器上存在的资源对象将都被控制. 这将有助于防止服务器存储资源被耗尽. 比如, 如果存储在服务器上的 secrets 资源对象过大, 你可能会想要限制它的数量. 过多的 secrets 可能会导致服务器无法启动! 你也可能会限制 job 的数量以防一些设计拙劣的定时任务会创建过多的 job 以导致服务被拒绝
以下资源类型的限额是支持的
Resource Name | Description |
---|---|
configmaps | The total number of config maps that can exist in the namespace. |
persistentvolumeclaims | The total number of persistent volume claims that can exist in the namespace. |
pods | The total number of pods in a non-terminal state that can exist in the namespace. A pod is in a terminal state if .status.phase in (Failed, Succeeded) is true. |
replicationcontrollers | The total number of replication controllers that can exist in the namespace. |
resourcequotas | The total number of resource quotas that can exist in the namespace. |
services | The total number of services that can exist in the namespace. |
services.loadbalancers | The total number of services of type load balancer that can exist in the namespace. |
services.nodeports | The total number of services of type node port that can exist in the namespace. |
secrets | The total number of secrets that can exist in the namespace. |
例如, pod 配额限制了一个名称空间下非 terminal 状态的 pod 总数量. 这样可以防止一个用户创建太多小的 pod 以至于耗尽集群分配给 pod 的所有 IP
配额范围
每一个配额都可以包含一系列相关的范围. 配额只会在匹配列举出的范围的交集时才计算资源的使用.
当一个范围被添加到配额里, 它将限制它支持的, 属于范围的资源. 指定的资源不在支持的集合里时, 将会导致验证错误
Scope | Description |
---|---|
Terminating | Match pods where .spec.activeDeadlineSeconds >= 0 |
NotTerminating | Match pods where .spec.activeDeadlineSeconds is nil |
BestEffort | Match pods that have best effort quality of service. |
NotBestEffort | Match pods that do not have best effort quality of service. |
BestEffort 范围限制配额只追踪 pods 资源
Terminating,NotTerminating 和 NotBestEffort 范围限制配额追踪以下资源:
- CPU
- limits.CPU
- limits.memory
- memory
- pods
- requests.CPU
- requests.memory
每一个 PriorityClass 的资源配额
此特征在 1.12 片本中为 beta
pod 可以以指定的优先级创建. 你可以通过 pod 的优先级来控制 pod 对系统资源的使用, 它是通过配额的 spec 下的 scopeSelector 字段产生效果的.
只有当配额 spec 的 scopeSelector 选择了一个 pod, 配额才会被匹配和消费
你在使用 PriorityClass 的配额的之前, 需要启用 ResourceQuotaScopeSelectors
以下示例创建一个配额对象, 并且一定优先级的 pod 会匹配它.
集群中的 pod 有以下三个优先级类之一: low,medium,high
每个优先级类都创建了一个资源配额
- 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 来查看
- 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, 把以下内容保存在 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
这时候再用 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
scopeSelector 支持 operator 字段的以下值:
- In
- NotIn
- Exist
- DoesNotExist
配额资源的申请与限制
当分配计算机资源时, 每一个容器可能会指定对 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:
- pods: "4"
- 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"
- 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
- pods 0 4
- 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
- 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.extensions=2,count/replicasets.extensions=4,count/pods=3,count/secrets=4 --namespace=myspace
- kubectl run nginx --image=nginx --replicas=2 --namespace=myspace
- kubectl describe quota --namespace=myspace
- Name: test
- Namespace: myspace
- Resource Used Hard
- -------- ---- ----
- count/deployments.extensions 1 2
- count/pods 2 3
- count/replicasets.extensions 1 4
- count/secrets 1 4
配额和集群容量
ResourceQuotas 独立于集群的容量, 它们通过绝对的单位表示. 因此, 如果你向集群添加了节点, 这并不会给集群中的每个名称空间赋予消费更多资源的能力.
有时候需要更为复杂的策略, 比如:
把集群中所有的资源按照比例分配给不同团队
允许每个租户根据需求增加资源使用, 但是有一个总体的限制以防资源被耗尽
检测名称空间的需求, 添加节点, 增加配额
这些策略可以通过实现 ResourceQuotas 来写一个 controller 用于监视配额的使用, 并且通过其它信号来调整每个名称空间的配额
默认限制优先类消费
有时候我们可能希望一定优先级别的 pod, 例如 cluster-services 应当被允许在一个名称空间里, 当且仅当匹配的配额存在.
通过这种机制, operators 可以限制一些高优先级的类只能用于有限数量的名称空间里, 并且不是所有的名称空间都可以默认消费它们.
为了使以上生效, kube-apiserver 标签 --admission-control-config-file 应当传入以下配置文件的路径
- apiVersion: apiserver.k8s.io/v1alpha1
- kind: AdmissionConfiguration
- plugins:
- - name: "ResourceQuota"
- configuration:
- apiVersion: resourcequota.admission.k8s.io/v1beta1
- kind: Configuration
- limitedResources:
- - resource: pods
- matchScopes:
- - scopeName: PriorityClass
- operator: In
- values: ["cluster-services"]
现在, cluster-services 类型的 pod 仅被允许运行在有匹配 scopeSelector 的配额资源对象的名称空间里, 例如
`YAML scopeSelector: matchExpressions: - scopeName: PriorityClass operator: In values: ["cluster-services"]
来源: http://www.bubuko.com/infodetail-3093887.html