limitRange
LimitRange有个好听的中文名字,叫"资源配置访问管理"。用过K8S的都知道,在默认情况下,K8S不会对Pod进行CPU和内存限制,这就意味着这个未被限制的Pod可以随心所欲的使用节点上的CPU和内存,如果某个Pod发生内存泄漏那么将是一个非常糟糕的事情。
所以正常情况下,我们在部署Pod的时候都会把Requests和Limits加上,如下:
apiVersion:apps/v1
kind:Deployment
metadata:
name:ng-deploy
spec:
selector:
matchLabels:
app:ng-demo
replicas:2
template:
metadata:
labels:
app:ng-demo
spec:
containers:
- name:ng-demo
image:nginx
imagePullPolicy:IfNotPresent
resources:
requests:
cpu:100m
memory:216Mi
limits:
cpu:100m
memory:216Mi
但是,如果Pod非常多,而且很多Pod只需要相同的限制,我们还是像上面那样一个一个的加就非常繁琐了,这时候我们就可以通过LimitRange做一个Namespace资源限制。如果在部署Pod的时候指定了requests和Limits,则指定的生效。反之则由全局的给Pod加上默认的限制。
总结,LimitRange可以实现的功能:
- 限制namespace中每个pod或container的最小和最大资源用量。
- 限制namespace中每个PVC的资源请求范围。
- 限制namespace中资源请求和限制数量的比例。
- 配置资源的默认限制。
创建LimitRange之后,LimitRange会在它所属namespace范围内生效。
常用的场景如下(来自《Kubernetes权威指南》)
- 集群中的每个节点都有2GB内存,集群管理员不希望任何Pod申请超过2GB的内存:因为在整个集群中都没有任何节点能满足超过2GB内存的请求。如果某个Pod的内存配置超过2GB,那么该Pod将永远都无法被调度到任何节点上执行。为了防止这种情况的发生,集群管理员希望能在系统管理功能中设置禁止Pod申请超过2GB内存。
- 集群由同一个组织中的两个团队共享,分别运行生产环境和开发环境。生产环境最多可以使用8GB内存,而开发环境最多可以使用512MB内存。集群管理员希望通过为这两个环境创建不同的命名空间,并为每个命名空间设置不同的限制来满足这个需求。
- 用户创建Pod时使用的资源可能会刚好比整个机器资源的上限稍小,而恰好剩下的资源大小非常尴尬:不足以运行其他任务但整个集群加起来又非常浪费。因此,集群管理员希望设置每个Pod都必须至少使用集群平均资源值(CPU和内存)的20%,这样集群能够提供更好的资源一致性的调度,从而减少了资源浪费。
LimitRange可以用来限制Pod,也可以限制Container。下面我们以一个例子来详细说明。
配置LimitRange
(1)、首先创建一个namespace
apiVersion:v1
kind:Namespace
metadata:
name:coolops
(2)、为namespace配置LimitRange
apiVersion:v1
kind:LimitRange
metadata:
name:mylimit
namespace:coolops
spec:
limits:
- max:
cpu:"1"
memory:1Gi
min:
cpu:100m
memory:10Mi
maxLimitRequestRatio:
cpu:3
memory:4
type:Pod
- default:
cpu:300m
memory:200Mi
defaultRequest:
cpu:200m
memory:100Mi
max:
cpu:"2"
memory:1Gi
min:
cpu:100m
memory:10Mi
maxLimitRequestRatio:
cpu:5
memory:4
type:Container
参数说明:
- max:如果type是Pod,则表示pod中所有容器资源的Limit值和的上限,也就是整个pod资源的最大Limit,如果pod定义中的Limit值大于LimitRange中的值,则pod无法成功创建。如果type是Container,意义类似。
- min:如果type是Pod,则表示pod中所有容器资源请求总和的下限,也就是所有容器request的资源总和不能小于min中的值,否则pod无法成功创建。如果type是Container,意义类似。
- maxLimitRequestRatio:如果type是Pod,表示pod中所有容器资源请求的Limit值和request值比值的上限,例如该pod中cpu的Limit值为3,而request为0.5,此时比值为6,创建pod将会失败。
- defaultrequest和defaultlimit则是默认值,只有type为Container才有这两项配置
注意:(1)、如果container设置了max, pod中的容器必须设置limit,如果未设置,则使用defaultlimt的值,如果defaultlimit也没有设置,则无法成功创建 (2)、如果设置了container的min,创建容器的时候必须设置request的值,如果没有设置,则使用defaultrequest,如果没有defaultrequest,则默认等于容器的limit值,如果limit也没有,启动就会报错
创建上面配置的LimitRange:
# kubectl apply -f limitrange.yaml
limitrange/mylimitcreated
# kubectl get limitrange -n coolops
NAMECREATEDAT
mylimit2020-03-26T09:46:33Z
# kubectl describe limitranges -n coolops mylimit
Name:mylimit
Namespace:coolops
TypeResourceMinMaxDefaultRequestDefaultLimitMaxLimit/RequestRatio
---------------------------------------------------------------------
Podmemory10Mi1Gi--4
Podcpu100m1--3
Containercpu100m2200m300m5
Containermemory10Mi1Gi100Mi200Mi4
测试LimitRange
(1)、创建一个允许范围之内的requests和limits的pod
apiVersion:v1
kind:Pod
metadata:
name:pod01
namespace:coolops
spec:
containers:
- name:pod-01
image:nginx
imagePullPolicy:IfNotPresent
resources:
requests:
cpu:200m
memory:30Mi
limits:
cpu:300m
memory:50Mi
我们通过kubectl apply -f pod-01.yaml可以正常创建Pod。
(2)、创建一个cpu超出允许访问的Pod
apiVersion:v1
kind:Pod
metadata:
name:pod02
namespace:coolops
spec:
containers:
- name:pod-02
image:nginx
imagePullPolicy:IfNotPresent
resources:
requests:
cpu:200m
memory:30Mi
limits:
cpu:2
memory:50Mi
然后我们创建会报如下错误:
# kubectl apply -f pod-02.yaml
Errorfromserver(Forbidden):errorwhencreating"pod-02.yaml":pods"pod02"isforbidden:[maximumcpuusageperPodis1,butlimitis2,cpumaxlimittorequestratioperPodis3,butprovidedratiois10.000000,cpumaxlimittorequestratioperContaineris5,butprovidedratiois10.000000]
(3)创建低于允许范围的Pod
apiVersion:v1
kind:Pod
metadata:
name:pod03
namespace:coolops
spec:
containers:
- name:pod-03
image:nginx
imagePullPolicy:IfNotPresent
resources:
requests:
cpu:200m
memory:30Mi
limits:
cpu:100m
memory:10Mi
然后会报如下错误:
# kubectl apply -f pod-03.yaml
ThePod"pod03"isinvalid:
*spec.containers[0].resources.requests:Invalidvalue:"200m":mustbelessthanorequaltocpulimit
*spec.containers[0].resources.requests:Invalidvalue:"30Mi":mustbelessthanorequaltomemorylimit
(4)、创建一个未定义request或Limits的Pod
apiVersion:v1
kind:Pod
metadata:
name:pod04
namespace:coolops
spec:
containers:
- name:pod-04
image:nginx
imagePullPolicy:IfNotPresent
resources:
requests:
cpu:200m
memory:200Mi
然后我们创建完Pod后会发现自动给我们加上了limits。如下:
# kubectl describe pod -n coolops pod04
...
Limits:
cpu:300m
memory:200Mi
Requests:
cpu:200m
memory:200Mi
...
上面我指定了requests,LimitRange自动给我们加上了defaultLimits,你也可以试一下全都不加或者加一个,道理是一样的。值得注意的是这里要注意一下我们设置的maxLimitRequestRatio,配置的比列必须小于等于我们设置的值。
上文有介绍LimitRange还可以限制还可以限制PVC,如下:
apiVersion:v1
kind:LimitRange
metadata:
name:storagelimits
namespace:coolops
spec:
limits:
- type:PersistentVolumeClaim
max:
storage:2Gi
min:
storage:1Gi
创建完后即可查看:
kubectldescribelimitranges-ncoolopsstoragelimits
Name:storagelimits
Namespace:coolops
TypeResourceMinMaxDefaultRequestDefaultLimitMaxLimit/RequestRatio
---------------------------------------------------------------------
PersistentVolumeClaimstorage1Gi2Gi---
你可以创建PVC进行测试,道理是一样的。
注意:在阿里云ack里这样是不行的
评论区