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.
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
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:
spec:
containers:
- name: api
image: nginx:1.27
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 250m
memory: 128MiYou can also set them without an editor, then check what the Pod got:
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}'; echoTo 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.
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.
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 limitrangecommand. 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.
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.cpuorlimits.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.
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
- Resource Management for Pods and Containerssearch: resource management for pods
- Configure Quality of Service for Podssearch: quality of service
- Limit Rangessearch: limit range
- Resource Quotassearch: resource quotas
Give a Pod exact requests and limits
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
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-1/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-1/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-1/cleanup | bash
Put defaults and a budget on a 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
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-2/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-res-2/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 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.