【kubernetes系列】Kubernetes之资源配置范围管理LimitRange

概述

在默认情况下,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的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出

你可能感兴趣的:(Kubernetes,kubernetes,容器,云原生)