kubernetes: enforce resource limits using LimitRange

3 min read

If we want to make sure the resources for a given namespace are controlled yet we want to be able to give full control to whoever is creating objects in that namespace, we can use LimitRange to enforce some resource constraints:

  • We can enforce a minimum and maximum (and it's default value) for compute resources per Pod or Container or storage request per PersistentVolumeClaim in the namespace
  • We can also enfornce a ratio between request and limit for a resource (so that we are not abusing the control setting limits that are too wide) Set default request/limit for compute resources in a namespace and automatically inject them to Containers at runtime.

This is implemented as an admission controller that observes the incoming requests and makes sure that it does not violate any of the constraints enumerated in the LimitRange object within it's namespace.

Using kubectl describe ns we can check whether there is already a LimitRange enforce resource limits on the namespace:

$ kubectl describe ns demo
Name:         demo
Labels:       <none>
Annotations:  <none>
Status:       Active

No resource quota.

No LimitRange resource.

If we want to set it, we just need to create a LimitRange object on the namespace, for example:

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-min-max-demo-lr
spec:
  limits:
  - max:
      cpu: "800m"
    min:
      cpu: "200m"
    type: Container

If we apply it and the get back al describing the namespace we will be able to see the resource limits we have defined:

$ kubectl apply -f limits.yaml  -n demo
limitrange/cpu-min-max-demo-lr created
$ kubectl describe ns demo
Name:         demo
Labels:       <none>
Annotations:  <none>
Status:       Active

No resource quota.

Resource Limits
 Type       Resource  Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
 ----       --------  ---   ---   ---------------  -------------  -----------------------
 Container  cpu       200m  800m  800m             800m           -

We can also set a default resource request / limit. For example:

apiVersion: v1
kind: LimitRange
metadata:
  name: demo-defaults
spec:
  limits:
  - default:
      cpu: "1000m"
      memory: 1000Mi
    defaultRequest:
      cpu: "500m"
      memory: 600Mi
    type: Container

This LimitRange defines that any pod within the namespace where it is set, if it doesn't specify any resources it will set the following settings:

  • CPU request to 500m
  • Memory request to 600Mi
  • CPU limit to 1000m
  • Memory limit to 1000Mi

We can check it using kubectl describe ns:

$ kubectl describe ns spinnaker-green
Name:         demo
Labels:       <none>
Annotations:  <none>
Status:       Active

No resource quota.

Resource Limits
 Type       Resource  Min  Max  Default Request  Default Limit  Max Limit/Request Ratio
 ----       --------  ---  ---  ---------------  -------------  -----------------------
 Container  cpu       -    -    500m             1              -
 Container  memory    -    -    600Mi            1000Mi         -

On the kubernetes documentation for Limit Ranges we will be able to get all the details.


Posted on 02/06/2021