概述
在默认情况下,Kubernetes不会对Pod加上CPU和内存限制,这意味着Kubernetes系统中任何Pod都可以使用其所在节点的所有可用的CPU和内存。在之前的章节https://blog.csdn.net/margu_168/article/details/131786000
分享了针对集群中某个pod的资源限制,通过配置容器的计算资源Requests和Limits,我们可以限制Pod的资源使用。但对于Kubernetes集群管理员而言,配置每一个Pod的Requests和Limits是烦琐的,而且很受限制。针对这样的情况Kubernetes提出了LimitRange,用来限制 namespace中单个Pod 默认资源 request 和 limit。
LimitRange限制范围
一个 LimitRange(限制范围) 对象提供的限制能够做到:
- 限制namespace中每个Pod或容器的最小与最大的资源使用量
- 限制namespace中每个Pod或容器计算资源request、limit之间的比例
- 限制namespace中每个存储卷声明(PersistentVolumeClaim)可使用的最小与最大存储空间
- 设置namespace中容器默认计算资源的request、limit,并在运行时自动注入到容器中
资源限制和请求的约束
- 管理员在一个命名空间内创建一个 LimitRange 对象。
- 用户在此命名空间内创建(或尝试创建) Pod 和 PersistentVolumeClaim 等对象。
- 首先,LimitRanger 准入控制器对所有没有设置计算资源需求的所有 Pod(及其容器)设置默认请求值与限制值。
- 其次,LimitRange 跟踪其使用量以保证没有超出命名空间中存在的任意 LimitRange 所定义的最小、最大资源使用量以及使用量比值。
- 若尝试创建或更新的对象(Pod 和 PersistentVolumeClaim)违反了 LimitRange 的约束, 向 API 服务器的请求会失败,并返回 HTTP 状态码 403 Forbidden 以及描述哪一项约束被违反的消息。
- 若在命名空间中添加 LimitRange 启用了对 cpu 和 memory 等计算相关资源的限制, 你必须指定这些值的请求使用量与限制使用量。否则,系统将会拒绝创建 Pod。
- LimitRange 的验证仅在 Pod 准入阶段进行,不对正在运行的 Pod 进行验证。 如果你添加或修改 LimitRange,命名空间中已存在的 Pod 将继续不变。
- 如果命名空间中存在两个或更多 LimitRange 对象,应用哪个默认值是不确定的。
Pod 的 LimitRange 和准入检查
LimitRange 不 检查所应用的默认值的一致性。 这意味着 LimitRange 设置的 limit 的默认值可能小于客户端提交给 API 服务器的规约中为容器指定的 request 值。 如果发生这种情况,最终 Pod 将无法调度。
示例
定义如下一个 LimitRange: -
[root@k8s-m1 k8s-resource]# cat example-limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: myspace-limitrange
namespace: myspace
spec:
limits:
- type: Container #限制的资源类型
max:
cpu: "1" #限制单个容器的最大CPU
memory: "2Gi" #限制单个容器的最大内存
min:
cpu: "100m" #限制单个容器的最小CPU
memory: "0.3Gi" #限制单个容器的最小内存
default:
cpu: "400m" #默认单个容器的CPU限制
memory: "1Gi" #默认单个容器的内存限制
defaultRequest:
cpu: "200m" #默认单个容器的CPU创建请求
memory: "0.5Gi" #默认单个容器的内存创建请求
maxLimitRequestRatio:
cpu: 2 #限制CPU limit/request比值最大为2
memory: 2 #限制内存limit/request比值最大为2
- type: Pod
max:
cpu: "2" #限制单个Pod的最大CPU
memory: "4Gi" #限制单个Pod最大内存
- type: PersistentVolumeClaim
max:
storage: 20Gi #限制PVC最大的requests.storage
min:
storage: 5Gi #限制PVC最小的requests.storage
[root@k8s-m1 k8s-resource]# kubectl apply -f example-limitrange.yaml
limitrange/myspace-limitrange created
[root@k8s-m1 k8s-resource]# kubectl get limitranges -n myspace
NAME CREATED AT
myspace-limitrange 2023-07-19T12:10:58Z
[root@k8s-m1 k8s-resource]# kubectl describe -n myspace limitranges myspace-limitrange
Name: myspace-limitrange
Namespace: myspace
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 1 200m 400m 2
Container memory 322122547200m 2Gi 512Mi 1Gi 2
Pod cpu - 2 - - -
Pod memory - 4Gi - - -
PersistentVolumeClaim storage 5Gi 20Gi - - -
创建一个没有声明内存请求和限制的 Pod
这里给出了定义一个容器的 Pod 的配置文件。容器没有声明内存请求,也没有声明内存限制。
[root@k8s-m1 k8s-resource]# cat no-request-limit-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: no-request-limit-pod
namespace: myspace
spec:
containers:
- name: no-request-limit-pod
image: nginx
[root@k8s-m1 k8s-resource]# kubectl apply -f no-request-limit-pod.yaml
pod/no-request-limit-pod created
[root@k8s-m1 k8s-resource]# kubectl describe po -n myspace no-request-limit-pod
......
Limits:
cpu: 400m
memory: 1Gi
Requests:
cpu: 200m
memory: 512Mi
Environment: <none>
......
从describe结果可以发现limit和request都是按照当前命名空间下limitrange配置的设置。
定义一个container的CPU 资源请求为 600m 但未声明限制值的 Pod:
[root@k8s-m1 k8s-resource]# cat outcpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: example-out-limitrange-cpu-pod
namespace: myspace
spec:
containers:
- name: http
image: nginx
resources:
requests:
cpu: 600m
[root@k8s-m1 k8s-resource]# kubectl apply -f outcpu-pod.yaml
The Pod "example-out-limitrange-cpu-pod" is invalid: spec.containers[0].resources.requests: Invalid value: "600m": must be less than or equal to cpu limit
#通过返回的报错可以发现原因,requests需要小于cpu limit(600>400)
同时设置了 request 和 limit,那么即使使用相同的 LimitRange,新 Pod 也会被成功调度,对比上面的区别:
[root@k8s-m1 k8s-resource]# cat request-limit-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: example-conflict-limitrange-cpu-mem-pod
namespace: myspace
spec:
containers:
- name: http
image: nginx
resources:
requests:
cpu: 600m
limits:
cpu: 600m
[root@k8s-m1 k8s-resource]# kubectl apply -f request-limit-pod.yaml
pod/example-conflict-limitrange-cpu-mem-pod created
创建一个LimitRange对maxLimitRequestRatio比例操过限制的Pod,我们会发现Pod会创建失败;
[root@k8s-m1 k8s-resource]# cat outmaxlimitrequestratio-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: outmaxlimitrequestratio-pod
namespace: myspace
labels:
name: outmaxlimitrequestratio-pod
spec:
containers:
- name: http
image: nginx
resources:
limits:
cpu: "600m"
memory: 1.5Gi
requests:
cpu: "200m"
memory: 0.5Gi
[root@k8s-m1 k8s-resource]# kubectl apply -f outmaxlimitrequestratio-pod.yaml
Error from server (Forbidden): error when creating "outmaxlimitrequestratio-pod.yaml": pods "outmaxlimitrequestratio-pod" is forbidden: [cpu max limit to request ratio per Container is 2, but provided ratio is 3.000000, memory max limit to request ratio per Container is 2, but provided ratio is 3.000000]
在比例范围之内的就可以正常创建,如下:
##比例为1.5,小于2(0.75/0.5 300/200)
[root@k8s-m1 k8s-resource]# cat outmaxlimitrequestratio-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: outmaxlimitrequestratio-pod
namespace: myspace
labels:
name: outmaxlimitrequestratio-pod
spec:
containers:
- name: http
image: nginx
resources:
limits:
cpu: "300m"
memory: 0.75Gi
requests:
cpu: "200m"
memory: 0.5Gi
[root@k8s-m1 k8s-resource]# kubectl apply -f outmaxlimitrequestratio-pod.yaml
pod/outmaxlimitrequestratio-pod created
更多关于request和limit的设置请根据实际使用情况调试。
更多关于kubernetes的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出