Chapter 9 of 47 · Controllers, part 1

ReplicaSet: keep N Pods alive

A standalone Pod that dies stays dead. A ReplicaSet fixes exactly that: you say how many identical Pods you want, and it keeps that many running. It is the first controller you meet, and it introduces the idea everything else is built on: labels and selectors.

What it does

A ReplicaSet has one job: make sure exactly N Pods matching a description exist. Too few? It creates Pods. Too many? It deletes some. Crash one or change the number:

ReplicaSet posts-rs   (replicas: 3)
├── Pod posts-rs-4kq2p
├── Pod posts-rs-m7x4t
└── Pod posts-rs-zt9wn

The YAML

A ReplicaSet wraps the Pod you wrote in chapter 8. Click each part:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: posts-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: posts
  template:
    metadata:
      labels:
        app: posts
    spec:
      containers:
        - name: posts
          image: micro-posts:1.0
          ports:
            - containerPort: 4000

replicas: 3

The desired number of Pods. Change it and apply again, or run kubectl scale rs posts-rs --replicas=5.

Pod (chapter 8)

kind: Pod
metadata:
  name: posts-pod
spec:
  containers: ...

ReplicaSet

kind: ReplicaSet
spec:
  replicas: 3
  selector: ...
  template:      ← the Pod goes here
    metadata: ...
    spec:
      containers: ...

Labels and selectors

A label is a key/value sticker on an object, such as app=posts. A selector is a query: "all Pods with app=posts". The ReplicaSet does not keep a list of Pod names; it just counts Pods that match its selector, every time.

Prove it. Change a Pod's label from posts to something else, or turn the users Pod into a posts Pod:

Relabel a Pod away and the ReplicaSet sees only 2, so it creates a new one; the relabelled Pod keeps running, now owned by nobody. Relabel an extra Pod into app=posts and the ReplicaSet sees 4 and deletes one. Labels are the glue between objects. Services use exactly the same mechanism.

Try it with kubectl

  1. $ kubectl apply -f replicaset.yaml
    replicaset.apps/posts-rs created

    Create it from the YAML above.

  2. $ kubectl get rs
    NAME       DESIRED   CURRENT   READY   AGE
    posts-rs   3         3         3       20s

    DESIRED is replicas. CURRENT is how many Pods exist, READY how many are ready.

  3. $ kubectl get pods --show-labels
    NAME             READY   STATUS    LABELS
    posts-rs-4kq2p   1/1     Running   app=posts
    posts-rs-m7x4t   1/1     Running   app=posts
    posts-rs-zt9wn   1/1     Running   app=posts

    Pod names are the ReplicaSet name plus a random suffix. All carry app=posts.

  4. $ kubectl delete pod posts-rs-4kq2p
    pod "posts-rs-4kq2p" deleted
    $ kubectl get pods
    NAME             READY   STATUS    AGE
    posts-rs-m7x4t   1/1     Running   2m
    posts-rs-zt9wn   1/1     Running   2m
    posts-rs-qr5vb   1/1     Running   3s

    Self-healing: a replacement appears within seconds.

  5. $ kubectl scale rs posts-rs --replicas=5
    replicaset.apps/posts-rs scaled
    $ kubectl get rs
    NAME       DESIRED   CURRENT   READY
    posts-rs   5         5         5

    Scaling is changing one number.

  6. $ kubectl label pod posts-rs-m7x4t app=debug --overwrite
    $ kubectl get pods -L app
    NAME             STATUS    APP
    posts-rs-m7x4t   Running   debug     ← no longer counted
    posts-rs-x2p8d   Running   posts     ← brand new
    ...

    The labels lab, for real. Handy for pulling a misbehaving Pod out of rotation to debug it.

  7. $ kubectl delete rs posts-rs
    replicaset.apps "posts-rs" deleted

    Deleting the ReplicaSet deletes the Pods it owns. The relabelled posts-rs-m7x4t survives; delete it by hand.

What a ReplicaSet cannot do

Change the image in the template from micro-posts:1.0 to 1.1 and apply. What happens?

$ kubectl apply -f replicaset.yaml      # image now 1.1
replicaset.apps/posts-rs configured
$ kubectl get pods -o custom-columns=NAME:.metadata.name,IMAGE:.spec.containers[0].image
NAME             IMAGE
posts-rs-qr5vb   micro-posts:1.0     ← still the old version
posts-rs-zt9wn   micro-posts:1.0
Nothing changes. The ReplicaSet already has 3 matching Pods, so it is satisfied. The template is only used for new Pods. There is no rolling update and no rollback. That missing piece is what a Deployment adds, next chapter.

Recap

Quick check

You manually create a bare Pod with label app=posts while posts-rs (replicas: 3) is running. What happens?
Show answer

The ReplicaSet now counts 4 matching Pods, adopts yours, and deletes one to get back to 3. It might even delete yours. Never reuse a controller's labels on unrelated Pods.

ReplicaSet: common questions

What is a ReplicaSet in Kubernetes?

A controller that keeps a fixed number of identical Pods running. It counts Pods matching its label selector and creates or deletes Pods from its template to reach the desired number.