系列目录html
当多个用户或者开发团队共享一个有固定节点的的kubernetes集群时,一个团队或者一个用户使用的资源超过他应当使用的资源是须要关注的问题,资源配额是管理员用来解决这个问题的一个工具.node
资源配额,经过ResourceQuota
定义,提供了对某一名称空间使用资源的整体约束.它便可以限制这个名称空间下有多少个对象能够被建立,也能够限制对计算机资源使用量的限制(前面说到过,计算机资源包括cpu,内存,磁盘空间等资源)nginx
资源配额经过如下相似方式工做:ubuntu
不一样的团队在不一样的名称空间下工做.当前kubernetes并无强制这样作,彻底是自愿的,可是kubernetes团队计划经过acl受权来达到强制这样作.api
管理员对每个名称空间建立一个ResourceQuota(资源配额)
bash
用户在一个名称空间下建立资源(例如pod,service等),配额系统跟踪资源使用量来保证资源的使用不超过ResourceQuota
定义的量.服务器
若是对一个资源的建立或者更新违反了资源配额约束,则请求会返回失败,失败的http状态码是403 FORBIDDEN
而且有一条消息来解释哪一个约束被违反.app
若是一个名称空间下的计算机资源配额,好比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
此特征在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
来用户以上yml文件
kubectl create -f ./quota.yml 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.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
这时候再用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
的配额资源对象的名称空间里,例如
`yml scopeSelector: matchExpressions: - scopeName: PriorityClass operator: In values: ["cluster-services"]