Lion Cipher Lab
Limit the blast radius of a runaway pod with ResourceQuotas and LimitRanges
- Cloud Security
- Intermediate
- ~45 min
- Free · no account required
Why it matters
One greedy pod can take a whole node down, and Kubernetes lets it by default. When you deploy a container without saying how much CPU or memory it may use, Kubernetes places no ceiling on it — it will happily claim whatever is free, and when memory runs out the kernel's out-of-memory killer starts terminating processes (an OOMKill) while the node's kubelet starts EVICTING pods to save itself. The pod that caused the pressure is not necessarily the one that dies; your other, innocent workloads on that node get starved, throttled, and evicted right alongside it. That is a denial of service, and…
What you'll learn
- the vocabulary of Kubernetes resource management: requests vs limits, CPU units (m = millicores) and memory units (Mi / Gi), and what OOMKill, eviction, and 'noisy neighbour' actually mean
- why 'no resource limits' is the Kubernetes default and why that default lets one pod exhaust a node and deny service to every other workload on it
- reproducing the break on your own throwaway kind cluster: deploying an unbounded workload and confirming with kubectl top / kubectl describe node that nothing in the namespace caps what it can claim
- applying a LimitRange with default/defaultRequest and max/min, then proving with kubectl describe pod that Kubernetes INJECTED those defaults into a pod that declared none
- applying a ResourceQuota that caps the namespace's total requests/limits (and pod count), then watching the API server REJECT an over-quota pod at admission with an 'exceeded quota' error, and reading used-vs-hard with kubectl describe resourcequota
- the judgment: when these controls belong (multi-tenant clusters, best-effort or untrusted workloads, defence in depth) and how a pro pairs LimitRange + ResourceQuota with per-team namespaces, PriorityClass/eviction, Pod Security Standards, and NetworkPolicy
- the honest limit: a quota/LimitRange is an AVAILABILITY guardrail, not a security or isolation boundary — a container that breaks out or has host access ignores it, capping limits.* can break deploys that omit limits, and CPU limits can throttle latency
Steps in this lab
- The problem: 'no limits' is the default, and one pod can take the node down
- Stand up: your kind cluster, a test namespace, and an unbounded pod
- Measure the break: nothing in the namespace caps what it can claim
- Apply a LimitRange: watch Kubernetes inject defaults into a pod that set none
- Apply a ResourceQuota: watch admission REJECT an over-budget pod
- The judgment: when these are the right control, and how a pro combines them
- The honest negative: an availability guardrail, NOT a security boundary