Resource Quotas & LimitRanges
Prevent resource exhaustion with namespace-level governance.
Time: ~10 minutes Difficulty: Intermediate
What You Will Learn
Section titled “What You Will Learn”- ResourceQuota: cap total CPU, memory, pods, and services per namespace
- LimitRange: set default and max resource limits per container
- Why pods get stuck in Pending (“insufficient quota”)
- How quotas enforce that every pod specifies resource requests
Deploy
Section titled “Deploy”Navigate to the demo directory:
cd demos/resource-quotaskubectl apply -f manifests/namespace.yamlkubectl apply -f manifests/resource-quota.yamlkubectl apply -f manifests/limit-range.yamlCheck the quota:
kubectl describe resourcequota compute-quota -n quota-demoDeploy Within Quota
Section titled “Deploy Within Quota”kubectl apply -f manifests/small-app.yamlkubectl get pods -n quota-demokubectl describe resourcequota compute-quota -n quota-demoThe “Used” column now shows resources consumed by the 2 pods.
Exceed the Quota
Section titled “Exceed the Quota”kubectl apply -f manifests/greedy-app.yamlkubectl get pods -n quota-demokubectl get deploy greedy-app -n quota-demoThe small-app already uses 200m of the 1000m CPU request quota. The greedy-app wants 400m per pod x 3 = 1200m, but only 800m remains. At most 2 greedy pods can schedule. The third gets rejected by the quota admission controller.
Check why:
kubectl describe deploy greedy-app -n quota-demo | grep -A 5 "Conditions"kubectl get events -n quota-demo --field-selector reason=FailedCreateLimitRange in Action
Section titled “LimitRange in Action”Deploy a pod without resource specs. The LimitRange injects defaults:
kubectl run no-limits --image=busybox:1.36 --command -- sleep infinity -n quota-demokubectl get pod no-limits -n quota-demo -o jsonpath='{.spec.containers[0].resources}' | python3 -m json.toolThe container gets the LimitRange defaults: 50m CPU request, 200m CPU limit.
Try to exceed the LimitRange max:
kubectl run too-big --image=busybox:1.36 -n quota-demo \ --overrides='{"spec":{"containers":[{"name":"too-big","image":"busybox:1.36","command":["sleep","infinity"],"resources":{"requests":{"cpu":"1"},"memory":"1Gi"}}}]}}'This fails because the LimitRange max is 500m CPU and 512Mi memory.
What is Happening
Section titled “What is Happening”manifests/ namespace.yaml # quota-demo namespace resource-quota.yaml # Caps: 1 CPU req, 2 CPU limit, 5 pods, 3 services limit-range.yaml # Defaults: 50m/200m CPU, min 25m, max 500m small-app.yaml # 2 pods, fits within quota greedy-app.yaml # 3 pods, exceeds CPU quotaResourceQuota limits the total resources a namespace can consume. LimitRange limits what a single container can request and provides defaults for containers that don’t specify resources.
| Resource | Quota Limit | LimitRange Default | LimitRange Max |
|---|---|---|---|
| CPU requests | 1000m total | 50m per container | 500m |
| CPU limits | 2000m total | 200m per container | 500m |
| Memory requests | 1Gi total | 64Mi per container | 512Mi |
| Memory limits | 2Gi total | 128Mi per container | 512Mi |
Cleanup
Section titled “Cleanup”kubectl delete namespace quota-demoFurther Reading
Section titled “Further Reading”See docs/deep-dive.md for a detailed explanation of quota scopes, priority class quotas, count quotas for CRDs, LimitRange types (Pod, PVC), and multi-team namespace strategies.
Next Step
Section titled “Next Step”Move on to Pod Disruption Budgets to learn how to maintain availability during maintenance.