What is ReplicaSet?
In practice, ReplicaSet is rarely created directly — Deployment creates it. Deployment manages the ReplicaSet, and the ReplicaSet manages Pods.
Junior Level
Simple Explanation
ReplicaSet (RS) is a Kubernetes controller that guarantees a specified number of Pod replicas are always running. If a Pod crashes — the ReplicaSet launches a new one.
In practice, ReplicaSet is rarely created directly — Deployment creates it. Deployment manages the ReplicaSet, and the ReplicaSet manages Pods.
Simple Analogy
A ReplicaSet is like a store manager who ensures the right number of cashiers are always at the registers. If one goes on break — the manager calls another.
How Does a ReplicaSet Work?
- You say: “I need 3 copies of the application”
- ReplicaSet checks: “How many are running now?”
- If less than 3 — launches new Pods
- If more than 3 — removes extra ones
- Repeats constantly (Reconciliation Loop)
Example
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs
spec:
replicas: 3 # I want 3 copies
selector:
matchLabels:
app: myapp # Finds Pods with this label
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
ReplicaSet vs Deployment
ReplicaSet vs Deployment: ReplicaSet guarantees N Pod copies. Deployment adds rolling updates, rollback, revision history. In 99% of cases, use Deployment.
In reality you almost never create a ReplicaSet manually. Instead you use Deployment — it manages ReplicaSets for you.
Deployment adds:
- Rolling updates (update without downtime)
- Rollback (revert to previous version)
- Version history
What a Junior Developer Should Remember
- ReplicaSet maintains the desired number of Pods
- If a Pod crashes — ReplicaSet creates a new one
- In production use Deployment, not ReplicaSet
- Deployment manages ReplicaSets
- Label selectors link ReplicaSet to Pods
Middle Level
Reconciliation Loop
ReplicaSet works on an infinite loop principle:
1. Read desired replicas from spec.replicas
2. Count current Pods by selector
3. If less than desired → create Pods
4. If more than desired → delete Pods
5. Wait and repeat
This loop provides self-healing: no matter how many Pods crash, the ReplicaSet always strives toward the desired state.
Relationship with Deployment
Deployment
↓ manages
ReplicaSet v1 (image: myapp:1.0, replicas: 0) ← old version
ReplicaSet v2 (image: myapp:2.0, replicas: 3) ← current version
↓ manages
Pod × 3
When updating a Deployment:
- Creates a new ReplicaSet with the new image
- Gradually moves Pods from the old RS to the new one
- Old RS is preserved for rollback
Selectors
ReplicaSet uses set-based selectors:
selector:
matchLabels:
app: myapp
env: production
# Or more complex:
selector:
matchExpressions:
- key: app
operator: In
values: [myapp, myapp-v2]
- key: env
operator: NotIn
values: [development]
ownerReference
Each Pod has a reference to its ReplicaSet:
metadata:
ownerReferences:
- apiVersion: apps/v1
kind: ReplicaSet
name: myapp-rs-abc123
uid: ...
This allows K8s to automatically delete Pods when the ReplicaSet is deleted.
Why Not ReplicationController?
ReplicationController is a legacy object. ReplicaSet differs by supporting set-based selectors with In, NotIn, Exists operators.
What a Middle Developer Should Remember
- ReplicaSet = mechanism for maintaining replica count
- Reconciliation Loop constantly compares desired vs actual
- Deployment manages ReplicaSets for rolling updates
- Set-based selectors are more powerful than simple matchLabels
- ownerReference ensures cascading deletion
Senior Level
ReplicaSet as a Fault Tolerance Primitive
ReplicaSet is a low-level controller that implements Kubernetes’ fundamental pattern: declarative state reconciliation.
ReplicaSet Controller Architecture
kube-controller-manager
└── replicaset-controller
├── Watch ReplicaSet changes
├── Watch Pod changes
├── Sync: compare desired vs actual
├── Scale up: create Pods
└── Scale down: delete Pods
Controller subscribes to events:
- ReplicaSet creation/modification
- Pod deletion (to replace them)
- Pod changes matching the selector
Pod Disruption and ReplicaSet
During kubectl drain or node eviction:
- Pods are marked for deletion
- ReplicaSet sees a decrease in Pod count
- Creates new Pods on other Nodes
- drain completes, old Pods removed
Overlapping Selectors: Danger
# ReplicaSet A
selector:
matchLabels:
app: myapp
tier: frontend
# ReplicaSet B
selector:
matchLabels:
app: myapp
If a Pod has labels app: myapp, tier: frontend, both RS may try to manage it. This leads to undefined behavior.
Protection: Kubernetes doesn’t prevent overlapping selectors — responsibility is on the engineer.
Adoption of Existing Pods
A ReplicaSet can “adopt” already existing Pods:
# Pod created manually
kubectl run myapp --image=myapp:1.0 --labels=app=myapp
# Create RS with the same selector
# RS "sees" the existing Pod and adopts it
This is used when migrating from manual Pods to Deployment.
Scaling a ReplicaSet
# Imperative
kubectl scale rs myapp-rs --replicas=5
# Via kubectl edit
kubectl edit rs myapp-rs
# Via patch
kubectl patch rs myapp-rs -p '{"spec":{"replicas":5}}'
When to Create a ReplicaSet Directly?
Almost never. The only scenarios:
- Learning/understanding K8s internals
- Custom controllers (based on ReplicaSet logic)
- Specific use cases where Deployment doesn’t fit
Troubleshooting
Pods aren’t created:
kubectl describe rs myapp-rs
# Events: Normal SuccessfulCreate pod/myapp-xyz created
# Warning FailedCreate error creating pods
Too many Pods:
- Check for overlapping selectors
- Check if another controller is creating Pods
Pods aren’t deleted:
- Check PodDisruptionBudget
- Check finalizers on Pods
Summary for Senior
- ReplicaSet guarantees N copies of the application.
- It’s a low-level mechanism managed by Deployment.
- Reconciliation Loop — fundamental K8s pattern.
- RS can’t update images — that’s Deployment logic.
- Overlapping selectors → undefined behavior.
- ownerReference ensures cascading deletion.
- Use labels carefully so RS doesn’t accidentally delete someone else’s Pods.
Interview Cheat Sheet
Must know:
- ReplicaSet guarantees the specified number of Pod replicas (reconciliation loop)
- In 99% of cases use Deployment, not ReplicaSet directly
- Deployment manages ReplicaSets for rolling updates and rollback
- Reconciliation Loop: desired vs actual → create/delete Pods → repeat
- ownerReference ensures cascading Pod deletion when RS is deleted
- Overlapping selectors → undefined behavior (two RS compete)
- ReplicationController is legacy; ReplicaSet supports set-based selectors
Frequent follow-up questions:
- “Why ReplicaSet if there’s Deployment?” — Deployment is a high-level abstraction; RS is the mechanism under the hood
- “What happens if you delete a ReplicaSet?” — All Pods are deleted (ownerReference cascade)
- “Can RS update images?” — No, that’s Deployment logic
- “Can RS adopt existing Pods?” — Yes, if the Pod matches the selector (adoption)
Red flags (DO NOT say):
- “I create ReplicaSet directly in production” (use Deployment)
- “ReplicaSet does rolling updates” (that’s Deployment)
- “Overlapping selectors aren’t a problem” (leads to race conditions)
- “ReplicationController is the modern standard” (deprecated, use ReplicaSet)
Related topics:
- [[What is Kubernetes and why is it needed]] — K8s controllers
- [[How to organize rolling update in Kubernetes]] — Deployment + RS
- [[How scaling works in Kubernetes]] — replica scaling