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.
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:
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:
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
BestEffortscope for development namespaces - Use
NotBestEffortfor 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:
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
- Requests & Limits - Pod-level resource requirements
- LimitRanges - Default resource constraints
- Namespaces - Namespace concepts
- Scheduling - How quotas affect scheduling
- Multi-Tenancy - Multi-tenant cluster patterns