KubernetesCVIII · ResourceQuotaResourceQuota
ResourceQuota — the namespace resource budget
What you'll learn
- Use ResourceQuota to bound per-namespace resources
- Configure compute, storage, and object count quotas
- Apply PriorityClass and StorageClass scoping
- Apply the operational discipline of treating quotas as production contracts
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
ResourceQuota bounds the total resources a namespace can consume. This lesson walks the quota types, the enforcement model, the scoping, and the operational discipline.
The quota types
flowchart LR
A[ResourceQuota] --> B[Compute quotas]
A --> C[Storage quotas]
A --> D[Object count quotas]
A --> E[Extended resource quotas]
B --> B1["requests.cpu, requests.memory"]
B --> B2["limits.cpu, limits.memory"]
C --> C1[requests.storage]
C --> C2[persistentvolumeclaims]
D --> D1["pods, services, secrets"]
E --> E1["nvidia.com/gpu"]
The quota types:
- Compute.
requests.cpu,requests.memory,limits.cpu,limits.memory— the sum across all Pods in the namespace. - Storage.
requests.storage(sum of PVC storage requests),persistentvolumeclaims(count of PVCs). - Object count.
pods,services,secrets,configmaps,count/deployments.apps,count/statefulsets.apps, etc. - Extended resources.
nvidia.com/gpu,ephemeral-storage, custom resources.
A quota example
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-a-quota
namespace: tenant-a-prod
spec:
hard:
# Compute
requests.cpu: "32"
requests.memory: 64Gi
limits.cpu: "64"
limits.memory: 128Gi
# Storage
requests.storage: 1Ti
persistentvolumeclaims: "50"
# Object counts
pods: "200"
services: "100"
secrets: "100"
configmaps: "100"
count/deployments.apps: "50"
count/statefulsets.apps: "20"
count/jobs.batch: "50"
count/cronjobs.batch: "20"
This quota bounds the namespace’s total resource consumption. A Pod that would exceed the quota is rejected by the admission controller.
The enforcement model
flowchart LR
A[Pod creation request] --> B{Admission controller}
B --> C{Check quota}
C -->|Within quota| D[Accepted]
C -->|Exceeds quota| E[Rejected with 403]
E --> F["Error: exceeded quota"]
The enforcement:
- The user submits a Pod creation request.
- The admission controller checks the namespace’s ResourceQuota.
- If the new Pod’s resources + existing usage > quota, the Pod is rejected with HTTP 403.
- The error message indicates which quota was exceeded.
The rejection is hard; there is no override.
LimitRange vs ResourceQuota
flowchart LR
A[LimitRange] --> B[Per-container defaults and constraints]
A --> C[Applied at Pod admission]
A --> D[Per-Pod or per-container]
E[ResourceQuota] --> F[Per-namespace totals]
E --> G[Applied at Pod admission]
E --> H[Sum of all Pods]
The relationship:
- LimitRange sets per-container defaults and constraints. New Pods without limits get defaults; Pods with limits beyond min/max are rejected.
- ResourceQuota sets per-namespace totals. The sum of all Pods’ requests/limits cannot exceed the quota.
Both are enforced at admission. Both are needed for production multi-tenancy.
Quota scoping
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-a-quota
namespace: tenant-a-prod
spec:
hard:
requests.cpu: "32"
requests.memory: 64Gi
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values: ["high-priority"]
Quota scoping limits the quota to specific scopes:
- PriorityClass. The quota only counts Pods with the specified PriorityClass.
- StorageClass. The quota only counts PVCs with the specified StorageClass.
Use scoping when different workloads in the same namespace should have separate quotas.
Quiz
Knowledge check · 4 questions
Q1. What happens to Pods already running when a ResourceQuota is created that they exceed?
Q2. A namespace can be over its ResourceQuota without any object having been rejected.
Q3. A ResourceQuota applied to a busy namespace reports usage above its own hard limit; explain the state and get the namespace back inside budget.
`kubectl describe resourcequota compute -n search-prod` shows `requests.cpu 41 / 32` and `pods 218 / 200`. Every Pod in the namespace is Running and nothing has been evicted, but a rollout of `indexer` has been stuck at 0 of 12 new Pods for twenty minutes, with `FailedCreate` events on its ReplicaSet reading `exceeded quota`.
Q4. A `kubectl apply` of a Deployment succeeds but no Pods appear, because the namespace is at its `pods` quota. Which object carries the error, and where do you read it?
Passing score: 75%. Answers are checked in this browser.
The operational discipline
ResourceQuota in production rests on five non-negotiable elements:
- Apply every layer. ResourceQuota + LimitRange + NetworkPolicy + PSS + RBAC.
- Set quotas deliberately. Compute, storage, object counts. Not too tight (causes failures); not too loose (no isolation).
- Monitor utilisation. Alert when namespaces approach their quotas.
- Review quotas quarterly. Workload changes; quotas may need adjustment.
- Document in the runbook. Each namespace’s quota is documented.
Quotas are production contracts. Treat them deliberately and monitor the contract.