>_
EngineeringNotes
Back to Kubernetes

ReplicaSet & Deployment

Ensuring high availability, auto-scaling, and managing updates for your Pods.

1.

ReplicaSet

A ReplicaSet in Kubernetes is a controller that ensures a specified number of pod replicas are running at any given time. It is used to maintain a stable set of replica Pods running in the cluster, even if some Pods fail or are deleted.

⚖️ Auto-Healing & Scaling

The core job of a ReplicaSet is to constantly monitor the cluster and compare the desired state (e.g., "I want 3 Pods running") with the actual state. If a Pod crashes and the count drops to 2, the ReplicaSet immediately starts a new one to bring the count back to 3. Conversely, if there are somehow 4 Pods running (perhaps due to manual intervention or a network partition healing), the ReplicaSet will terminate the excess Pod to ensure exactly 3 are running.

Cluster
control-plane (master node)
kube-controller-manager
Deployment Controller
Replicaset Controller
API Server
worker 1
Pod 1
worker 2
Pod 2

Create a replicaset

Let's not worry about deployments yet. Let's just create a replicaset that starts 3 pods. Notice that we do not need to write a separate manifest to start the Pods! The ReplicaSet manifest contains a template section that defines exactly how to create the Pods it manages.

Create rs.yml

yaml
yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

ReplicaSet ensures a fixed number of Pods are always running.

replicas: 3
Maintain 3 Pods at all times.
selector
Tells the ReplicaSet which Pods it owns.
matchLabels
ReplicaSet manages only Pods that have label app=nginx.
It searches for Pods where key = app and value = nginx.
template
Blueprint used to create new Pods.
template.metadata.labels
Every Pod created by this ReplicaSet gets label app=nginx.
This makes sure the selector can identify and manage them.
container image
Defines which application runs inside the Pod.
containerPort
Port used inside the container, not exposed outside automatically.
Core idea

ReplicaSet watches labels, not image or name.
It keeps the number of Pods with label app=nginx equal to replicas.

Apply the manifest

Terminal
bash
kubectl apply -f rs.yml

$ -f stands for the filename flag

Get the rs details

Terminal
bash
kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-replicaset 3 3 3 23s

Check the pods

Terminal
bash
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-replicaset-7zp2v 1/1 Running 0 35s
nginx-replicaset-q264f 1/1 Running 0 35s
nginx-replicaset-vj42z 1/1 Running 0 35s

Try deleting a pod and check if it self heals

Terminal
bash
kubectl delete pod nginx-replicaset-7zp2v
kubectl get pods

Try adding a pod with the app=nginx

Terminal
bash
kubectl run nginx-pod --image=nginx --labels="app=nginx"

Ensure it gets terminated immediately because the rs already has 3 pods

Scaling up the ReplicaSet

If we want to increase the number of pods from 3 to 5, we don't need to run messy commands to start new containers manually. All we have to do is edit the rs.yml file and change the replica count:

yaml
yaml
replicas: 5

Then, simply run the apply command again (kubectl apply -f rs.yml). The ReplicaSet will automatically detect the desired state has changed to 5, calculate that it needs 2 more pods, and start the rest of the 2 pods for us!

Delete the replicaset

Terminal
bash
kubectl delete rs nginx-replicaset
💡

Note the naming convention of the pods. The pods are named after the replicaset followed by a unique id (for eg nginx-replicaset-vj42z).

2.

Deployment

A Deployment in Kubernetes is a higher-level abstraction that manages a set of Pods and provides declarative updates to them. It offers features like scaling, rolling updates, and rollback capabilities, making it easier to manage the lifecycle of applications.

🎯 Role of Deployment

Even though the ReplicaSet (RS) is what does Pod management, the Deployment is what does ReplicaSet management.

A Deployment ensures that there is a smooth rollout. If the new image fails for some reason, the Deployment ensures the old ReplicaSet is maintained, preventing downtime and allowing for easy rollbacks.

Deployment
ReplicaSet
Pod #1
Pod #2
Pod #3

🔄 Rolling Updates

When you update a Deployment (e.g., by changing the container image from v1 to v2), it doesn't just kill all existing Pods and start new ones simultaneously. That would cause downtime. Instead, a Deployment performs a Rolling Update.

It creates a brand new ReplicaSet for the new version and gradually scales it up, while simultaneously scaling down the old ReplicaSet. This ensures that new Pods are ready to serve traffic before the old ones are terminated. If there is any issue or bug in the new code, the old Pods will keep running, preventing downtime for the application, and we can easily rollback the latest change to fix the issue.

Before Update (v1)
Deployment
ReplicaSet
image: backend:v1
Pod #1
Pod #2
Pod #3
During Rolling Update
kubectl apply -f deploy.yml
replicas = 3
image = backend:v2
Deployment
ReplicaSet
image: v1
Pod #3
ReplicaSet
image: v2
Pod #1
Pod #2
* Similarly the third pod will first start with new image, then the old pod will be terminated.

Rollbacks

If there happens to be an issue or bug in your new code, your old Pods will keep running until the new ones are fully healthy, ensuring no downtime for your application. If a deployment fails, or if you discover a bug after rolling out, you can easily rollback to the previous stable change to fix the issue on your own time.

# Roll back to the previous deployment revision
kubectl rollout undo deployment/nginx-deployment --to-revision=1
deployment.apps/nginx-deployment rolled back

Key Differences Between Deployment and Pod:

1. Abstraction Level:

  • Pod: A Pod is the smallest and simplest Kubernetes object. It represents a single instance of a running process in your cluster, typically containing one or more containers.
  • Deployment: A Deployment is a higher-level controller that manages a set of identical Pods. It ensures the desired number of Pods are running and provides declarative updates to the Pods it manages.

2. Management:

  • Pod: They are ephemeral, meaning they can be created and destroyed frequently.
  • Deployment: Deployments manage Pods by ensuring the specified number of replicas are running at any given time. If a Pod fails, the Deployment controller replaces it automatically.

3. Updates:

  • Pod: Directly updating a Pod requires manual intervention and can lead to downtime.
  • Deployment: Supports rolling updates, allowing you to update the Pod template (e.g., new container image) and roll out changes gradually. If something goes wrong, you can roll back to a previous version.

4. Scaling:

  • Pod: Scaling Pods manually involves creating or deleting individual Pods.
  • Deployment: Allows easy scaling by specifying the desired number of replicas. The Deployment controller adjusts the number of Pods automatically.

5. Self-Healing:

  • Pod: If a Pod crashes, it needs to be restarted manually unless managed by a higher-level controller like a Deployment.
  • Deployment: Automatically replaces failed Pods, ensuring the desired state is maintained.

⚔️ ReplicaSet vs Deployment

FeatureReplicaSetDeployment
Primary GoalEnsures a specific number of Pod replicas are running.Manages ReplicaSets and provides declarative updates for Pods.
Use CaseRarely used directly in modern Kubernetes environments.The standard, recommended way to deploy stateless applications.
Updates / RolloutsNo built-in support for rolling updates. Old pods must be deleted manually for new template changes to apply.Fully supports rolling updates with zero downtime. Gradually replaces old Pods with new ones.
RollbacksNot supported natively.Maintains rollout history, allowing instant rollbacks to previous stable versions.
Abstraction LevelDirectly governs Pods.Governs ReplicaSets (which in turn govern Pods).

Create a deployment

Lets create a deployment that starts 3 pods

Create deployment.yml

yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

Apply the deployment

Terminal
bash
kubectl apply -f deployment.yml

Get the deployment

Terminal
bash
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 18s

Get the rs

Terminal
bash
kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-576c6b7b6 3 3 3 34s

Get the pod

Terminal
bash
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-576c6b7b6-b6kgk 1/1 Running 0 46s
nginx-deployment-576c6b7b6-m8ttl 1/1 Running 0 46s
nginx-deployment-576c6b7b6-n9cx4 1/1 Running 0 46s

Try deleting a pod

Terminal
bash
kubectl delete pod nginx-deployment-576c6b7b6-b6kgk
pod "nginx-deployment-576c6b7b6-b6kgk" deleted

Ensure the pods are still up

Terminal
bash
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-576c6b7b6-m8ttl 1/1 Running 0 84s
nginx-deployment-576c6b7b6-n9cx4 1/1 Running 0 84s
nginx-deployment-576c6b7b6-x7y9z 0/1 ContainerCreating 0 4s