02 - Replicaset concepts with real examples
Understand core Kubernetes building blocks — Pod, ReplicaSet, and Deployment — with real-world examples, YAML manifests, and hands-on troubleshooting scenarios.
Kubernetes Core Concepts — ReplicaSet
2.1 What Is a ReplicaSet?
A ReplicaSet is a Kubernetes controller whose job is to ensure that a specified number of Pod replicas are running at all times. It continuously watches the cluster and takes corrective action:
- If a Pod crashes or is deleted → ReplicaSet creates a new one
- If there are too many Pods (e.g., you manually created extras) → ReplicaSet deletes the excess
- If a node goes down and takes Pods with it → ReplicaSet schedules replacement Pods on healthy nodes
┌────────────────────────────────────────────────────────┐
│ ReplicaSet │
│ replicas: 3 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │
│ │ Running │ │ Running │ │ Running │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ Pod 2 crashes ↓ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Pod 1 │ │ Pod 4 │ │ Pod 3 │ │
│ │ Running │ │ Creating │ │ Running │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ (auto-created by ReplicaSet) │
└────────────────────────────────────────────────────────┘
The key mechanism that allows a ReplicaSet to identify “its” Pods is the label selector. The ReplicaSet claims ownership of any Pod that matches its selector — this is how Kubernetes controllers work in general.
2.2 Why Is a ReplicaSet Used?
| Problem Without ReplicaSet | How ReplicaSet Solves It |
|---|---|
| Single Pod failure = application downtime | Maintains N replicas; one crash does not take down the app |
| Manual intervention needed when pods die | Automatic self-healing — no human needed |
| No way to distribute load across instances | Multiple pod replicas allow load balancer to distribute traffic |
| Node failure kills all pods on that node | ReplicaSet detects missing pods and reschedules on healthy nodes |
| Manual scaling is tedious | Single command to change replica count |
2.3 Where Is a ReplicaSet Used?
Direct use is rare. In practice, you almost never create a ReplicaSet directly. Instead, you create a Deployment (covered in the next section), which automatically creates and manages ReplicaSets for you. The reasons for this are:
- Deployments add rolling update capability on top of ReplicaSets
- Deployments maintain a history of ReplicaSets for rollback
- Deployments give you fine-grained control over how updates are applied
However, understanding ReplicaSets is essential because:
- They appear in
kubectl get alloutput and you need to understand what they are - Debugging deployment issues often requires inspecting the underlying ReplicaSet
- Some GitOps tools and operators create ReplicaSets directly
Real-world ReplicaSet appearances:
- Backend API services running 3+ replicas for high availability
- Stateless web front-ends scaled to handle traffic
- Worker processes consuming from a queue
2.4 ReplicaSet YAML Manifest — Full Breakdown
apiVersion: apps/v1 # ReplicaSet is in the apps API group
kind: ReplicaSet
metadata:
name: nginx-replicaset
namespace: default
labels:
app: nginx
tier: frontend
spec:
replicas: 3 # Desired number of pod replicas at all times
selector: # How the ReplicaSet identifies the pods it owns
matchLabels:
app: nginx # Must match the labels in template.metadata.labels below
tier: frontend
template: # Pod template — same as a pod spec, but nested here
metadata:
labels:
app: nginx # MUST match the selector above — this is how RS finds its pods
tier: frontend
version: "1.25"
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Critical Rule: The labels in
spec.selector.matchLabelsMUST exactly match the labels inspec.template.metadata.labels. If they do not match, Kubernetes will reject the ReplicaSet with a validation error.
2.5 Essential ReplicaSet Commands
# Create a ReplicaSet from a manifest
kubectl apply -f nginx-replicaset.yaml
# List all ReplicaSets
kubectl get replicasets
kubectl get rs # short form
# Detailed view with pod counts
kubectl get rs -o wide
# Describe a ReplicaSet (shows selector, pod status, events)
kubectl describe rs nginx-replicaset
# Scale a ReplicaSet (imperative)
kubectl scale rs nginx-replicaset --replicas=5
# Scale using the manifest file (declarative — preferred)
# Edit replicas: 5 in the YAML, then:
kubectl apply -f nginx-replicaset.yaml
# Delete a ReplicaSet (also deletes the pods it owns)
kubectl delete rs nginx-replicaset
# Delete ReplicaSet but keep the pods running
kubectl delete rs nginx-replicaset --cascade=orphan
# Get the pods owned by a ReplicaSet (using label selector)
kubectl get pods -l app=nginx,tier=frontend
2.6 Real-World Troubleshooting — ReplicaSet
Scenario 1: ReplicaSet not creating pods
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-replicaset 3 0 0 30s
DESIRED is 3 but CURRENT is 0 — no pods are being created.
kubectl describe rs nginx-replicaset
Events section:
Warning FailedCreate 20s replicaset-controller
Error creating: pods "nginx-replicaset-" is forbidden:
maximum pod limit reached for namespace "default"
Root Cause: A LimitRange or ResourceQuota in the namespace is preventing new pod creation.
# Check resource quotas
kubectl get resourcequota -n default
kubectl describe resourcequota -n default
# Check limit ranges
kubectl get limitrange -n default
kubectl describe limitrange -n default
Scenario 2: Pods running but not ready
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-replicaset 3 3 1 5m
READY is 1/3 — only one pod is ready even though 3 are running.
# Check the individual pods
kubectl get pods -l app=nginx
# NAME READY STATUS RESTARTS AGE
# nginx-replicaset-2k9xz 1/1 Running 0 5m
# nginx-replicaset-7mfvp 0/1 Running 0 5m
# nginx-replicaset-9nlqt 0/1 Running 0 5m
kubectl describe pod nginx-replicaset-7mfvp
Events reveal:
Warning Unhealthy 3m kubelet
Readiness probe failed: HTTP probe failed with statuscode: 503
Root Cause: The readiness probe is failing — the application is running but returning HTTP 503, so the pods are excluded from service endpoints. This usually means the app is waiting for a dependency (database, cache, config).
Fix:
# Exec into the pod to test manually
kubectl exec -it nginx-replicaset-7mfvp -- curl -s http://localhost:80/ready
# Check application logs
kubectl logs nginx-replicaset-7mfvp
Scenario 3: Manually deleted pod instantly recreates
Situation: You delete a pod but it immediately comes back with a new name. This surprises many beginners.
$ kubectl delete pod nginx-replicaset-2k9xz
pod "nginx-replicaset-2k9xz" deleted
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-replicaset-xt8pl ContainerCreating 0 2s # NEW pod created immediately!
nginx-replicaset-7mfvp Running 0 5m
nginx-replicaset-9nlqt Running 0 5m
This is expected and correct behaviour — the ReplicaSet controller detected that only 2 pods existed and immediately created a 3rd to maintain the desired state of 3 replicas.
To actually scale down, change the replica count:
kubectl scale rs nginx-replicaset --replicas=2