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