当多个用户或团队共享具有固定数目节点的集群时,人们会担心有人使用的资源超出应有的份额。
ResourceQuotas
是帮助管理员解决这一问题的工具。
资源配额, 通过 ResourceQuota
对象来定义, 对每个namespace的资源消耗总量提供限制。 它可以按类型限制namespace
下可以创建的对象的数量,也可以限制可被该项目以资源形式消耗的计算资源的总量。
提示: 可配合 LimitRange 准入控制器来为没有设置计算资源需求的Pod设置
request
和limits
默认值。
当 apiserver 的 --admission-control=
参数中包含 ResourceQuota
时,资源配额会被启用。
当namespace中存在一个 ResourceQuota
对象时,该namespace即开始实施资源配额管理。 一个namespace中最多只应存在一个 ResourceQuota
对象
Kubernetes 的版本在1.10+ 之后 启用的的参数
--enable-admission-plugins=
,--admission-control=
将在后续被废弃
资源配额分为以下三种:
cpu
,memory
pods
,configmap
,service
,services.loadbalancers
,services.nodeports
数量。用户可能希望在namespace中为pod设置配额,来避免有用户创建过多的pod,从而耗尽集群提供的pod IP地址
---
apiVersion: v1
kind: Namespace
metadata:
name: myspace
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
pods: "10"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
如果配额中指定了
requests.cpu
或requests.memory
的值,那么它要求每个进来的容器针对这些资源有明确的请求。 如果配额中指定了limits.cpu
或limits.memory
的值,那么它要求每个进来的容器针对这些资源指定明确的约束
针对这个myspace
资源配额限制:
最大pods
数量为10
内存限额总量不能超过2Gi
允许存在的pvc的数量最大为4
Resource Quota
区分的粒度是namespace
,其目的是为了不同namespace之间的公平,防止某些流氓team占用了太多的资源。而limitRange
区分的粒度则是container
,则是在为了在同一个namespace下,限制container的最大最小值。
在设置了resourceQuota的namespace下,如果用户创建Pod时没有指定limit/request,默认是无法创建的(403 FORBIDDEN,此时可以通过limitRanges来配置该namespace下容器默认的limit/request。
默认情况下启用限制范围支持。当apiserver --enable-admission-plugins=
标志具有LimitRanger
允许控制器作为其参数之一时,它被启用
limit-mem-cpu-container.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: limit-mem-cpu-per-container
namespace: myspace
spec:
limits:
- max:
cpu: "1"
memory: "1Gi"
min:
cpu: "100m"
memory: "100Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
type: Container
default
即该namespace配置resourceQuota时,创建container的默认limit上限
defaultRequest
:即该namespace配置resourceQuota时,创建container的默认request上限max
:即该namespace下创建container的资源最大值min
:即该namespace下创建container的资源最小值其中: min <= defaultRequest <= default <= max
root@k8s-master-1:~/k8s_manifests/quota-resource# kubectl describe limitranges/limit-mem-cpu-per-container -n myspace
Name: limit-mem-cpu-per-container
Namespace: myspace
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 1 200m 500m -
Container memory 100Mi 1Gi 256Mi 512Mi -
limit-range-pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox1
spec:
containers:
- name: busybox-cnt01
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt01; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "200Mi"
cpu: "500m"
- name: busybox-cnt02
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt02; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "100m"
- name: busybox-cnt03
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt03; sleep 10;done"]
resources:
limits:
memory: "200Mi"
cpu: "500m"
- name: busybox-cnt04
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt04; sleep 10;done"]
创建busybox1
Pod:
root@k8s-master-1:~/k8s_manifests/quota-resource# kubectl apply -f limit-range-pod-1.yaml -n myspace
查看busybox-cnt01
资源配置
root@k8s-master-1:~/k8s_manifests/quota-resource# kubectl get po/busybox1 -n myspace -o json | jq ".spec.containers[0].resources"
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
busybox-cnt01
Container busybox
定义requests.cpu=100m
和requests.memory=100Mi
。100m <= 500m <= 1
,容器cpu限制(500m)落在授权的CPU限制范围内。100Mi <= 200Mi <= 1Gi
,容器内存限制(200Mi)落在授权的内存限制范围内。查看busybox-cnt02
资源配置
root@k8s-master-1:~/k8s_manifests/quota-resource# kubectl get po/busybox1 -n myspace -o json | jq ".spec.containers[1].resources"
{
"limits": {
"cpu": "500m",
"memory": "512Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
Pod中的busybox-cnt02
Container busybox
定义requests.cpu=100m
和requests.memory=100Mi
但没定义CPU和内存的limits
容器没有limits
部分,limit-mem-cpu-per-container LimitRange对象中定义的默认限制将注入此容器limits.cpu=500mi和
limits.memory=512Mi`。
100m <= 500m <=1
,容器cpu限制(500m)落在授权的CPU限制范围内。
100Mi <= 512Mi <= 1Gi
,容器内存限制(512Mi)落在授权的内存限制范围内。
如果container只设置了request,没设置limit,则最终container的limit为default设置的值。
查看busybox-cnt03
资源配置
root@k8s-master-1:~/k8s_manifests/quota-resource# kubectl get po/busybox1 -n myspace -o json | jq ".spec.containers[2].resources"
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "500m",
"memory": "200Mi"
}
}
busybox-cnt03
Container busybox
定义limits.cpu=500m
和limits.memory=200Mi
,但没有requests
对CPU和内存requests
部分,limit-mem-cpu-per-container LimitRange中定义的defaultRequest不用于填充其限制部分,但容器定义的限制设置为请求limits.cpu=500m
和limits.memory=200Mi
。100m <= 500m <= 1
,容器cpu限制(500m)落在授权的CPU限制范围内。100Mi <= 200Mi <= 1Gi
,容器内存限制(200Mi)落在授权的内存限制范围内。注意:如果container的resources部分设置了limit,没有设置request,那么最终创建出来的container,其request=limit。而不是想当然的是defaultRequest。
查看busybox-cnt04
资源配置
root@k8s-master-1:~/k8s_manifests/quota-resource# kubectl get po/busybox1 -n myspace -o json | jq ".spec.containers[3].resources"
{
"limits": {
"cpu": "500m",
"memory": "512Mi"
},
"requests": {
"cpu": "200m",
"memory": "256Mi"
}
}
busybox-cnt03
Container busybox
定义中没有requests
和limits
limits
部分,limit-mem-cpu-per-container LimitRange中定义的默认限制用于填充其请求 limits.cpu=500m and
limits.memory=512Mi
。requests
部分,limit-mem-cpu-per-container LimitRange中定义的defaultRequest用于填充请求部分requests.cpu = 200m
和requests.memory = 256Mi
100m <=500m <= 1
,容器cpu限制(500m)落在授权的CPU限制范围内。100Mi <= 512Mi <= 1Gi
,容器内存限制(512Mi)属于授权的内存限制范围。requests
和limits
的设置会影响Pod的Qos服务等级,如果系统中的所有节点都没有剩余资源来填充请求,则Pod将进入pending
状态。由于CPU可以被压缩,Kubernetes将减少该容器的调度时间,并不会直接杀死Pod。内存无法压缩,因此如果Node耗尽内存,Kubernetes需要开始根据Pod的Qos服务等级和Pod的优先级,进行驱逐Pod或者杀死Pod,并首先终止最低优先级的pod。如果所有Pod具有相同的优先级,Kubernetes将终止最多其请求的Pod。。
https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-resource-requests-and-limits
https://kubernetes.io/zh/docs/concepts/policy/resource-quotas/
https://kubernetes.io/docs/concepts/policy/limit-range/
https://k8smeetup.github.io/docs/tasks/configure-pod-container/quality-service-pod/