Kubernetes Tutorial · Configuration and Resources · Lesson 19 of 26

Resource Requests and Limits

Requests drive scheduling, limits cap usage; set both well to avoid OOMKills, throttling and noisy neighbours.

Create a free account to save this page, take notes and track your progress. Sign in

Requests and limits

resources:
  requests: {cpu: 250m, memory: 256Mi}   # reserved for scheduling
  limits:   {memory: 256Mi}              # hard cap
  • The scheduler places pods using requests; a pod whose requests don't fit anywhere stays Pending.
  • Exceeding a memory limit gets the container OOMKilled and restarted.
  • Exceeding a CPU limit throttles it; many teams set CPU requests but no CPU limit to avoid needless throttling.
  • Requests equal to limits for every resource give the Guaranteed QoS class (evicted last under pressure).
OOMKilled, Pending and QoS
kubectl create namespace demo-resources > /dev/null
trap 'kubectl delete namespace demo-resources --wait=false > /dev/null' EXIT
cat > hungry.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata: {name: hungry}
spec:
  restartPolicy: Never
  containers:
    - name: app
      image: busybox:1.37
      command: ["sh", "-c", "tail /dev/zero"]
      resources:
        requests: {memory: 32Mi}
        limits: {memory: 32Mi}
EOF
kubectl -n demo-resources apply -f hungry.yaml > /dev/null
kubectl -n demo-resources wait --for=jsonpath='{.status.phase}'=Failed pod/hungry --timeout=120s > /dev/null
kubectl -n demo-resources get pod hungry -o jsonpath='terminated: {.status.containerStatuses[0].state.terminated.reason}, exit code {.status.containerStatuses[0].state.terminated.exitCode}{"\n"}'
kubectl -n demo-resources run greedy --image=busybox:1.37 --overrides='{"spec":{"containers":[{"name":"greedy","image":"busybox:1.37","command":["sleep","3600"],"resources":{"requests":{"cpu":"500"}}}]}}' > /dev/null
sleep 3
echo "pod asking for 500 CPUs: $(kubectl -n demo-resources get pod greedy -o jsonpath='{.status.phase}') ($(kubectl -n demo-resources get pod greedy -o jsonpath='{.status.conditions[0].reason}'))"
echo "QoS of hungry: $(kubectl -n demo-resources get pod hungry -o jsonpath='{.status.qosClass}')"

Output

terminated: OOMKilled, exit code 137
pod asking for 500 CPUs: Pending (Unschedulable)
QoS of hungry: Burstable

Run this on your computer — see “Get Started” for setup.

Test yourself

A pod stays Pending with reason Unschedulable. A likely cause?

  1. Its image is missing
  2. Its resource requests don't fit on any node
  3. Its readiness probe fails
  4. It has no Service
Show answer

Answer: Its resource requests don't fit on any node

kubectl describe pod shows the scheduler's message, for example 'Insufficient cpu'.

Was this page helpful?