Requests, limits and QoS

Kubernetes · Practical · 12 min

Wrong resource settings cause most mysterious OOMKills, throttling and unschedulable pods.

Each container can declare resources.requests and resources.limits for cpu (cores: 500m = half a core) and memory (256Mi, 1Gi).

  • Requests are what the scheduler uses: a pod fits on a node only if the sum of requests fits the node's allocatable capacity. They also set the CPU share under contention.
  • Limits are enforced by the kernel through cgroups. Exceeding the memory limit gets the container OOMKilled (exit code 137). Exceeding the CPU limit only throttles it; it slows down but isn't killed.

The combination gives a QoS class:

  • Guaranteed: every container has requests equal to limits for CPU and memory.
  • Burstable: some requests or limits set.
  • BestEffort: none at all; first to be evicted when a node runs short of memory.

Practical advice:

  • Always set memory requests, and a memory limit close to it; memory isn't compressible.
  • Set CPU requests from measured usage. Many teams omit CPU limits to avoid needless throttling of latency-sensitive services.
  • Use kubectl top pods (needs metrics-server) to see real usage.
  • A LimitRange can give defaults in a namespace and a ResourceQuota caps its total.

Runtimes such as recent JVMs, Go and Node read the cgroup limits; check yours does before relying on that.

Example

containers:
  - name: api
    image: ghcr.io/acme/api:2.1.0
    resources:
      requests:
        cpu: 250m        # scheduler reserves a quarter core
        memory: 512Mi
      limits:
        memory: 512Mi    # above this: OOMKilled
        # no cpu limit: may burst into idle CPU
# kubectl top pod -l app=api
# NAME        CPU(cores)  MEMORY(bytes)
# api-6f-x1   180m        430Mi
# kubectl get pod api-6f-x1 -o jsonpath='{.status.qosClass}'   # Burstable

Remember

  • Requests drive scheduling; limits are enforced at runtime
  • Memory over limit = OOMKilled; CPU over limit = throttled
  • QoS: Guaranteed, Burstable, BestEffort (evicted first)

Watch out for

  • Setting no requests at all: pods get packed onto nodes and are evicted or starved under load.

Check yourself

  1. A container keeps exiting with reason OOMKilled. Which setting is it hitting?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: kubernetes.io/docs/concepts/configuration/manage-resources-containers/