微信公众号:运维开发故事,作者:乔克
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-demoreplicas:2template:metadata:labels:app:ng-demospec:containers:- name:ng-demoimage:nginximagePullPolicy:IfNotPresentresources:requests:cpu:100mmemory:216Milimits:cpu:100mmemory: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:mylimitnamespace:coolops
spec:limits:- max:cpu:"1"memory:1Gimin:cpu:100mmemory:10MimaxLimitRequestRatio:cpu:3memory:4type:Pod- default:cpu:300mmemory:200MidefaultRequest:cpu:200mmemory:100Mimax:cpu:"2"memory:1Gimin:cpu:100mmemory:10MimaxLimitRequestRatio:cpu:5memory:4type: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:pod01namespace:coolops
spec:containers:- name:pod-01image:nginximagePullPolicy:IfNotPresentresources:requests:cpu:200mmemory:30Milimits:cpu:300mmemory:50Mi
我们通过kubectl apply -f pod-01.yaml
可以正常创建Pod。
(2)、创建一个cpu超出允许访问的Pod
apiVersion:v1
kind:Pod
metadata:name:pod02namespace:coolops
spec:containers:- name:pod-02image:nginximagePullPolicy:IfNotPresentresources:requests:cpu:200mmemory:30Milimits:cpu:2memory: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:pod03namespace:coolops
spec:containers:- name:pod-03image:nginximagePullPolicy:IfNotPresentresources:requests:cpu:200mmemory:30Milimits:cpu:100mmemory: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:pod04namespace:coolops
spec:containers:- name:pod-04image:nginximagePullPolicy:IfNotPresentresources:requests:cpu:200mmemory:200Mi
然后我们创建完Pod后会发现自动给我们加上了limits。如下:
# kubectl describe pod -n coolops pod04
...Limits:cpu:300mmemory:200MiRequests:cpu:200mmemory:200Mi
...
上面我指定了requests,LimitRange自动给我们加上了defaultLimits,你也可以试一下全都不加或者加一个,道理是一样的。值得注意的是这里要注意一下我们设置的maxLimitRequestRatio
,配置的比列必须小于等于我们设置的值。
上文有介绍LimitRange还可以限制还可以限制PVC,如下:
apiVersion:v1
kind:LimitRange
metadata:name:storagelimitsnamespace:coolops
spec:limits:- type:PersistentVolumeClaimmax:storage:2Gimin:storage:1Gi
创建完后即可查看:
kubectldescribelimitranges-ncoolopsstoragelimits
Name:storagelimits
Namespace:coolops
TypeResourceMinMaxDefaultRequestDefaultLimitMaxLimit/RequestRatio
---------------------------------------------------------------------
PersistentVolumeClaimstorage1Gi2Gi---
你可以创建PVC进行测试,道理是一样的。
参考资料
[1] https://kubernetes.io/docs/concepts/policy/limit-range/
[2] 《Kubernetes权威指南》
-----------------------
公众号:乔边故事(ID:qiaobiangushi)
知乎: 乔边故事
头条号:乔边故事
只要脸皮够厚,整个世界都将被你踩在脚下。
-----------------------
扫码二维码关注公众号,不定期维护优质内容,技术干货!
温馨提示
如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。