Lab 10 - ReplicaSets
Lab 10 - ReplicaSets
Goal: watch the reconciliation loop, and see the selector do the binding. Chapter: ReplicaSets
# 1 - a ReplicaSet by hand (the only time you will write one)
cd ~
cat > web-rs.yaml <<'YAML'
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
resources:
requests: { cpu: "20m", memory: "32Mi" }
YAML
kubectl apply -f web-rs.yaml
kubectl get rs,pods -l app=web -o wide
Note the Pod names: web-rs- plus a hash of the template plus a random suffix.
The controller owns them, which kubectl get pod <name> -o yaml | grep -A5 ownerReferences will confirm.
# 2 - self-healing
kubectl delete pod "$(kubectl get pods -l app=web -o name | head -1)"
kubectl get pods -l app=web
A replacement appeared within a second. Nothing “noticed the failure” in a special way - the same loop that created them counted three, found two, and created one.
# 3 - scaling is the same loop with a different number
kubectl scale rs web-rs --replicas=5
kubectl get pods -l app=web --no-headers | wc -l
kubectl scale rs web-rs --replicas=2
kubectl get pods -l app=web --no-headers | wc -l
# 4 - the selector binds Pods, not the name
kubectl run stray --image nginx:1.27 --labels app=web
kubectl get pods -l app=web
kubectl get events --sort-by=.lastTimestamp | tail -5
The stray Pod was adopted because its labels match, so the ReplicaSet counted three and deleted one to get back to two. Labels are load-bearing: an accidental match is an accidental takeover.
# 5 - changing the template does NOT touch running Pods
sed -i 's/nginx:1.27/nginx:1.28/' web-rs.yaml
kubectl apply -f web-rs.yaml
kubectl get pods -l app=web -o jsonpath='{.items[*].spec.containers[0].image}{"\n"}'
Still 1.27. A ReplicaSet has no rollout logic - new Pods would use the new template, existing ones are left alone. That gap is exactly what a Deployment fills.
Clean up
# 6 -
kubectl delete -f web-rs.yaml
kubectl delete pod stray --ignore-not-found