当多个用户或团队共享具有固定数目节点的集群时,人们会担心有人使用的资源超出应有的份额。
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,memorypods,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"]
创建busybox1Pod:
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-cnt01Container 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-cnt02Container 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-cnt03Container 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-cnt03Container busybox定义中没有requests和limitslimits部分,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 = 256Mi100m <=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/