• By Jock

  • Public account: Operation and maintenance development story

limitRange

LimitRange has a nice Chinese name called “Resource Configuration Access Management”. As anyone who has used K8S knows, by default, K8S does not impose CPU or memory limits on a Pod, which means that an unrestricted Pod can use as much CPU and memory as it wants on the node. If one of the pods leaks memory, this is a very bad thing.

So normally, we would add Requests and Limits to Pod deployments as follows:

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

Copy the code

However, if there are a large number of pods, and many pods only need the same limitation, it would be tedious to add them one by one as above. In this case, we can set a Namespace resource limit with LimitRange. If you specify requests and Limits when deploying a Pod, the requirements take effect. Otherwise, a default limit is applied to the Pod globally.

To summarize, LimitRange can achieve:

  • Limits the minimum and maximum resource usage for each pod or Container in a namespace.

  • Limits the scope of resource requests for each PVC in a namespace.

  • Limits the ratio of resource requests to the number of limits in a namespace.

  • Configure default limits for resources.

After a LimitRange is created, a LimitRange takes effect in the namespace to which it belongs.

Common scenarios are as follows (from the Authoritative Guide to Kubernetes)

  • Each node in the cluster has 2GB of memory, and the cluster administrator does not want any Pod to request more than 2GB of memory: there is no node in the entire cluster that can accommodate more than 2GB of memory. If the memory configuration of a Pod exceeds 2GB, the Pod will never be scheduled for execution on any node. To prevent this from happening, the cluster administrator wants to disable pods from requesting more than 2GB of memory in the system administration function.

  • Clusters are shared by two teams within the same organization, running production and development environments respectively. Production environments can use up to 8GB of memory, while development environments can use up to 512MB. The cluster administrator wants to meet this requirement by creating different namespaces for the two environments and setting different restrictions for each.

  • A user might create a Pod with just a little less than the upper limit of the entire machine’s resources, and just have an awkward amount of resources left: not enough to run other tasks, but very wasteful for the cluster to add up. Therefore, the cluster administrator wants to set each Pod to use at least 20 percent of the average cluster resource value (CPU and memory) so that the cluster can provide better resource consistency scheduling and thus reduce resource waste.

LimitRange can be used to limit pods as well as Containers. Let’s use an example to illustrate.

Configuration LimitRange

(1) Create a namespace

apiVersion:v1
kind:Namespace
metadata:
  name:coolops

Copy the code

(2) Configure LimitRange for namespace

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

Copy the code

Parameter Description:

  • Max: If Type is Pod, it indicates the upper Limit of all container resources in Pod, that is, the maximum Limit of the entire Pod resource. If the Limit value in Pod definition is greater than the value in LimitRange, Pod cannot be created successfully. If type is Container, the meaning is similar.

  • Min: if type is Pod, it indicates the lower limit of the total resource requests of all containers in Pod. That is, the total resource requests of all containers cannot be less than the value in min. Otherwise, Pod cannot be created successfully. If type is Container, the meaning is similar.

  • MaxLimitRequestRatio: If Type is Pod, it indicates the upper Limit of the ratio between the Limit value of resource requests and the Request value of all container resource requests in Pod. For example, if the Limit value of CPU in Pod is 3 and the request value is 0.5, the ratio is 6. Creating Pod will fail.

  • Defaultrequest and DefaultLimit are the default values, which are available only when type is Container

Note: If Max is set for container, pod must set limit. If Max is not set for container, pod must set limit. If Max is not set for container, POD must set limit for container. Request must be set when creating the container. If it is not set, use defaultrequest. If it is not set, it defaults to the limit value of the container

Create LimitRange as configured above:

# 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


Copy the code

Test LimitRange

Create a pod for requests within limits and limits

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

Copy the code

Kubectl apply-f pod-01.yaml creates pods normally.

(2) Create a Pod with more CPU than allowed

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

Copy the code

Then we create the following error:

# kubectl apply -f pod-02.yaml Errorfromserver(Forbidden):errorwhencreating"pod-02.yaml":pods"pod02"isforbidden:[maximumcpuusageperPodis1,butlimitis2,c PumaxlimittorequestratioperPodis3 butprovidedratiois10.000000, cpumaxlimittorequestratioperContaineris5 butprovidedratioi S10.000000]Copy the code

(3) Create pods below the allowed range

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

Copy the code

The following error is reported:

# 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

Copy the code

Create a Pod that does not define Request or Limits

apiVersion:v1
kind:Pod
metadata:
  name:pod04
  namespace:coolops
spec:
  containers:
  - name:pod-04
    image:nginx
    imagePullPolicy:IfNotPresent
    resources:
      requests:
        cpu:200m
        memory:200Mi

Copy the code

Then after we create the Pod, we’ll see that limits is automatically added to us. As follows:

# kubectl describe pod -n coolops pod04
...
    Limits:
      cpu:300m
      memory:200Mi
    Requests:
      cpu:200m
      memory:200Mi
...

Copy the code

LimitRange automatically assigns us defaultLimits. You can also try adding none or just one. It’s the same thing. It’s worth noting here that we set maxLimitRequestRatio, and the configured ratio column must be less than or equal to the value we set.

LimitRange can also limit PVC, as follows:

apiVersion:v1
kind:LimitRange
metadata:
  name:storagelimits
  namespace:coolops
spec:
  limits:
  - type:PersistentVolumeClaim
    max:
      storage:2Gi
    min:
      storage:1Gi

Copy the code

After creation, you can view:

kubectldescribelimitranges-ncoolopsstoragelimits
Name:storagelimits
Namespace:coolops
TypeResourceMinMaxDefaultRequestDefaultLimitMaxLimit/RequestRatio
---------------------------------------------------------------------
PersistentVolumeClaimstorage1Gi2Gi---

Copy the code

You can create a PVC and test it, it’s the same thing.


The resources

[1] kubernetes. IO/docs/concep…

[2] Kubernetes Authoritative Guide