LimitRange and ResourceQuota Interaction in Kubernetes

📘 Introduction

In Kubernetes, both ResourceQuota and LimitRange are mechanisms used to manage resource usage within a namespace. While they both help enforce resource constraints, they serve different purposes:

  • ResourceQuota: Limits the overall resource consumption for a namespace (like CPU, memory, the number of objects).
  • LimitRange: Sets constraints for individual pod/container resource requests and limits within a namespace.

This document explains their interaction and how they work together to ensure resource management policies in a Kubernetes cluster.


🧠 Key Concepts

1. ResourceQuota Overview

A ResourceQuota defines limits on the total amount of resources that can be consumed by objects within a namespace. It is usually applied to limit the usage of:

  • CPU
  • Memory
  • Storage
  • Number of objects (pods, services, PVCs, etc.)

Example YAML for ResourceQuota:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
spec:
  hard:
    cpu: "4"
    memory: "8Gi"
    pods: "10"
    services: "5"
    persistentvolumeclaims: "2"

2. LimitRange Overview

A LimitRange defines the default and maximum/minimum resource requests and limits for containers within a namespace. It allows you to specify:

  • Default CPU/memory requests and limits for containers that do not specify them.
  • Maximum/Minimum resource limits that containers can request/consume.

Example YAML for LimitRange:

apiVersion: v1
kind: LimitRange
metadata:
  name: my-limits
spec:
  limits:
  - max:
      cpu: "1"
      memory: "2Gi"
    min:
      cpu: "100m"
      memory: "256Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container


🔍 Interaction Between ResourceQuota and LimitRange

1. ResourceQuota and LimitRange Together

When both ResourceQuota and LimitRange are used within a namespace, they complement each other:

  • ResourceQuota tracks the total resource usage for the namespace, limiting the overall consumption of resources (e.g., CPU, memory, storage, number of objects).
  • LimitRange sets rules for individual containers/pods, specifying what resource requests and limits should be for each container.

2. How They Work Together

  • LimitRange ensures that containers within the namespace request and use resources within the specified limits (e.g., minimum/maximum).
  • ResourceQuota ensures that the total resources consumed by all objects in the namespace do not exceed the set quota.

For example, if a ResourceQuota limits the total CPU usage to 4 cores and memory to 8Gi, and a LimitRange defines the maximum CPU usage per container as 1 core and memory as 2Gi, the total number of containers that can be created is constrained by both:

  1. The number of containers (ResourceQuota).
  2. The resource consumption of each container (LimitRange).

🛠️ YAML Examples for Interaction

1. ResourceQuota Example:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
spec:
  hard:
    cpu: "4"
    memory: "8Gi"
    pods: "10"
    services: "5"
    persistentvolumeclaims: "2"

This ResourceQuota limits:

  • CPU usage to 4 cores.
  • Memory usage to 8Gi.
  • Pods in the namespace to 10.
  • Services to 5.
  • Persistent Volume Claims (PVCs) to 2.

2. LimitRange Example:

apiVersion: v1
kind: LimitRange
metadata:
  name: my-limits
spec:
  limits:
  - max:
      cpu: "1"
      memory: "2Gi"
    min:
      cpu: "100m"
      memory: "256Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container

This LimitRange defines:

  • Max limits for containers: 1 CPU and 2Gi memory.
  • Min limits for containers: 100m CPU and 256Mi memory.
  • Default limits if not specified: 500m CPU and 1Gi memory.
  • Default requests if not specified: 200m CPU and 512Mi memory.

3. Combined Effect Example

If you try to create a pod with more than the allowed resources (e.g., 2 CPU and 3Gi memory), the pod creation will be blocked by the LimitRange because it exceeds the maximum limits specified.

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: mycontainer
    image: nginx
    resources:
      requests:
        cpu: "200m"
        memory: "500Mi"
      limits:
        cpu: "2"
        memory: "3Gi"

In this case, the pod creation will fail because the resource limits exceed the maximums set by the LimitRange (1 CPU and 2Gi memory).

4. Namespace with Both ResourceQuota and LimitRange

apiVersion: v1
kind: Namespace
metadata:
  name: mynamespace
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
  namespace: mynamespace
spec:
  hard:
    cpu: "4"
    memory: "8Gi"
    pods: "10"
    services: "5"
    persistentvolumeclaims: "2"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: my-limits
  namespace: mynamespace
spec:
  limits:
  - max:
      cpu: "1"
      memory: "2Gi"
    min:
      cpu: "100m"
      memory: "256Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container

Here, both ResourceQuota and LimitRange are applied to the mynamespace namespace:

  • ResourceQuota limits the total resource consumption for the namespace.
  • LimitRange controls the resource requests/limits for each individual container within the namespace.

🔍 Policy Interactions

1. Enforcing Fair Resource Usage

By combining ResourceQuota and LimitRange, Kubernetes ensures that resources are used fairly and efficiently within a namespace. The LimitRange guarantees that containers have resource requests and limits set, while ResourceQuota ensures that the namespace as a whole does not exceed the specified resource limits.

2. Example of Conflict:

If the LimitRange specifies a maximum of 1 CPU per container and a ResourceQuota allows for a total of 4 CPU in the namespace, and you try to create a pod that requests 2 CPU, the pod will fail because it exceeds the maximum allowed by LimitRange, even though the ResourceQuota would allow it.


✅ Best Practices

  • Use ResourceQuota when you want to limit total resource consumption in a namespace (CPU, memory, number of objects).
  • Use LimitRange to enforce resource requests and limits for individual containers/pods, ensuring resource fairness.
  • Use both together to enforce policies at both the namespace level (ResourceQuota) and the container level (LimitRange).
  • Always monitor resource usage to ensure that the limits set by both ResourceQuota and LimitRange are aligned with your system's overall needs and goals.

🤝 Final Thoughts

The combination of ResourceQuota and LimitRange provides a powerful way to manage resources in Kubernetes. By setting both namespace-wide quotas and container-specific resource constraints, you can ensure that your clusters are optimized for resource usage and avoid resource contention.