Tools · Containers and Kubernetes security · 16 / 20
Kubernetes requests, limits, ResourceQuota, and LimitRange as security controls
See how missing limits let one workload starve a node, set requests and limits, and use ResourceQuota and LimitRange to keep namespaces within bounds.
Availability is security
A pod without limits can consume all CPU and memory on a node, whether through a bug, a traffic spike, or abuse such as cryptomining in a compromised container. Requests tell the scheduler what a pod needs; limits cap what it can use. Exceeding a memory limit gets the container OOM-killed; exceeding a CPU limit throttles it.
Namespace guardrails
A LimitRange sets default and maximum requests and limits for containers in a namespace, so pods created without them still get sensible values. A ResourceQuota caps the namespace total: CPU, memory, number of pods, services of type LoadBalancer, and more.
apiVersion: v1
kind: LimitRange
metadata: { name: defaults, namespace: team-a }
spec:
limits:
- type: Container
default: { cpu: 500m, memory: 256Mi }
defaultRequest: { cpu: 100m, memory: 128Mi }
max: { cpu: '2', memory: 1Gi }
---
apiVersion: v1
kind: ResourceQuota
metadata: { name: team-a-quota, namespace: team-a }
spec:
hard:
requests.cpu: '4'
requests.memory: 8Gi
limits.memory: 16Gi
pods: '40'
services.loadbalancers: '0'Lab: hit the limits
Apply the objects above to a test namespace, create a pod without resources, and inspect it to see the defaults filled in. Run a memory stress container that inherits the 256Mi default limit and allocate more: kubectl describe shows the container terminated with reason OOMKilled. Try creating a LoadBalancer service and read the quota error.
kubectl -n team-a run plain --image=nginx:1.27 && kubectl -n team-a get pod plain -o jsonpath='{.spec.containers[0].resources}'
kubectl -n team-a run hog --image=polinux/stress -- stress --vm 1 --vm-bytes 300M
kubectl -n team-a describe pod hog | grep -A3 'Last State'
kubectl -n team-a describe resourcequotaMonitoring
Unexpected sustained CPU at the limit in a workload that is usually idle is a classic cryptomining signal. Pair limits with alerts on CPU throttling and with runtime detection for unknown processes.
Diagram
Unbounded namespace versus guarded namespace
Defaults and caps contain mistakes and abuse.
Pod without limits. Can use the whole node
Namespace total. Unlimited
LoadBalancers. Anyone can expose one
Pod without limits. Gets LimitRange defaults
Namespace total. Capped by ResourceQuota
LoadBalancers. Quota of 0 unless approved
Check yourself
1. A container exceeds its memory limit. What happens?
2. Which object gives pods default limits when none are specified?
3. How can you prevent a namespace from creating LoadBalancer services?