Fit a Deployment Inside a Namespace LimitRange
The Pod for the Deployment named nosql in the prepium-db namespace fails to start because its Container's memory configuration violates the namespace's memory constraint.
Live lab access
This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.
Create an account to continue →
On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.
The task
Task
The Pod for the Deployment named nosql in the prepium-db namespace fails to start because its Container's memory configuration violates the namespace's memory constraint.
The namespace prepium-db has a LimitRange that sets a maximum memory constraint per Container.
Update the nosql Deployment so that the Container:
- requests
128Miof memory - limits the memory to half the maximum memory constraint set for the
prepium-dbnamespace
After your change, the Pod must start successfully.
Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster.
How a LimitRange fills in, and rejects, container resources
A request is what the scheduler reserves for a container; a limit is the ceiling the kernel enforces (CPU is throttled, memory overuse can end in an OOM kill). A LimitRange is a namespace policy applied by an admission controller at Pod creation: first it injects defaults into containers that left values out, then it checks the result against min and max. Knowing which happens first, and which value is compared with which bound, is what lets you fix a rejected workload in one edit.
Pod submitted
──→ mutating phase: LimitRanger fills missing values (defaultRequest, default)
──→ validating phase: LimitRanger checks min ≤ request and limit ≤ max
ResourceQuota checks the namespace total still fits
──→ admitted, or 403 Forbidden naming the violated rule
1. Create a policy and read it back
kubectl create namespace prepium-tutorial
kubectl apply -n prepium-tutorial -f - <<'EOF'
apiVersion: v1
kind: LimitRange
metadata:
name: mem-guard
spec:
limits:
- type: Container
min:
memory: 64Mi
max:
memory: 768Mi
defaultRequest:
memory: 192Mi
default:
memory: 384Mi
EOF
kubectl -n prepium-tutorial describe limitrange mem-guard
describe prints the bounds and defaults per resource in one table, which is the quickest way to read the numbers you must stay inside. If an administrator sets only min and max, the stored object still gains default and defaultRequest; the documented example shows both filled with the max value, so read the object with -o yaml rather than assuming they are empty.
2. Watch a Deployment get refused
kubectl -n prepium-tutorial create deployment cache --image=nginx:1.27-alpine
kubectl -n prepium-tutorial set resources deployment cache --limits=memory=1Gi
kubectl -n prepium-tutorial describe deployment cache
The Deployment object is accepted, because the LimitRange checks Pods, not Deployments. The new ReplicaSet cannot create its Pod, so the Deployment gains a ReplicaFailure condition with reason FailedCreate, and the ReplicaSet events carry the Forbidden text. For a max violation it reads like maximum memory usage per Container is ..., but limit is .... The max bound is compared with the limit; the min bound is compared with the request.
Notice that you only set a limit. With no request given, the request is copied from the limit, so defaultRequest does not apply here.
3. See the defaulting rules on a single Pod
kubectl -n prepium-tutorial run probe-a --image=nginx:1.27-alpine
kubectl apply -n prepium-tutorial -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: probe-b
spec:
containers:
- name: web
image: nginx:1.27-alpine
resources:
requests:
memory: 96Mi
EOF
kubectl -n prepium-tutorial get pod probe-a probe-b \
-o custom-columns=NAME:.metadata.name,REQ:.spec.containers[0].resources.requests.memory,LIM:.spec.containers[0].resources.limits.memory
Predict before you look: probe-a set nothing, so it gets both defaults (192Mi request, 384Mi limit). probe-b set only a request, so it keeps 96Mi and receives the default limit of 384Mi. The values are written into the Pod spec at admission, which is why they appear in get -o yaml.
4. Fix within the bounds and confirm
kubectl -n prepium-tutorial set resources deployment cache \
--requests=memory=160Mi --limits=memory=640Mi
kubectl -n prepium-tutorial rollout status deployment/cache
The template change creates a fresh ReplicaSet whose Pod passes both checks. Changing the LimitRange later never touches running Pods; it only affects the next admission.
Common mistakes
- Fixing the request when the limit broke the max. The error keeps returning because the limit was the compared value.
- Sending a request above the default limit while omitting the limit. The LimitRange does not check its own defaults for consistency, so the Pod is rejected as invalid (request greater than limit).
- Looking for the error on the Deployment events. It lives on the ReplicaSet and in the Deployment's
ReplicaFailurecondition. - Forgetting the quota. If a ResourceQuota covers memory, every new Pod must declare it; LimitRange defaults are the usual way to satisfy that automatically.
| Example check | Evidence |
|---|---|
| Bounds known | Min, Max and defaults from describe limitrange |
| Values are compliant | Container request is at least min, limit is at most max |
| Pods actually exist | rollout status completes; no FailedCreate on the new ReplicaSet |
| Defaults landed where expected | Pod spec shows the injected request and limit |
Cleanup: kubectl delete namespace prepium-tutorial. References: Limit Ranges, Minimum and maximum memory constraints, Default memory requests and limits. Next, try resource requests under a quota or CPU autoscaling.
Video walkthrough: CKAD Exam Question 16 - Namespace Limitrange on YouTube. It shows the full solution, so try the task first.
What this tests
Roll out and update deployments, run canary and blue-green strategies, and right-size workloads. On the CKAD exam, Application Deployment tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.
Practice it for real
The public description lets you study the task before signing up. Full access includes this live lab; the selected Task of the Week is free with an account. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.