Room Full
Objective
Escape Room: Room Full
The application pod is waiting in line but never gets scheduled.
Your Mission
- Identify why the pod can't be scheduled
- Figure out what's blocking it
- Fix the configuration so the pod can run
Success Criteria
- The pod
escape-appis inRunningstate - The nginx container is serving traffic on port 80
Getting Started
# Check the pod status
kubectl get pods -n escape-room-full
# You'll see something like:
# NAME READY STATUS RESTARTS AGE
# escape-app 0/1 Pending 0 2m
Notice that READY is 0/1 and STATUS is Pending - the pod hasn't even started!
Namespace
All resources are in the escape-room-full namespace.
Good luck, engineer. The scheduler awaits your fix.
Quick Start
Run this command in your terminal to set up the room:
$ make room-apply ROOM=room-fullThis creates the namespace escape-room-full with the broken resources.
Other useful commands:
$ make room-test ROOM=room-fullVerify the room is in the expected broken state
$ make room-escape-test ROOM=room-fullTest if you have successfully fixed all issues
$ make room-reset ROOM=room-fullReset the room to try again
Useful Commands
Check pod status
$ kubectl get pods -n escape-room-fullSee the current state of pods in the namespace
View events
$ kubectl get events -n escape-room-full --sort-by='.lastTimestamp'Check recent events for error details
Describe pods
$ kubectl describe pods -n escape-room-fullGet detailed information about pods
Check logs
$ kubectl logs -l app.kubernetes.io/part-of=K8sEscapeRoom -n escape-room-fullView the application logs
Hints
Submit Proof
Login to submit proof and track your progress.
Login with GitHubView Solution (Spoiler)
Solution preview locked
Complete the room to unlock the full solution here
Run this to see the full solution:
$ make room-solution ROOM=room-fullShow solution anyway (spoiler)
Solution: Pending - Resource Requests Exceed Capacity
Root Cause
The pod requests 64Gi of memory and 32 CPU cores - far more than any node in a kind cluster can provide. The scheduler cannot find a suitable node, so the pod remains Pending indefinitely.
Diagnosis Steps
# 1. Check pod status - see Pending
kubectl get pods -n escape-room-full
# NAME READY STATUS RESTARTS AGE
# escape-app 0/1 Pending 0 2m
# 2. Describe the pod to see scheduler events
kubectl describe pod escape-app -n escape-room-full
# Look for events like:
# Events:
# Type Reason Age From Message
# ---- ------ ---- ---- -------
# Warning FailedScheduling 30s default-scheduler 0/1 nodes are available:
# 1 Insufficient cpu, 1 Insufficient memory. preemption: 0/1 nodes are available:
# 1 No preemption victims found for incoming pod.
# 3. Check what resources the pod is requesting
kubectl get pod escape-app -n escape-room-full \
-o jsonpath='{.spec.containers[0].resources.requests}'
# Output: {"cpu":"32","memory":"64Gi"}
# 4. Check what resources are available on nodes
kubectl describe nodes | grep -A 6 "Allocatable:"
# Allocatable:
# cpu: 8 # Much less than 32!
# memory: 8052956Ki # About 8Gi, much less than 64Gi!
The Fix
Option 1: Quick Fix with kubectl run
# Delete the broken pod
kubectl delete pod escape-app -n escape-room-full
# Create a new pod with reasonable resource requests
kubectl run escape-app -n escape-room-full \
--image=nginx:1.25 \
--port=80 \
--requests='cpu=100m,memory=128Mi' \
--limits='cpu=500m,memory=256Mi'
Option 2: Apply Corrected YAML
# Delete the broken pod
kubectl delete pod escape-app -n escape-room-full
# Apply the fixed manifest
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: escape-app
namespace: escape-room-full
labels:
app: escape-app
room: pending-resources
spec:
containers:
- name: app
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
EOF
Verification
# Check the pod is now running
kubectl get pods -n escape-room-full
# NAME READY STATUS RESTARTS AGE
# escape-app 1/1 Running 0 30s
# Verify scheduling succeeded by checking events
kubectl describe pod escape-app -n escape-room-full | grep -A 3 "Events:"
# Should show: Successfully assigned, Pulled, Created, Started
Lessons Learned
- Pending always has a reason - Check
kubectl describe podfor scheduler messages - Know your node capacity - Use
kubectl describe nodesto see available resources - Right-size your requests - Requests should match actual usage, not arbitrary large numbers
- Requests vs Limits:
- Requests: Used for scheduling; pod guaranteed these resources
- Limits: Maximum the container can use; enforced at runtime
Real-World Considerations
Resource Planning
# Check total cluster capacity
kubectl top nodes
# Check resource usage of running pods
kubectl top pods --all-namespaces
# See resource quotas in a namespace
kubectl describe resourcequota -n <namespace>
Best Practices
-
Set appropriate requests and limits
resources: requests: memory: "128Mi" # What the app needs to run cpu: "100m" # 0.1 CPU cores limits: memory: "256Mi" # Max before OOM kill cpu: "500m" # Max CPU throttling -
Use LimitRanges to set defaults
apiVersion: v1 kind: LimitRange metadata: name: default-limits spec: limits: - default: memory: "256Mi" cpu: "500m" defaultRequest: memory: "128Mi" cpu: "100m" type: Container -
Use ResourceQuotas to prevent overcommitment
apiVersion: v1 kind: ResourceQuota metadata: name: namespace-quota spec: hard: requests.cpu: "4" requests.memory: "8Gi" limits.cpu: "8" limits.memory: "16Gi"
Cluster Autoscaling
In cloud environments, if a pod can't be scheduled due to resource constraints, a cluster autoscaler can automatically add more nodes. But this doesn't help if the pod requests more than a single node can provide!