kubernetes笔记: LimitRanges
by 伊布
前面我们介绍了kubernetes的resourceQuota,现在再来介绍下limitRanges。
Resource Quota区分的粒度是namespace,其目的是为了不同namespace之间的公平,防止某些流氓team占用了太多的资源。而limitRange区分的粒度则是container,则是在为了在同一个namespace下,限制container的最大最小值。另外, 在设置了resourceQuota的namespace下,如果用户创建Pod时没有指定limit/request,默认是无法创建的(403 FORBIDDEN),此时可以通过limitRanges来配置该namespace下容器默认的limit/request。
来看下面这个例子。
先创建一个namespace,并切换到该namespace。
kubectl create namespace limit-example
kubens limit-example
如果你没有装kubens,可以装一个,很好用,很方便。
然后apply下面的编排文件。
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: 512Mi
cpu: 1
defaultRequest:
memory: 256Mi
cpu: 0.5
max:
memory: 1024Mi
cpu: 1
min:
memory: 128Mi
cpu: 0.5
type: Container
说明:
default
:即该namespace配置resourceQuota时,创建container的默认limit上限defaultRequest
:即该namespace配置resourceQuota时,创建container的默认request上限max
:即该namespace下创建container的资源最大值min
:即该namespace下创建container的资源最小值
其中: min <= defaultRequest <= default <= max
其实我觉得default、defaultRequest应该单独拿出来,他们跟max、min的意义区别还是挺大的。
看一下刚创建的limits。
$ kubectl describe limits
Name: limit-range
Namespace: resource-quota
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 500m 1 500m 1 -
Container memory 128Mi 1Gi 256Mi 512Mi -
我没有配置Max Limit/Request Ratio
。
先来看看max
和min
的效果。
apiVersion: v1
kind: Pod
metadata:
name: default-cpu-demo-maxmin
spec:
containers:
- name: default-cpu-demo-ctr-maxmin
image: nginx
resources:
limits:
cpu: "1.1"
memory: 1.1Gi
尝试创建一下,会看到失败信息,提示,超过max啦!
kubectl apply -f nginx-maxmin.yaml
Error from server (Forbidden): error when creating "nginx-maxmin.yaml": pods "default-cpu-demo-maxmin" is forbidden: [maximum cpu usage per Container is 1, but limit is 1100m., maximum memory usage per Container is 1Gi, but limit is 1181116006400m.]
其他类似,不再赘述。
再看看default
和defaultRequest
。
在namespace limit-example下创建下面的Pod。该Pod未指定任何资源信息。
apiVersion: v1
kind: Pod
metadata:
name: default-cpu-demo
spec:
containers:
- name: default-cpu-demo-ctr
image: nginx
创建后来看看其实际资源的情况,可以看到确实是按照上面的limits配置的。
apiVersion: v1
kind: Pod
spec:
containers:
- image: gcr.io/nginx
imagePullPolicy: Always
name: default-cpu-demo-ctr
resources:
limits:
cpu: "1"
memory: 512Mi
requests:
cpu: 500m
memory: 256Mi
注意:如果container只设置了limit,没有设置request,那么最终创建出来的container,其request=limit。而不是想当然的是 default request。
apiVersion: v1
kind: Pod
metadata:
name: default-cpu-demo-maxmin
spec:
containers:
- name: default-cpu-demo-ctr-maxmin
image: nginx
resources:
limits:
cpu: "1"
memory: 1Gi
尝试创建,提示request要求为1核1G,超过defaultRequest限制。
kubectl apply -f nginx-maxmin.yaml
Error from server (Forbidden): error when creating "nginx-maxmin.yaml": pods "default-cpu-demo-maxmin" is forbidden: exceeded quota: compute-resources, requested: requests.cpu=1,requests.memory=1Gi, used: requests.cpu=500m,requests.memory=256Mi, limited: requests.cpu=1,requests.memory=1Gi
为什么要这样设计呢?可能是如果使用defaultRequest,那么必然request<limit,这种container比较容易在节点资源不足的时候被k8s杀死,设计为一致,能更好的提示用户(猜的)。
如果container只设置了request,没设置limit,则最终container的limit为default设置的值。
推荐阅读下 Kubernetes best practices: Resource requests and limits(作者是 Dinesh 哈哈),会对limit、request的设置有更好的理解。
简单来说,request影响的是k8s的调度,也就是说k8s会保证container所request的资源,在调度时会考虑node是否满足request的条件。而limit则是实际运行时k8s的限制,防止container无限制的占用node的资源。显然的,由于调度时更多的考虑了request而不是limit,那么必然会出现某个node上container的limit总和超过该node资源的情况,此时,k8s针对cpu和memory会由不同的处理。
对于cpu,k8s认为cpu是可压缩的,在应用达到limit时,k8s会减少该容器的调度时间,并不会杀死应用。
对于memory,k8s认为memory是无法压缩的,此时k8s会杀死占用资源超过其request的应用(1.9版本之后的版本)。首当其冲的是没有指定request的container,然后是使用资源超过其request更多的container。同等情况下优先级更低的container更容易被杀死。
Ref:
Subscribe via RSS