Requests, limits, LimitRange and ResourceQuota

What requests and limits do, how they set a Pod's QoS class, and how LimitRange and ResourceQuota set rules for a whole namespace.

40 min 2 hands-on tasksWorkloads · 15% of the exam

Key ideas in this lesson · tap one for a simple explanation

What you will be able to do

  • Set requests and limits in the right units, and predict the QoS class Kubernetes will give the Pod.
  • Say what happens when a container goes over its CPU limit, and when it goes over its memory limit.
  • Create a LimitRange that fills in and caps container resources, and a ResourceQuota that caps a namespace, and read both with kubectl describe.

Every uses CPU and memory on its . You tell Kubernetes how much each container needs, and the most it may use. Without that, one busy app can starve the other apps on the same node.

On the exam, expect a task that wants exact resource values on a or a . Expect another where a rule decides whether a Pod may be created at all. Both are quick if you know the field names and the units.

Requests and limits: two different jobs

Request versus limit

Request

what the container is promised

Used by the scheduler

to pick a node with room

Limit

the most it may use

Over the CPU limit

slowed down (throttled)

Over the memory limit

killed (OOMKilled)

The scheduler only looks at requests. Limits only matter once the container runs.

  • A request is what the reserves. A Pod fits on a node only if the requests of all Pods there stay within what the node can offer. Real usage plays no part in that choice.
  • A limit is enforced while the container runs. Over its CPU limit, a container is throttled: it keeps running, just slower. Over its memory limit, it is killed, and the Pod shows OOMKilled.

Example: your Django app requests 100m CPU and 64Mi memory, with limits of 250m and 128Mi. The scheduler looks for a node with at least 100m CPU and 64Mi memory not yet reserved. Later, a memory leak takes the app past 128Mi, so it is killed and restarted.

Reading the signs of a killed container, such as exit code 137 and CrashLoopBackOff, is covered in Application failures.

CPU and memory use different units, and the letters matter:

WriteMeansTrap
cpu: 1One CPU corecpu: 0.5 is stored as 500m. Both are fine
cpu: 250mA quarter of a core. m means a thousandth (millicores)1000m is one whole core
memory: 128Mi128 mebibytes (128 × 1,048,576 bytes)128M is 128 × 1,000,000 bytes, about 5% less
memory: 1Gi1024 Mimemory: 128m means 0.128 bytes. Lowercase m is a thousandth
Per-container resources
    spec:
      containers:
        - name: api
          image: nginx:1.27
          resources:
            requests:
              cpu: 100m
              memory: 64Mi
            limits:
              cpu: 250m
              memory: 128Mi

You can also set them without an editor, then check what the Pod got:

Set and inspect without opening an editor
kubectl -n wl-res set resources deploy/api -c api --requests=cpu=100m,memory=64Mi --limits=cpu=250m,memory=128Mi
kubectl -n wl-res get pod -l app=api -o jsonpath='{.items[0].spec.containers[0].resources}'; echo
kubectl -n wl-res get pod -l app=api -o jsonpath='{.items[0].status.qosClass}'; echo

To see how much of a node is already reserved, or how much a Pod really uses, see Monitoring resource usage.

Three rules about missing values and changes:

  • A limit but no request: the request is set equal to the limit.
  • A request but no limit: there is no limit, unless a adds one.
  • Changing resources on a Deployment edits its Pod template, so it starts a .

QoS classes

From your requests and limits, Kubernetes gives each Pod a (quality of service). The class decides which Pods a node removes first when it runs out of memory.

ClassRuleWhen the node runs short of memory
GuaranteedEvery container has CPU and memory limits, and its requests equal its limitsEvicted last
BurstableNot Guaranteed, but at least one container has a CPU or memory request or limitEvicted after BestEffort
BestEffortNo container has any request or limitEvicted first

The class is set when the Pod is created, and stored in status.qosClass. Do not mix up the two ways memory can stop your app:

  • OOMKilled: one container went over its own memory limit, so the kernel killed that container.
  • Evicted: the whole node ran short of memory, so the removed whole Pods, BestEffort ones first. This is covered in Worker node failures.

LimitRange: defaults and bounds for each container

A LimitRange sets rules for every container in one namespace. It fills in requests and limits for containers that set none. It also rejects containers that ask for too much or too little. Example: in your team's namespace, every container gets 100m CPU unless it asks for something else.

Container defaults and a ceiling for one namespace
apiVersion: v1
kind: LimitRange
metadata:
  name: container-defaults
  namespace: wl-quota
spec:
  limits:
    - type: Container
      default:            # limit applied when a container sets none
        cpu: 200m
        memory: 256Mi
      defaultRequest:     # request applied when a container sets none
        cpu: 100m
        memory: 128Mi
      max:                # anything above is rejected at admission
        cpu: 500m
        memory: 512Mi
      min:
        cpu: 50m
        memory: 32Mi
  • A LimitRange is applied when a Pod is created. Pods that are already running are never changed.
  • There is no kubectl create limitrange command. You write the yourself.

ResourceQuota: a budget for the whole namespace

A is a budget for a whole namespace. It caps the total that all Pods there may request, and how many objects may exist. Example: the team's namespace may run at most 4 Pods, and together they may request at most 1 CPU.

LimitRangeResourceQuota
Applies toEach container, one at a timeThe namespace as a whole
What it doesFills in defaults, sets a minimum and a maximumCaps the total, and counts objects
Example"Every container gets 100m CPU by default""All Pods together may request at most 1 CPU"
Create, then read used against hard
kubectl -n wl-quota create quota team-quota --hard=pods=4,requests.cpu=1,requests.memory=1Gi,limits.cpu=2,limits.memory=2Gi
kubectl -n wl-quota create quota objects --hard=count/deployments.apps=3,services=5,configmaps=10,persistentvolumeclaims=2
kubectl -n wl-quota describe quota
kubectl describe ns wl-quota          # quotas and limit ranges together
  • Once a quota covers requests.cpu or limits.memory, every new Pod in the namespace must set those values. Otherwise it is rejected with must specify limits.cpu.
  • That is why a quota almost always comes with a LimitRange: the LimitRange fills those values in.
  • A quota is checked when an object is created. Lowering it never removes what already exists; it only blocks new objects.
What happens to a new Pod in a namespace with both

New Pod

no resources set

LimitRange

fills in requests and limits

ResourceQuota

checks the namespace budget

Pod created

or rejected if over budget

The LimitRange fills in the values first, so the quota has numbers to check.

In the official docs· open on exam day too

Hands-on task 1 of 2wl-res-1
~5 min4% weightWorkloads

Give a Pod exact requests and limits

In namespace wl-res create a Pod gateway with one container named httpd (image httpd:2.4). The container requests 100m CPU and 64Mi memory and is limited to 250m CPU and 128Mi memory. When it is running, write the QoS class Kubernetes assigned to the Pod (the class name only) to /tmp/cka/wl-res-qos.txt.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-1/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-1/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-1/cleanup | bash
Hands-on task 2 of 2wl-res-2
~8 min6% weightWorkloads

Put defaults and a budget on a namespace

In namespace wl-quota: create a LimitRange container-defaults so that containers that specify nothing get a request of 100m CPU and 128Mi memory and a limit of 200m CPU and 256Mi memory, and no container may be limited above 500m CPU or 512Mi memory. Create a ResourceQuota team-quota allowing at most 4 Pods, 1 CPU and 1Gi memory of requests, and 2 CPU and 2Gi memory of limits. Finally create a Pod defaulted (image nginx:1.27) with no resources section; it must be running.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-2/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-2/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-2/cleanup | bash

Finished this lesson?

0 of 2 tasks passed. Your readiness counts tasks, so run them before you move on.