Resource Quotas

Resource quotas limit the total resource consumption within a namespace, preventing one namespace from consuming all cluster resources. They’re essential for multi-tenant clusters, cost control, and ensuring fair resource distribution across teams or applications.

What Are Resource Quotas?

Resource quotas are namespace-scoped objects that define hard limits on resource consumption. They control:

  • Compute resources - CPU and memory requests and limits
  • Storage resources - Persistent volume claims
  • Object counts - Number of pods, services, ConfigMaps, etc.
graph TB A[Namespace] --> B[ResourceQuota] B --> C[CPU Limits] B --> D[Memory Limits] B --> E[Storage Limits] B --> F[Object Count Limits] G[Pod Creation] --> H{Within Quota?} H -->|Yes| I[Pod Created] H -->|No| J[Pod Rejected] style A fill:#e1f5ff style B fill:#fff4e1 style I fill:#e8f5e9 style J fill:#ffe1e1

Why Use Resource Quotas?

Resource quotas provide several benefits:

Multi-Tenancy

Isolate teams or applications by limiting their resource consumption:

  • Prevent one team from consuming all cluster resources
  • Ensure fair resource distribution
  • Enable secure multi-tenant clusters

Cost Control

Limit resource usage to control costs:

  • Prevent runaway resource consumption
  • Enforce budget constraints per namespace
  • Track resource usage per team or project

Resource Planning

Plan and allocate cluster resources:

  • Reserve resources for critical workloads
  • Prevent resource exhaustion
  • Ensure capacity for important applications

Resource Quota Types

Compute Resources

Limit CPU and memory usage:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi

Storage Resources

Limit persistent volume claims:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: storage-quota
  namespace: production
spec:
  hard:
    persistentvolumeclaims: "10"
    requests.storage: 100Gi

Object Count Quotas

Limit the number of Kubernetes objects:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota
  namespace: production
spec:
  hard:
    pods: "10"
    services: "5"
    configmaps: "10"
    secrets: "10"
    persistentvolumeclaims: "4"

How Resource Quotas Work

Resource quotas are enforced at the API server level during object creation:

graph TD A[Create Pod/Service/etc] --> B[API Server] B --> C[Check ResourceQuota] C --> D{Within Limits?} D -->|Yes| E[Create Object] D -->|No| F[Reject with QuotaExceeded] E --> G[Update Quota Usage] G --> H[Track Consumption] style A fill:#e1f5ff style C fill:#fff4e1 style E fill:#e8f5e9 style F fill:#ffe1e1

Quota Enforcement

  • Immediate enforcement - Quotas are checked when objects are created
  • No retroactive application - Existing objects aren’t affected when quotas are added
  • Namespace-scoped - Each namespace can have its own quotas
  • Cumulative limits - All objects in a namespace count toward quotas

Creating Resource Quotas

Basic Resource Quota

apiVersion: v1
kind: ResourceQuota
metadata:
  name: basic-quota
  namespace: my-namespace
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 8Gi
    pods: "10"

Comprehensive Resource Quota

apiVersion: v1
kind: ResourceQuota
metadata:
  name: comprehensive-quota
  namespace: production
spec:
  hard:
    # Compute resources
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    
    # Storage
    persistentvolumeclaims: "10"
    requests.storage: 200Gi
    
    # Object counts
    pods: "20"
    services: "10"
    configmaps: "20"
    secrets: "20"
    services.loadbalancers: "2"
    services.nodeports: "5"

Resource Quota Scopes

Scopes allow you to apply quotas selectively:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: scoped-quota
  namespace: production
spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: 8Gi
  scopes:
  - BestEffort  # Only applies to pods without resource requests

Available Scopes

  • Terminating - Pods with .spec.activeDeadlineSeconds
  • NotTerminating - Pods without .spec.activeDeadlineSeconds
  • BestEffort - Pods without resource requests or limits
  • NotBestEffort - Pods with resource requests or limits
  • PriorityClass - Pods with a specific priority class

Viewing Resource Quotas

List Quotas

kubectl get resourcequota -n my-namespace

View Quota Details

kubectl describe resourcequota my-quota -n my-namespace

Output shows:

  • Resource - The resource type (CPU, memory, pods, etc.)
  • Used - Current consumption
  • Hard - The limit

Resource Quota Best Practices

1. Set Appropriate Limits

Base quotas on:

  • Expected workload requirements
  • Team or project needs
  • Cluster capacity
  • Cost constraints

2. Use Multiple Quotas

Create separate quotas for different resource types:

# Compute quota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi

---
# Storage quota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: storage-quota
spec:
  hard:
    persistentvolumeclaims: "10"
    requests.storage: 100Gi

3. Combine with LimitRanges

Use LimitRanges to set default requests/limits, then use quotas to limit totals:

graph TB A[LimitRange] --> B[Default Pod Resources] C[ResourceQuota] --> D[Namespace Total Limits] E[Create Pod] --> B E --> D B --> F{Pod Valid?} D --> F F -->|Yes| G[Pod Created] F -->|No| H[Pod Rejected] style A fill:#e1f5ff style C fill:#fff4e1 style G fill:#e8f5e9 style H fill:#ffe1e1

4. Monitor Quota Usage

Regularly check quota consumption:

# Watch quota usage
kubectl get resourcequota -w

# Check specific quota
kubectl describe resourcequota my-quota -n my-namespace

5. Plan for Growth

Set quotas that allow for growth:

  • Don’t set quotas too low initially
  • Monitor usage and adjust as needed
  • Leave headroom for scaling

6. Use Scopes Selectively

Apply scopes to target specific pod types:

  • Use BestEffort scope for development namespaces
  • Use NotBestEffort for production workloads
  • Combine scopes for fine-grained control

Common Issues

Pods Rejected Due to Quota

Problem: Pods can’t be created because quotas are exceeded.

Solution:

  • Check quota usage: kubectl describe resourcequota
  • Increase quota limits if appropriate
  • Remove unused resources
  • Review resource requests/limits

Quota Not Enforced

Problem: Resources are created even with quotas set.

Possible causes:

  • Quota created after resources already existed
  • Resources created in different namespace
  • Quota scopes exclude the resources

Quota Calculation Issues

Problem: Quota usage doesn’t match expectations.

Check:

  • Verify all pods have resource requests/limits
  • Check for resources in other namespaces
  • Review quota scopes
  • Verify quota is applied to correct namespace

Resource Quotas vs LimitRanges

Understanding the difference:

graph TB A[ResourceQuota] --> B[Namespace-Level Limits] C[LimitRange] --> D[Pod-Level Defaults/Constraints] B --> E[Total CPU: 10 cores] B --> F[Total Memory: 20Gi] B --> G[Total Pods: 20] D --> H[Default CPU: 500m] D --> I[Default Memory: 512Mi] D --> J[Max CPU: 2 cores] D --> K[Max Memory: 4Gi] style A fill:#e1f5ff style C fill:#fff4e1

ResourceQuota:

  • Limits total namespace consumption
  • Enforced at namespace level
  • Prevents resource exhaustion

LimitRange:

  • Sets defaults and constraints per pod
  • Applied to individual pods
  • Ensures pods have resource requests/limits

Use Cases

Multi-Tenant Clusters

Isolate teams with separate namespaces and quotas:

# Team A namespace
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    pods: "20"

---
# Team B namespace
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-b-quota
  namespace: team-b
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    pods: "20"

Cost Control

Limit resource usage to control cloud costs:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cost-control
  namespace: development
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 8Gi
    persistentvolumeclaims: "2"
    requests.storage: 20Gi

Resource Reservation

Reserve resources for critical workloads:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    requests.cpu: "50"
    requests.memory: 100Gi
    pods: "100"

See Also