Limit Ranges

    A LimitRange provides constraints that can:

    • Enforce minimum and maximum compute resources usage per Pod or Container in a namespace.
    • Enforce minimum and maximum storage request per PersistentVolumeClaim in a namespace.
    • Enforce a ratio between request and limit for a resource in a namespace.
    • Set default request/limit for compute resources in a namespace and automatically inject them to Containers at runtime.

    LimitRange support is enabled by default for many Kubernetes distributions. It is enabled when the apiserver flag has LimitRanger admission controller as one of its arguments.

    A LimitRange is enforced in a particular namespace when there is a LimitRange object in that namespace.

    The name of a LimitRange object must be a valid DNS subdomain name.

    • The administrator creates one LimitRange in one namespace.
    • Users create resources like Pods, Containers, and PersistentVolumeClaims in the namespace.
    • The LimitRanger admission controller enforces defaults and limits for all Pods and Containers that do not set compute resource requirements and tracks usage to ensure it does not exceed resource minimum, maximum and ratio defined in any LimitRange present in the namespace.
    • If creating or updating a resource (Pod, Container, PersistentVolumeClaim) that violates a LimitRange constraint, the request to the API server will fail with an HTTP status code 403 FORBIDDEN and a message explaining the constraint that have been violated.
    • If a LimitRange is activated in a namespace for compute resources like cpu and memory, users must specify requests or limits for those values. Otherwise, the system may reject Pod creation.
    • LimitRange validations occurs only at Pod Admission stage, not on Running Pods.

    Examples of policies that could be created using limit range are:

    • In a 2 node cluster with a capacity of 8 GiB RAM and 16 cores, constrain Pods in a namespace to request 100m of CPU with a max limit of 500m for CPU and request 200Mi for Memory with a max limit of 600Mi for Memory.
    • Define default CPU limit and request to 150m and memory default request to 300Mi for Containers started with no cpu and memory requests in their specs.

    In the case where the total limits of the namespace is less than the sum of the limits of the Pods/Containers, there may be contention for resources. In this case, the Containers or Pods will not be created.

    Neither contention nor changes to a LimitRange will affect already created resources.

    Limiting Container compute resources

    The following section discusses the creation of a LimitRange acting at Container Level. A Pod with 04 Containers is first created. Each Container within the Pod has a specific spec.resource configuration. Each Container within the Pod is handled differently by the LimitRanger admission controller.

    Create a namespace limitrange-demo using the following kubectl command:

    To avoid passing the target limitrange-demo in your kubectl commands, change your context with the following command:

    1. kubectl config set-context --current --namespace=limitrange-demo

    Here is the configuration file for a LimitRange object:

    This object defines minimum and maximum CPU/Memory limits, default CPU/Memory requests, and default limits for CPU/Memory resources to be apply to containers.

    Create the limit-mem-cpu-per-container LimitRange in the limitrange-demo namespace with the following kubectl command:

    1. kubectl create -f https://k8s.io/examples/admin/resource/limit-mem-cpu-container.yaml -n limitrange-demo
    1. kubectl describe limitrange/limit-mem-cpu-per-container -n limitrange-demo
    1. Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
    2. ---- -------- --- --- --------------- ------------- -----------------------
    3. Container cpu 100m 800m 110m 700m -
    4. Container memory 99Mi 1Gi 111Mi 900Mi -
    admin/resource/limit-range-pod-1.yaml
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: busybox1
    5. spec:
    6. containers:
    7. - name: busybox-cnt01
    8. image: busybox
    9. command: [“/bin/sh”]
    10. args: [“-c”, while true; do echo hello from cnt01; sleep 10;done”]
    11. resources:
    12. requests:
    13. memory: 100Mi
    14. cpu: 100m
    15. limits:
    16. memory: 200Mi
    17. cpu: 500m
    18. - name: busybox-cnt02
    19. image: busybox
    20. command: [“/bin/sh”]
    21. args: [“-c”, while true; do echo hello from cnt02; sleep 10;done”]
    22. resources:
    23. requests:
    24. memory: 100Mi
    25. cpu: 100m
    26. - name: busybox-cnt03
    27. image: busybox
    28. command: [“/bin/sh”]
    29. args: [“-c”, while true; do echo hello from cnt03; sleep 10;done”]
    30. resources:
    31. limits:
    32. memory: 200Mi
    33. cpu: 500m
    34. - name: busybox-cnt04
    35. image: busybox
    36. command: [“/bin/sh”]
    37. args: [“-c”, while true; do echo hello from cnt04; sleep 10;done”]

    Create the busybox1 Pod:

    1. kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-1.yaml -n limitrange-demo

    Container spec with valid CPU/Memory requests and limits

    View the busybox-cnt01 resource configuration:

    1. kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[0].resources"
    1. {
    2. "limits": {
    3. "cpu": "500m",
    4. "memory": "200Mi"
    5. },
    6. "cpu": "100m",
    7. "memory": "100Mi"
    8. }
    9. }
    • The busybox-cnt01 Container inside busybox Pod defined requests.cpu=100m and requests.memory=100Mi.
    • 100m <= 500m <= 800m , The Container cpu limit (500m) falls inside the authorized CPU LimitRange.
    • 99Mi <= 200Mi <= 1Gi , The Container memory limit (200Mi) falls inside the authorized Memory LimitRange.
    • No request/limits ratio validation for CPU/Memory, so the Container is valid and created.

    View the busybox-cnt02 resource configuration

    1. kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[1].resources"
    1. {
    2. "limits": {
    3. "cpu": "700m",
    4. "memory": "900Mi"
    5. },
    6. "requests": {
    7. "cpu": "100m",
    8. "memory": "100Mi"
    9. }
    • The busybox-cnt02 Container inside busybox1 Pod defined requests.cpu=100m and requests.memory=100Mi but not limits for cpu and memory.
    • The Container does not have a limits section. The default limits defined in the limit-mem-cpu-per-container LimitRange object are injected in to this Container: limits.cpu=700mi and limits.memory=900Mi.
    • 100m <= 700m <= 800m , The Container cpu limit (700m) falls inside the authorized CPU limit range.
    • 99Mi <= 900Mi <= 1Gi , The Container memory limit (900Mi) falls inside the authorized Memory limit range.
    • No request/limits ratio set, so the Container is valid and created.

    Container spec with a valid CPU/Memory limits but no requests

    View the busybox-cnt03 resource configuration:

    1. kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[2].resources"
    1. {
    2. "limits": {
    3. "cpu": "500m",
    4. "memory": "200Mi"
    5. },
    6. "requests": {
    7. "cpu": "500m",
    8. "memory": "200Mi"
    9. }
    10. }
    • The busybox-cnt03 Container inside busybox1 Pod defined limits.cpu=500m and limits.memory=200Mi but no requests for cpu and memory.
    • The Container does not define a request section. The default request defined in the limit-mem-cpu-per-container LimitRange is not used to fill its limits section, but the limits defined by the Container are set as requests limits.cpu=500m and limits.memory=200Mi.
    • 100m <= 500m <= 800m , The Container cpu limit (500m) falls inside the authorized CPU limit range.
    • 99Mi <= 200Mi <= 1Gi , The Container memory limit (200Mi) falls inside the authorized Memory limit range.
    • No request/limits ratio set, so the Container is valid and created.

    View the busybox-cnt04 resource configuration:

    1. {
    2. "limits": {
    3. "cpu": "700m",
    4. "memory": "900Mi"
    5. },
    6. "requests": {
    7. "cpu": "110m",
    8. "memory": "111Mi"
    9. }
    10. }
    • The busybox-cnt04 Container inside busybox1 define neither limits nor requests.
    • The Container do not define a limit section, the default limit defined in the limit-mem-cpu-per-container LimitRange is used to fill its request limits.cpu=700m and limits.memory=900Mi .
    • The Container do not define a request section, the defaultRequest defined in the limit-mem-cpu-per-container LimitRange is used to fill its request section requests.cpu=110m and requests.memory=111Mi
    • 100m <= 700m <= 800m , The Container cpu limit (700m) falls inside the authorized CPU limit range.
    • 99Mi <= 900Mi <= 1Gi , The Container memory limit (900Mi) falls inside the authorized Memory limit range .
    • No request/limits ratio set, so the Container is valid and created.

    All Containers defined in the busybox Pod passed LimitRange validations, so this the Pod is valid and created in the namespace.

    The following section discusses how to constrain resources at the Pod level.

    Limit Ranges (EN) - 图3
    1. apiVersion: v1
    2. kind: LimitRange
    3. metadata:
    4. name: limit-mem-cpu-per-pod
    5. spec:
    6. limits:
    7. - max:
    8. cpu: 2
    9. memory: 2Gi
    10. type: Pod

    Without having to delete the busybox1 Pod, create the limit-mem-cpu-pod LimitRange in the limitrange-demo namespace:

    1. kubectl apply -f https://k8s.io/examples/admin/resource/limit-mem-cpu-pod.yaml -n limitrange-demo

    The LimitRange is created and limits CPU to 2 Core and Memory to 2Gi per Pod:

    1. limitrange/limit-mem-cpu-per-pod created

    Describe the limit-mem-cpu-per-pod limit object using the following kubectl command:

    1. kubectl describe limitrange/limit-mem-cpu-per-pod
    1. Name: limit-mem-cpu-per-pod
    2. Namespace: limitrange-demo
    3. Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
    4. ---- -------- --- --- --------------- ------------- -----------------------
    5. Pod cpu - 2 - - -
    6. Pod memory - 2Gi - - -

    Now create the busybox2 Pod:

    1. kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-2.yaml -n limitrange-demo

    The busybox2 Pod definition is identical to busybox1, but an error is reported since the Pod’s resources are now limited:

    1. Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]
    1. kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[].resources.limits.memory"
    2. "200Mi"
    3. "900Mi"
    4. "200Mi"
    5. "900Mi"

    busybox2 Pod will not be admitted on the cluster since the total memory limit of its Container is greater than the limit defined in the LimitRange. busybox1 will not be evicted since it was created and admitted on the cluster before the LimitRange creation.

    Limiting Storage resources

    1. apiVersion: v1
    2. kind: LimitRange
    3. metadata:
    4. name: storagelimits
    5. spec:
    6. limits:
    7. - type: PersistentVolumeClaim
    8. max:
    9. storage: 2Gi
    10. min:
    11. storage: 1Gi

    Apply the YAML using kubectl create:

    1. kubectl create -f https://k8s.io/examples/admin/resource/storagelimits.yaml -n limitrange-demo
    1. limitrange/storagelimits created

    Describe the created object:

    The output should look like:

    1. Name: storagelimits
    2. Namespace: limitrange-demo
    3. Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
    4. ---- -------- --- --- --------------- ------------- -----------------------
    5. PersistentVolumeClaim storage 1Gi 2Gi - - -
    admin/resource/pvc-limit-lower.yaml Limit Ranges (EN) - 图6
    1. apiVersion: v1
    2. kind: PersistentVolumeClaim
    3. metadata:
    4. name: pvc-limit-lower
    5. spec:
    6. accessModes:
    7. - ReadWriteOnce
    8. resources:
    9. requests:
    10. storage: 500Mi
    1. kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-lower.yaml -n limitrange-demo

    While creating a PVC with requests.storage lower than the Min value in the LimitRange, an Error thrown by the server:

    1. Error from server (Forbidden): error when creating "pvc-limit-lower.yaml": persistentvolumeclaims "pvc-limit-lower" is forbidden: minimum storage usage per PersistentVolumeClaim is 1Gi, but request is 500Mi.

    Same behaviour is noted if the requests.storage is greater than the Max value in the LimitRange:

    1. kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-greater.yaml -n limitrange-demo
    1. Error from server (Forbidden): error when creating "pvc-limit-greater.yaml": persistentvolumeclaims "pvc-limit-greater" is forbidden: maximum storage usage per PersistentVolumeClaim is 2Gi, but request is 5Gi.

    If LimitRangeItem.maxLimitRequestRatio is specified in the LimitRangeSpec, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value.

    The following LimitRange enforces memory limit to be at most twice the amount of the memory request for any Pod in the namespace:

    1. apiVersion: v1
    2. kind: LimitRange
    3. metadata:
    4. name: limit-memory-ratio-pod
    5. spec:
    6. limits:
    7. - maxLimitRequestRatio:
    8. memory: 2
    9. type: Pod
    1. kubectl apply -f https://k8s.io/examples/admin/resource/limit-memory-ratio-pod.yaml

    Describe the LimitRange with the following kubectl command:

    1. kubectl describe limitrange/limit-memory-ratio-pod
    1. Name: limit-memory-ratio-pod
    2. Namespace: limitrange-demo
    3. Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
    4. ---- -------- --- --- --------------- ------------- -----------------------
    5. Pod memory - - - - 2

    Create a pod with requests.memory=100Mi and limits.memory=300Mi:

    admin/resource/limit-range-pod-3.yaml Limit Ranges (EN) - 图9
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: busybox3
    5. spec:
    6. containers:
    7. - name: busybox-cnt01
    8. image: busybox
    9. resources:
    10. limits:
    11. memory: 300Mi
    12. requests:
    13. memory: 100Mi
    1. kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-3.yaml

    The pod creation failed as the ratio here (3) is greater than the enforced limit (2) in limit-memory-ratio-pod LimitRange:

    Clean up

    Delete the namespace to free all resources:

    1. kubectl delete ns limitrange-demo

    Examples

    See for more information.

    Feedback

    Was this page helpful?