Quota资源限制
对每个命名空间的资源消耗总量提供限制(在一个namespace下创建quota,就会只对当前namespace进行资源限制)。它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命令空间中的单个Pod可以使用的计算资源的总上限。
配额类型
Kubernetes可以限制两种类型资源:
- 对象数量:Kubernetes 资源数量,例如pods,services和ingress等。实施资源数量配额可以提高kubernetes稳定性,避免Etcd数据库无限增长,还可以避免占用node中其他功能资源(例如ip地址服务)。
- 计算资源:物理或者虚拟资源容量,例如CPU,memory和存储容量。同样,实施计算资源配额可以避免消耗kubernetes集群中单个node所有计算资源,避免单个namespace中应用消耗所有集群资源,导致其他namespace中应用无法正常运行。
kubernetes实施配额,通过ResourceQuota类型资源。一个namespace可以包含多个ResourceQuota对象,这些限制是累加的,一般情况,多个ResourceQuota 对象不会限定同一个资源。
对象数量:
- persistentvolumeclaims
- services
- secrets
- configmaps
- replicationcontrollers
- deployments.apps
- deployments.apps
- statefulsets.apps
- jobs.batch
- cronjobs.batch
可以限制给定命名空间中可以请求的计算资源的总和
资源名称 |
描述 |
limits.cpu |
所有非终止状态的Pod,其CPU限额总量不能超过该值。 |
limits.memory |
所有非终止状态的Pod,其内存限额总量不能超过该值。 |
requests.cpu |
所有非终止状态的Pod,其CPU需求总量不能超过该值。 |
requests.memory |
所有非终止状态的Pod,其内存需求总量不能超过该值。 |
hugepages-<size> |
对于所有非终止状态的Pod,针对指定尺寸的巨页请求总数不能超过此值。 |
cpu |
与requests.cpu相同。 |
memorys |
与requests.memory相同。 |
配额管理
示例:创建ResourceQuota对象
[root@master10 ~]# kubectl create ns quota #创建一个ns用于测试 | |
namespace/quota created | |
[root@master10 ~]# kubectl config set-context --namespace quota --current | |
kubectl create quota -h #查看创建帮助 | |
#创建quota my-quota | |
kubectl create quota my-quota --hard=cpu=1,memory=1G,pods=2,services=3,replicationcontrollers=2,resourcequotas=1,secrets=5,persistentvolumeclaims=10 |
也可以通过yaml方式创建:
apiVersion: v1 | |
kind: ResourceQuota | |
metadata: | |
name: my-quota | |
namespace: quota | |
spec: | |
hard: | |
persistentvolumeclaims: "10" | |
pods: "5" | |
requests.cpu: "2" | |
limits.cpu: "4" | |
requests.memory: 2Gi | |
limits.memory: 4Gi | |
secrets: "5" | |
services: "3" |
pvc限制示例:
apiVersion: v1 | |
kind: ResourceQuota | |
metadata: | |
name: storagequota | |
spec: | |
hard: | |
persistentvolumeclaims: "5" | |
requests.storage: "5Gi" |
查看创建的quota
kubectl get resourcequotas | |
kubectl describe resourcequotas my-quota |
示例:
创建一个quota对deployment pod数量进行限制,上限为5副本
apiVersion: v1 | |
kind: ResourceQuota | |
metadata: | |
name: my-quota | |
namespace: quota | |
spec: | |
hard: | |
persistentvolumeclaims: "10" | |
pods: "5" | |
secrets: "5" | |
services: "3" |
创建deployment
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
labels: | |
app: nginx | |
name: nginx | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: nginx | |
strategy: {} | |
template: | |
metadata: | |
labels: | |
app: nginx | |
spec: | |
containers: | |
- image: nginx | |
name: nginx | |
imagePullPolicy: IfNotPresent |
水平伸缩扩展deployment为5副本
水平伸缩扩展deployment为6和7副本
提示创建错误超出pod数量限制为5个上线
Request 和 Limits
pod.containers.resources定义包含两部分:requests和limits。
- requests,指明pod运行需要的最少计算资源。调度器查找具有充足计算资源的nodes。
- limits,指明pod运行可以获得节点最多计算资源,用于阻止pod占用node太多计算资源。node使用Linux内核功能cgroup,限制pod资源使用。
Request
示例:限制cpu和内存
apiVersion: v1 | |
kind: ResourceQuota | |
metadata: | |
name: my-quota | |
namespace: quota | |
spec: | |
hard: | |
cpu: "1" | |
memory: "2G" | |
persistentvolumeclaims: "10" | |
pods: "5" | |
secrets: "5" | |
services: "3" |
cpu: 1核等于1000M资源申请
创建deployment
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
labels: | |
app: nginx | |
name: nginx | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: nginx | |
template: | |
metadata: | |
labels: | |
app: nginx | |
spec: | |
containers: | |
- image: nginx | |
name: nginx | |
imagePullPolicy: IfNotPresent | |
resources: | |
requests: | |
memory: "256Mi" | |
cpu: "500m" |
Limits:
示例:限制cpu和内存的上限
quota限制namespace下的资源上限cpu不得超过1核,内存不得超过2G
apiVersion: v1 | |
kind: ResourceQuota | |
metadata: | |
name: my-quota | |
namespace: quota | |
spec: | |
hard: | |
limits.cpu: "1" | |
limits.memory: "2G" | |
cpu: "500M" | |
memory: "1G" | |
persistentvolumeclaims: "10" | |
pods: "5" | |
secrets: "5" | |
services: "3" |
deployment需要指定pods的cpu和内存最大使用上限
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
labels: | |
app: nginx | |
name: nginx | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: nginx | |
template: | |
metadata: | |
labels: | |
app: nginx | |
spec: | |
containers: | |
- image: nginx | |
name: nginx | |
imagePullPolicy: IfNotPresent | |
resources: | |
requests: | |
memory: "256Mi" | |
cpu: "500m" | |
limits: | |
memory: "256Mi" | |
cpu: "500m" |
Limit Range
limit range是解决使用quota资源配额时,控制器或者pod没有指定resource,而服务成功创建pod,必须使用limit range来指定默认配额,从而达到quota和limit range搭配使用。
如果namespace设置了quota配额,那么创建不指定资源请求和资源限制的pod是不允许的。kubernetes中pod默认不指定资源请求和计算资源。为了在设定配额的namespace中使用pod,namespace还需要为pod资源请求设定默认范围。
1、如果运行的容器没有定义资源(memory、CPU)等限制,但是在namespace定义了LimitRange限制,那么该容器会继承LimitRange中的默认限制。
2、如果namespace没有定义LimitRange限制,那么该容器可以只要宿主机的最大可用资源,直到无资源可用而触发宿主机(OOM Killer)。
https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-cpu-resource/ CPU
以核心为单位进行限制,单位可以是整核、浮点核心数或毫核(m/milli):2=2核心=200% 0.5=500m=50% 1.2=1200m=120%
https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-memory-resource/
memory以字节为单位,单位可以是E、P、T、G、M、K、Ei、Pi、Ti、Gi、Mi、Ki 1536Mi=1.5Gi
requests(请求)为kubernetes scheduler执行pod调度时node节点至少需要拥有的资源。
limits(限制)为pod运行成功后最多可以使用的资源上限。
LimitRange类型资源,也称为limits,定义了单个pod的资源请求和资源限制default minimum maximum值。pod的资源请求是其中所有容器请求的总和
默认情况下,Kubernetes集群上的容器运行使用的计算资源没有限制。 使用资源配额,集群管理员可以以名字空间为单位,限制其资源的使用与创建。在命名空间中,一个Pod或Container最多能够使用命名空间的资源配额所定义的 CPU和内存用量。 有人担心,一个Pod或Container会垄断所有可用的资源。LimitRange是在命名空间内限制资源分配(给多个Pod或Container)的策略对象。
参考官网文档:
https://kubernetes.io/zh-cn/docs/concepts/policy/limit-range/
一个LimitRange(限制范围)对象提供的限制能够做到:
- 在一个命名空间中实施对每个Pod或Container最小和最大的资源使用量的限制。
- 在一个命名空间中实施对每个PersistentVolumeClaim能申请的最小和最大的存储空间大小的限制。
- 在一个命名空间中实施对一种资源的申请值和限制值的比值的控制。
- 设置一个命名空间中对计算资源的默认申请/限制值,并且自动的在运行时注入到多个Container中。
- 如果项目中请求一个未提供计算资源的对象,那么此时namespace将使用limit范围default值创建该对象。
- 如果项目中请求一个计算资源的对象,请求的资源小于项目limit最小值,那么该资源无法创建。
- 如果项目中请求一个计算资源的对象,请求的资源大于项目limit最大值,那么该资源也无法创建。
能够使用限制范围创建的策略示例有:
在一个有两个节点,8GiB内存与16个核的集群中,限制一个命名空间的Pod申请100m单位,最大500m单位的CPU,以及申请200Mi,最大600Mi的内存。
为spec中没有cpu和内存需求值的Container定义默认CPU限制值与需求值150m,内存默认需求值300Mi。
在命名空间的总限制值小于Pod或Container的限制值的总和的情况下,可能会产生资源竞争。在这种情况下,将不会创建Container或Pod。
限定资源类型
Type |
Resource Name |
Description |
container |
cpu、memory |
限定容器cpu、memroy |
Pod |
cpu、memory |
限定Pod中所有容器cpu、memroy的总和 |
PVS |
storage |
限定PVS申请的存储空间大小 |
pvc限制示例:
apiVersion: v1 | |
kind: LimitRange | |
metadata: | |
name: storagelimits | |
namespace: test | |
spec: | |
limits: | |
- type: PersistentVolumeClaim | |
max: | |
storage: 2Gi | |
min: | |
storage: 1Gi |
所有类型示例:
apiVersion: v1 | |
kind: LimitRange | |
metadata: | |
name: limitrange | |
namespace: test | |
spec: | |
limits: | |
- type: Container #限制的资源类型 | |
max: | |
cpu: "2" #限制单个容器的最大CPU | |
memory: "2Gi" #限制单个容器的最大内存 | |
min: | |
cpu: "500m" #限制单个容器的最小CPU | |
memory: "512Mi" #限制单个容器的最小内存 | |
default: | |
cpu: "500m" #默认单个容器的CPU限制 | |
memory: "512Mi" #默认单个容器的内存限制 | |
defaultRequest: | |
cpu: "500m" #默认单个容器的CPU创建请求 | |
memory: "512Mi" #默认单个容器的内存创建请求 | |
maxLimitRequestRatio: | |
cpu: 2 #限制CPU limit/request比值最大为2 | |
memory: 2 #限制内存limit/request比值最大为2 | |
- type: Pod | |
max: | |
cpu: "4" #限制单个Pod的最大CPU | |
memory: "4Gi" #限制单个Pod最大内存 | |
- type: PersistentVolumeClaim | |
max: | |
storage: 50Gi #限制PVC最大的requests.storage | |
min: | |
storage: 30Gi #限制PVC最小的requests.storage |
limit-range配置:
apiVersion: v1 | |
kind: LimitRange | |
metadata: | |
name: mem-min-max-demo-lr | |
spec: | |
limits: | |
- default: | |
cpu: "500m" | |
memory: "1Gi" | |
defaultRequest: | |
cpu: "200m" | |
memory: "450Mi" | |
max: | |
cpu: "2" | |
memory: "2Gi" | |
min: | |
cpu: "100m" | |
memory: "128Mi" | |
type: Container |
创建出来的 pod resources与limit ranage指定的相关默认值一致。
说明:
name:只能使用小写字母,数字,'-' 和 '.',而且只能是数字或字母开头和结尾。
default:即该namespace配置resourceQuota时,创建container的默认limit上限
defaultRequest:即该namespace配置resourceQuota时,创建container的默认request上限
max:即该namespace下创建container的资源最大值
min:即该namespace下创建container的资源最小值
其中:min <= defaultRequest <= default <= max
Pod未申请resource
与quota搭配使用:注意limit-range中的default和defaultRequest不能超过quota中limit和requset的值,否则资源限制,导致错误无法创建pod
apiVersion: v1 | |
kind: ResourceQuota | |
metadata: | |
name: my-quota | |
namespace: quota | |
spec: | |
hard: | |
limits.cpu: "2" | |
limits.memory: "2Gi" | |
requests.cpu: "0.5" | |
requests.memory: "1Gi" | |
persistentvolumeclaims: "10" | |
pods: "5" | |
secrets: "5" | |
services: "3" |
limit range配置内容
apiVersion: v1 | |
kind: LimitRange | |
metadata: | |
name: mem-min-max-demo-lr | |
spec: | |
limits: | |
- default: | |
cpu: "500m" | |
memory: "1Gi" | |
defaultRequest: | |
cpu: "200m" | |
memory: "450Mi" | |
max: | |
cpu: "2" | |
memory: "2Gi" | |
min: | |
cpu: "100m" | |
memory: "128Mi" | |
type: Container |
Depoloyment: 未申请resources
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
labels: | |
app: nginx | |
name: nginx | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: nginx | |
template: | |
metadata: | |
labels: | |
app: nginx | |
spec: | |
containers: | |
- image: nginx | |
name: nginx | |
imagePullPolicy: IfNotPresent |
Pod申请资源
创建的容器requests值必须满足条件:min值<requests值<limits值。
当只指定requests值时,limits值与default值保持一致。不得超过default limit值。
Deployment只申请request值并且大于limit中的default limit值
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
labels: | |
app: nginx | |
name: nginx | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: nginx | |
template: | |
metadata: | |
labels: | |
app: nginx | |
spec: | |
containers: | |
- image: nginx | |
name: nginx | |
imagePullPolicy: IfNotPresent | |
resources: | |
requests: | |
memory: "1.5G" | |
cpu: "600m" |
创建deployment失败,查看rs描述不得超过default limit值
kubectl describe rs |
申请request和limit值,则request大于defult limit值是不受限制的,但不能大于limit range中的max limit值。
kind: Deployment | |
metadata: | |
labels: | |
app: nginx | |
name: nginx | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: nginx | |
template: | |
metadata: | |
labels: | |
app: nginx | |
spec: | |
containers: | |
- image: nginx | |
name: nginx | |
imagePullPolicy: IfNotPresent | |
resources: | |
requests: | |
memory: "500Mi" | |
cpu: "0.25" | |
limits: | |
memory: "1Gi" | |
cpu: "1" |
创建成功