iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

ReplicaSets

A ReplicaSet keeps a fixed number of identical Pods running. In practice you almost never write one directly — you create a Deployment, which creates and rolls a ReplicaSet for you. Knowing how ReplicaSets work explains why rolling updates and rollbacks behave the way they do.

Manifest, owner refs, rolling updates

EXAMPLE
# 1) A ReplicaSet on its own (rare in real apps)
apiVersion: apps/v1
kind: ReplicaSet
metadata:
    name: web
    labels:
        app: web
spec:
    replicas: 3
    selector:
        matchLabels:
            app: web
    template:
        metadata:
            labels:
                app: web
        spec:
            containers:
                - name: web
                    image: nginx:1.27-alpine
                    ports:
                        - containerPort: 80
                    resources:
                        requests: { cpu: 50m,  memory: 64Mi }
                        limits:   { cpu: 200m, memory: 128Mi }

# selector.matchLabels MUST match template.metadata.labels.
# The ReplicaSet adopts any pod with those labels — and will DELETE
# excess pods if there are more than .spec.replicas.

# 2) In real life — let Deployment manage the ReplicaSet
apiVersion: apps/v1
kind: Deployment
metadata:
    name: web
spec:
    replicas: 3
    selector:
        matchLabels:
            app: web
    strategy:
        type: RollingUpdate
        rollingUpdate:
            maxSurge:        1     # at most 1 extra pod during the roll
            maxUnavailable:  0     # never drop below 'replicas' during the roll
    template:
        metadata:
            labels:
                app: web
        spec:
            containers:
                - name: web
                    image: nginx:1.27-alpine
                    readinessProbe:
                        httpGet:
                            path: /
                            port: 80
                        initialDelaySeconds: 2
                        periodSeconds: 5

# 3) What kubectl shows
kubectl get deploy,rs,pods -l app=web
# deploy.apps/web        3/3   …
# replicaset.apps/web-7c8…   3   3   3   …
# pod/web-7c8…-abc12  1/1 Running
#
# Note: each Deployment update produces a NEW ReplicaSet.
# Old ReplicaSets stick around (scaled to 0) so you can rollback.

# 4) Rolling update — change image, watch new RS roll in
kubectl set image deploy/web web=nginx:1.27.1-alpine --record
kubectl rollout status deploy/web
kubectl rollout history deploy/web
kubectl rollout undo deploy/web                  # back to previous revision
kubectl rollout undo deploy/web --to-revision=3

# Behind the scenes:
#   • Deployment creates a new ReplicaSet with the updated template
#   • Scales new RS up by maxSurge, scales old RS down by maxUnavailable
#   • Repeats until new RS == replicas, old RS == 0
#   • All gated by readinessProbe — a pod is 'ready' only when its probe passes

# 5) Scale up or down
kubectl scale deploy/web --replicas=10
# The Deployment updates the active RS's .spec.replicas.

# Horizontal Pod Autoscaler — scale on metrics
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
    name: web
spec:
    scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: web
    minReplicas: 3
    maxReplicas: 30
    metrics:
        - type: Resource
            resource:
                name: cpu
                target:
                    type: Utilization
                    averageUtilization: 60
        - type: Resource
            resource:
                name: memory
                target:
                    type: Utilization
                    averageUtilization: 75

# 6) Owner references — how garbage collection works
kubectl get pod web-7c8…-abc12 -o jsonpath='{.metadata.ownerReferences}'
# Each pod's owner is the ReplicaSet. Delete the RS → pods deleted.
# Each RS's owner is the Deployment. Delete the Deployment → cascade kills all.
# kubectl delete deploy/web --cascade=orphan   # rare: keep RS + pods

# 7) Selector trap — DO NOT change selector after creation
# If you edit selector to match different labels, the old pods become orphaned
# (not managed) and the RS may launch new pods. This was a footgun;
# Kubernetes now rejects most selector changes on Deployments to prevent it.

# 8) Pod template changes vs RS regeneration
#   • Editing spec.template (image, env, resources) → new ReplicaSet
#   • Editing spec.replicas only → same ReplicaSet, just scaled
#   • Editing spec.strategy → next rollout uses the new strategy

# 9) revisionHistoryLimit — how many old ReplicaSets to keep for rollback
apiVersion: apps/v1
kind: Deployment
spec:
    revisionHistoryLimit: 10        # default; lower for noisy CD pipelines

# 10) Debug a stuck rollout
kubectl rollout status deploy/web --timeout=2m
kubectl describe deploy/web                            # events at the bottom — readiness failures, image pull errors
kubectl get rs -l app=web -o wide                      # which RS has DESIRED != READY
kubectl describe pod web-7c8…-abc12                    # individual pod events
kubectl logs -l app=web --tail=200 --max-log-requests=10
kubectl get events --sort-by=.lastTimestamp | tail -30

# 11) StatefulSet vs ReplicaSet
#   ReplicaSet/Deployment — stateless, interchangeable pods, network identity ephemeral
#   StatefulSet            — ordered, named pods (web-0, web-1), stable storage
#                             For DBs, queues, anything with per-pod identity.

# 12) Common bugs
#   • selector doesn't match template labels → 'invalid: selector does not match template labels'
#   • Missing readinessProbe → rollout completes 'successfully' but pods can't serve traffic
#   • maxUnavailable: 50% + replicas: 2 → outage during deploy; tune for small replicas
#   • Image tag :latest → pod restart pulls a NEW build silently; pin tags or use digests
#   • Forgetting resources.requests → unschedulable on heavily-packed nodes

Why it matters

ReplicaSets are the layer the Deployment controller drives, not something you usually create yourself. Treat the Deployment as the API you operate against — pin image tags, set a real readiness probe, and use maxUnavailable: 0 for small replica counts where 50% downtime during a rollout is unacceptable.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Don't create ReplicaSets directly — use Deployments which manage them.
Try it Yourself »

Discussion

Loading…