Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Deploy a ReplicaSet

Learn how to deploy a ReplicaSet for scaling in Kubernetes with step-by-step hands-on exercises and troubleshooting.

Focus: deploy a Replicaset for scaling

Sponsored

When your application starts receiving real traffic — even moderate traffic — you quickly realize that a single Pod isn't enough. One Pod can crash, get evicted for resource pressure, or simply run out of capacity. Manually restarting it every time is not a strategy. This is the problem that the Kubernetes ReplicaSet solves: it ensures that a specified number of identical Pod replicas are running at all times, providing automatic self-healing and a foundation for scaling.

The problem this lesson solves

Running a single instance of your application in a Kubernetes Pod is fragile. If that Pod dies, your service goes down until someone (or something) recreates it. Even if you use kubectl run, that Pod has no built-in ability to come back after a node failure or a crash-loop. Without a ReplicaSet, you are responsible for babysitting your workloads. Scaling manually (creating Pods one by one) is error-prone and doesn't handle failure recovery. The ReplicaSet abstraction solves all three pain points:

  • Automatic recovery — If a Pod is deleted or crashes, the ReplicaSet controller notices the mismatch between desired replicas and actual replicas, and immediately creates a replacement.
  • Scaling on demand — You can increase or decrease the replica count with a single command (kubectl scale) or by editing the YAML.
  • Predictable naming — Each Pod gets a unique name with a hash suffix, making them easy to identify and manage.

Pro tip: Think of a ReplicaSet as your application's safety net — it tolerates failures without manual intervention.

Core concept / mental model

A ReplicaSet is a desired-state controller. You declare how many Pods you want to run, and the ReplicaSet continuously works to match that number. If a Pod disappears for any reason, the ReplicaSet creates a new one to bring the count back to the desired level.

Definitions

  • ReplicaSet: A Kubernetes object that ensures a specified number of identical Pod replicas are running at any given time.
  • Desired replicas: The target number of Pods you want to run (e.g., replicas: 3).
  • Selector: A label query that the ReplicaSet uses to identify which Pods belong to it.
  • Pod template: The Pod specification (containers, volumes, etc.) that the ReplicaSet uses when creating new Pods.

Diagram-in-words

Imagine you run a food truck. You need three cooks to handle the lunch rush. You hire three people (Pods). If one calls in sick (Pod crashes), you immediately call a temp agency to replace them (ReplicaSet creates a new Pod). You don't want more than three cooks, so you don't hire extras unless you scale up the operation. This is exactly how a ReplicaSet works — it's a replacement-as-a-service for your Pods.

How it works step by step

Creating a ReplicaSet involves writing a YAML manifest and applying it to your cluster. Here's the minimal structure:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-app-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: nginx:1.25

The key parts:

  1. apiVersion: apps/v1 (must use apps/v1, not the deprecated extensions/v1beta1).
  2. spec.replicas: The desired number of Pod copies.
  3. spec.selector.matchLabels: A label query that the ReplicaSet uses to find matching Pods. This must match the labels in the template.
  4. spec.template: The Pod template — every field under template.spec is exactly as you would write in a Pod manifest.

Lifecycle of a ReplicaSet

  1. You kubectl apply -f replicaset.yaml.
  2. The Kubernetes control plane registers the ReplicaSet object.
  3. The ReplicaSet controller (part of the controller-manager) starts a reconciliation loop.
  4. It counts existing Pods with matching labels; if fewer than replicas, it creates new Pods from the template.
  5. If a Pod is deleted, the loop detects the mismatch and creates a replacement.
  6. If you kubectl scale replicaset my-app-replicaset --replicas=5, the controller creates two more Pods.

Key point: The ReplicaSet only manages existence — it does not perform rolling updates or rollbacks. That's the role of a Deployment (which wraps a ReplicaSet).

Hands-on walkthrough

Let's create a ReplicaSet for a simple web server and test its behavior.

Step 1: Create the ReplicaSet YAML

Save the following as nginx-replicaset.yaml:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      tier: web
  template:
    metadata:
      labels:
        app: nginx
        tier: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80

Step 2: Apply the manifest

kubectl apply -f nginx-replicaset.yaml

Output:

replicaset.apps/nginx-rs created

Step 3: View the ReplicaSet

kubectl get rs

Expected output (example):

NAME       DESIRED   CURRENT   READY   AGE
nginx-rs   3         3         3       10s

Step 4: List the Pods

kubectl get pods

Expected output (names may vary):

NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-5f9k2   1/1     Running   0          10s
nginx-rs-7h4j8   1/1     Running   0          10s
nginx-rs-8m3p1   1/1     Running   0          10s

Notice the naming pattern: {replicaset-name}-{random-hash}. This hash ensures unique Pod names.

Step 5: Test self-healing — delete a Pod

kubectl delete pod nginx-rs-5f9k2

Now list Pods again within a few seconds:

kubectl get pods

Expected output:

NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-7h4j8   1/1     Running   0          50s
nginx-rs-8m3p1   1/1     Running   0          50s
nginx-rs-v9c2q   1/1     Running   0          5s   <-- new Pod

The ReplicaSet immediately created a replacement Pod. The name is different because it's a brand-new Pod.

Step 6: Scale the ReplicaSet

kubectl scale rs nginx-rs --replicas=5

Check:

kubectl get pods

You'll now see five Pods running.

Step 7: Delete the ReplicaSet

To clean up and remove all associated Pods:

kubectl delete rs nginx-rs

This deletes both the ReplicaSet object and the Pods it manages.

Compare options / when to choose what

You might wonder when to use a ReplicaSet directly versus other workload resources:

Resource Use Case Manages Updates? Self-Healing? Scaling?
ReplicaSet Reference-only scaling, batch/stateless workloads No Yes (recreation only) Yes
ReplicationController (Legacy) Older clusters; deprecated No Yes Yes
Deployment Long-running apps requiring rollouts & rollbacks Yes (rolling, canary) Yes (via ReplicaSet) Yes (via replicas field)
StatefulSet Stateful apps (databases, queues) Yes (ordered/graceful) Yes (with stable identity) Yes (carefully)
DaemonSet Exactly one Pod per node (logging, monitoring) No (per-node) Yes Not typical

When to use a ReplicaSet directly:

  • Learning purposes — Understand the controller pattern without deployment complexity.
  • Non-updating workloads — Batch jobs that don't need rolling updates (although Job may be better).
  • Custom controllers — If you're writing your own controller that orchestrates ReplicaSets.

Pro tip: In production, you almost always want a Deployment instead of a bare ReplicaSet. A Deployment manages a ReplicaSet and adds rollout/rollback capabilities. The ReplicaSet exists as a building block within a Deployment.

Troubleshooting & edge cases

Common mistakes and how to fix them

  • Mismatched labels: The selector.matchLabels must match the labels in the Pod template. If they don't, the ReplicaSet will fail to match any Pods and create all of them from scratch (even if you intended to adopt existing ones).
  • Fix: Ensure selector.matchLabels is a subset of the template.metadata.labels.

  • Pods stuck in Pending: The ReplicaSet creates Pods, but they stay Pending. This means the scheduler cannot find a node with enough resources.

  • Fix: Check node resources with kubectl describe nodes. Reduce replicas or add more nodes.

  • Pods crash-looping before ReplicaSet can stabilize: If the container image has a bad entry point, Pods will crash immediately. The ReplicaSet will keep creating new ones, causing a churn.

  • Fix: Debug with kubectl logs <pod-name> to see the container error. Fix the image or configuration.

  • Orphaned ReplicaSets: If you delete a Deployment without cascading, its ReplicaSets may remain. They continue to manage Pods, possibly causing unexpected scaling.

  • Fix: Use kubectl delete deployment <name> (which cascades) or manually clean up ReplicaSets.

  • Scaling down too aggressively: Dropping replica count too fast can cause connection drops if your service doesn't handle graceful shutdown.

  • Fix: Use a preStop lifecycle hook and terminationGracePeriodSeconds in the Pod template to allow in-flight requests to complete.

What you learned & what's next

You now understand how to deploy a ReplicaSet for scaling in Kubernetes. You know:

  • The core concept of desired-state controllers and self-healing.
  • How to write a ReplicaSet YAML with replicas, selector, and template.
  • How to apply, view, scale, and delete a ReplicaSet using kubectl.
  • The difference between ReplicaSets, Deployments, and other workload resources.
  • How to troubleshoot common issues like mismatched labels and stuck Pods.

What's next? The ReplicaSet is a powerful primitive, but for real-world deployments you'll almost always use a Deployment — which wraps a ReplicaSet and adds rolling updates, rollbacks, and revision history. In the next lesson, you'll learn how to create and manage Deployments, building on the ReplicaSet foundation you just mastered.

Practice recap

Create a ReplicaSet with 3 replicas running the httpd:2.4 image. Scale it to 5 replicas. Then delete one Pod and confirm the ReplicaSet recreates it. Finally, clean up by deleting the ReplicaSet. This reinforces the core concept of desired-state management.

Common mistakes

  • Forgetting to match selector.matchLabels with template.metadata.labels — the ReplicaSet won't adopt existing Pods, causing duplicate creation.
  • Deleting a Pod manually and expecting it to stay deleted — the ReplicaSet will immediately recreate it.
  • Using extensions/v1beta1 API version instead of apps/v1 — the old version is deprecated and may be removed.
  • Scaling up without enough node resources — Pods will remain in Pending state indefinitely.

Variations

  1. Using kubectl scale to change replicas dynamically instead of editing the YAML file and reapplying.
  2. Using a HorizontalPodAutoscaler (HPA) to automatically adjust replica count based on CPU/memory metrics.
  3. Using a Deployment instead of a bare ReplicaSet — the Deployment manages the ReplicaSet and adds rollout capabilities.

Real-world use cases

  • Scaling a web frontend across three replicas to handle traffic spikes with zero-downtime recovery if a Pod fails.
  • Running a stateless API backend with a ReplicaSet that ensures 5 replicas are always available during node maintenance.
  • Using a ReplicaSet as the underlying controller for a custom operator that manages distributed batch processing jobs.

Key takeaways

  • A ReplicaSet ensures a specified number of identical Pods are always running, providing self-healing and scaling.
  • You define replicas, a label selector, and a Pod template in the YAML manifest under spec.
  • kubectl apply, kubectl get rs, and kubectl scale are the primary commands for managing ReplicaSets.
  • The ReplicaSet only manages Pod existence — it does not handle rolling updates (use a Deployment for that).
  • Always match selector.matchLabels with template.metadata.labels to avoid orphaned or duplicate Pods.
  • In production, prefer Deployments over bare ReplicaSets for rollout safety.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.