Skip to main content
RunBook Academy

KubernetesCVIII · ResourceQuotaResourceQuota

ResourceQuota — the namespace resource budget

Advanced⏱ ~16 minkubectl

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

Not yet marked complete on this device.

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:

  1. The user submits a Pod creation request.
  2. The admission controller checks the namespace’s ResourceQuota.
  3. If the new Pod’s resources + existing usage > quota, the Pod is rejected with HTTP 403.
  4. 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

  1. Q1. What happens to Pods already running when a ResourceQuota is created that they exceed?

  2. Q2. A namespace can be over its ResourceQuota without any object having been rejected.

  3. 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`.

  4. 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.