In the previous tutorials, we learned what a Kubernetes Pod is, how to create one, and how to manage Kubernetes resources with YAML definition files.
But one important question remains.
Say you have a web application running in Kubernetes.
There is one Pod for the application.
Pod 1 → Web Application
Now, for some reason, the Pod fails.
What happens then?
If it is a standalone Pod and it gets deleted, or its node becomes permanently unavailable, the application can become unavailable.
To solve this problem, Kubernetes uses controllers.
In this tutorial, we will learn about two important controllers:
- ReplicationController
- ReplicaSet
Their main job is to maintain the desired number of Pod replicas.
1. What is a Kubernetes controller?
In Kubernetes, a controller is a component that monitors the current state of Kubernetes resources and tries to make it match the desired state.
Say you told Kubernetes:
My application must always have three Pods.
Now the controller checks:
Desired State = 3 Pods
Current State = 3 Pods
Action = Nothing
But if one Pod is deleted:
Desired State = 3 Pods
Current State = 2 Pods
Action = Create 1 New Pod
This way, the controller continuously tries to maintain the desired state.
Controller workflow
Desired State
3 Pods
|
▼
Kubernetes Controller
|
▼
Check Actual State
|
+------+------+
| |
▼ ▼
3 Pods 2 Pods
| |
▼ ▼
No Action Create 1 Pod
This process is called Kubernetes' reconciliation loop.
The controller keeps observing the current state and acts when needed.
2. Why does an application need multiple replicas?
Say you have an NGINX web application.
It is currently running in one Pod.
Kubernetes Cluster
|
▼
Pod 1
|
▼
Web Application
If this Pod becomes unavailable, the application can have an availability problem.
Now, if you run three replicas of the same application:
Kubernetes Cluster
|
+-------+-------+
| | |
▼ ▼ ▼
Pod 1 Pod 2 Pod 3
| | |
▼ ▼ ▼
App App App
then even if one Pod fails, the other Pods can still serve the application.
This makes it possible to improve the application's high availability.
What is high availability?
High availability means designing an application so that the service stays available as much as possible, even when one component fails.
But multiple Pods alone don't guarantee complete high availability.
Service routing, readiness checks and multiple nodes matter too.
3. What is a replica?
A replica is one Pod instance running the same application.
Say your application image is:
nginx
Now you want to run three replicas.
That means:
Replica 1 → NGINX Pod
Replica 2 → NGINX Pod
Replica 3 → NGINX Pod
In other words:
3 replicas = 3 Pod instances of the same application.
Example
Deployment / ReplicaSet
|
▼
replicas: 3
|
+-------+-------+
| | |
▼ ▼ ▼
Pod 1 Pod 2 Pod 3
| | |
NGINX NGINX NGINX
The Kubernetes controller tries to maintain the desired replica count.
4. What is a ReplicationController?
A ReplicationController is a Kubernetes controller whose job is to maintain a specific number of Pods.
Say the configuration says:
replicas: 3
That means Kubernetes will try to maintain three matching Pods.
Example
Desired Replicas: 3
Actual Pods: 2
Missing Pods: 1
The ReplicationController will then create a new Pod.
Before:
Pod 1 → Running
Pod 2 → Running
Pod 3 → Deleted
After:
Pod 1 → Running
Pod 2 → Running
Pod 4 → Created
Here, creating a new Pod restores the desired replica count.
Is a controller only needed for scaling?
No.
Say you only want to run one Pod.
replicas: 1
If that Pod is deleted, the controller can create a replacement Pod.
This is called self-healing.
Self-healing example
Desired State
|
▼
1 Pod
|
▼
Pod Deleted
|
▼
Controller Detects Difference
|
▼
New Pod Created
So a ReplicationController is useful not only for scaling, but also for replacing Pods.
5. Load sharing and scaling
When an application's traffic grows, one Pod may not be able to handle all the requests.
Then you can create more replicas.
Before scaling
Node 1
|
└── Pod 1
|
▼
Web App
After scaling
Node 1
|
├── Pod 1 → Web App
|
├── Pod 2 → Web App
|
└── Pod 3 → Web App
Now three Pods of the same application are running.
If Node 1 doesn't have enough available resources, Kubernetes can schedule Pods on other suitable nodes.
Multi-node example
Kubernetes Cluster
|
+----------+----------+
| |
▼ ▼
Node 1 Node 2
| |
+---+---+ +---+---+
| | | |
▼ ▼ ▼ ▼
Pod 1 Pod 2 Pod 3 Pod 4
| | | |
App App App App
This way, application workloads can be distributed across multiple nodes of the cluster.
Important: a ReplicaSet does not load-balance HTTP traffic itself. A Kubernetes Service is usually used to distribute traffic across the matching Pods.
6. ReplicationController vs ReplicaSet
A ReplicationController and a ReplicaSet have the same main goal:
maintaining the desired number of matching Pods.
But there are some differences between them.
| Feature | ReplicationController | ReplicaSet |
|---|---|---|
| Technology | Older | Newer |
| API Version | v1 | apps/v1 |
| Selector | Optional / can be inferred | Explicitly required |
| Label Matching | Equality-based | Equality- and set-based |
| Modern Usage | Rare | Commonly used |
| Recommended Approach | Legacy workloads | Usually through a Deployment |
A ReplicaSet supports more flexible label selectors than a ReplicationController.
In a modern Kubernetes environment, instead of creating ReplicaSets directly, we usually use a Deployment.
Because the Deployment manages the ReplicaSet itself.
Deployment
|
▼
ReplicaSet
|
▼
Pods
Still, understanding how a ReplicaSet works is important for learning Kubernetes' internal architecture.
7. ReplicationController YAML structure
The four main sections of a ReplicationController definition file are:
apiVersion: v1
kind: ReplicationController
metadata:
spec:
Now let's look at a complete example.
rc-definition.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
app: myapp
type: frontend
spec:
replicas: 3
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: frontend
spec:
containers:
- name: nginx-container
image: nginx
This YAML file tells Kubernetes:
Create a ReplicationController named
myapp-rcand maintain three matching Pods of themyappapplication.
YAML breakdown
| Field | Meaning |
|---|---|
apiVersion: v1 | Kubernetes API version |
kind: ReplicationController | Resource type |
metadata.name | Controller name |
metadata.labels | The controller's labels |
spec.replicas | Desired Pod replicas |
spec.template | Pod creation template |
template.metadata.labels | Labels of the created Pods |
template.spec.containers | Container configuration |
ReplicationController structure
ReplicationController
|
├── apiVersion: v1
|
├── kind: ReplicationController
|
├── metadata
| |
| ├── name
| └── labels
|
└── spec
|
├── replicas: 3
|
└── template
|
├── metadata
| |
| └── labels
|
└── spec
|
└── containers
|
└── NGINX
8. Why does a controller need a Pod template?
A ReplicationController or ReplicaSet needs to know how to create a replacement Pod.
This information is defined in the template field.
Example:
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: nginx-container
image: nginx
This template tells Kubernetes:
- What the new Pod's labels will be
- Which container image will run
- What the container's name will be
Example
Say three Pods are running.
Pod 1 → Running
Pod 2 → Running
Pod 3 → Deleted
The controller detects that one replica is missing.
It will now create a new Pod using the template.
Controller
|
▼
Pod Template
|
▼
Create New Pod
|
▼
Pod 4
The Pod template is the blueprint for creating new replacement Pods.
Does the template need apiVersion and kind?
The template of a ReplicationController or ReplicaSet is an embedded Pod template.
You don't write the Pod's own root-level apiVersion and kind here.
Because the parent controller resource's spec.template is already defined as a Pod template.
9. ReplicaSet YAML structure
A ReplicaSet's YAML structure is quite similar to a ReplicationController's.
But there are two important differences.
First:
apiVersion: apps/v1
kind: ReplicaSet
Second, a ReplicaSet needs an explicit selector.
replicaset-definition.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs
labels:
app: myapp
type: frontend
spec:
replicas: 3
selector:
matchLabels:
app: myapp
type: frontend
template:
metadata:
labels:
app: myapp
type: frontend
spec:
containers:
- name: nginx-container
image: nginx
Here, Kubernetes will create a ReplicaSet.
The ReplicaSet will try to maintain three matching Pods.
ReplicaSet structure
ReplicaSet
|
├── apiVersion: apps/v1
|
├── kind: ReplicaSet
|
├── metadata
|
└── spec
|
├── replicas: 3
|
├── selector
| |
| └── matchLabels
|
└── template
|
├── metadata
| |
| └── labels
|
└── spec
|
└── containers
Why does the API version matter?
The correct API version for a ReplicaSet is:
apiVersion: apps/v1
With the wrong API version, Kubernetes may not recognize the resource.
For example, writing apiVersion: v1 for a ReplicaSet can produce an error like this:
no matches for kind "ReplicaSet" in version "v1"
So it is important to use the correct API version for the resource type.
10. How do selectors and labels work?
One of the most important features of a ReplicaSet is the label selector.
With the selector, the ReplicaSet decides which Pods count toward its desired replica count.
Example:
selector:
matchLabels:
app: myapp
type: frontend
This selector means:
Match the Pods that have both the
app=myappandtype=frontendlabels.
Pod template labels
template:
metadata:
labels:
app: myapp
type: frontend
Here, the Pod template's labels match the ReplicaSet's selector.
Selector matching
ReplicaSet
|
▼
Selector
|
├── app: myapp
|
└── type: frontend
|
▼
Matching Pods
|
+------+------+
| | |
▼ ▼ ▼
Pod 1 Pod 2 Pod 3
Here, the labels of three Pods match the selector.
Important rule
A ReplicaSet's selector must match its Pod template's labels.
If the selector and the template labels don't match, the ReplicaSet definition can be invalid.
11. Why do selectors matter?
Many kinds of Pods can be running in one Kubernetes cluster.
For example:
Frontend Pods
Backend Pods
Database Pods
Monitoring Pods
Logging Pods
The ReplicaSet needs to know which Pods belong to its application.
Labels and selectors do that job.
Example
Pod labels:
labels:
app: myapp
ReplicaSet selector:
selector:
matchLabels:
app: myapp
This selector matches Pods that have the app=myapp label.
Matching logic
Pod Label
|
▼
app=myapp
|
▼
ReplicaSet Selector
|
▼
app=myapp
|
▼
Match
Important: matching labels alone don't make a ReplicaSet automatically take over another controller's Pods.
A ReplicaSet can adopt existing Pods when they match and are not owned by another controller.
12. Can a ReplicaSet manage existing Pods?
Yes.
A ReplicaSet can adopt Pods that already exist in the cluster and match its selector, as long as the ownership rules allow it.
Say there are already three standalone Pods in the cluster.
Pod A → app=myapp
Pod B → app=myapp
Pod C → app=myapp
Now a ReplicaSet is created.
replicas: 3
selector:
matchLabels:
app: myapp
If the existing Pods are not owned by another controller and match the selector, the ReplicaSet can adopt them.
Since three matching Pods already exist, it may not need to create any new Pods.
Example
Existing Pods
|
├── Pod A
├── Pod B
└── Pod C
|
▼
ReplicaSet
|
▼
Desired: 3 Pods
|
▼
No New Pod
But if one Pod is deleted later, the ReplicaSet can create a replacement Pod using its template.
That is why defining the template in a ReplicaSet is essential.
13. Creating a ReplicationController and a ReplicaSet
Now let's look at the commands for creating controllers from YAML files.
Creating a ReplicationController
File name:
rc-definition.yaml
Command:
kubectl create -f rc-definition.yaml
Listing ReplicationControllers
kubectl get replicationcontroller
Short form:
kubectl get rc
Creating a ReplicaSet
File name:
replicaset-definition.yaml
Command:
kubectl create -f replicaset-definition.yaml
Listing ReplicaSets
kubectl get replicaset
Short form:
kubectl get rs
Checking the Pods
kubectl get pods
Example output:
NAME READY STATUS RESTARTS
myapp-rs-xxxxx 1/1 Running 0
myapp-rs-yyyyy 1/1 Running 0
myapp-rs-zzzzz 1/1 Running 0
Pods created by a ReplicaSet usually have generated names.
Their names often start with the ReplicaSet's name.
14. How does ReplicaSet scaling work?
Say our ReplicaSet's configuration is:
replicas: 3
That means Kubernetes is maintaining three matching Pods.
Now the application's traffic has grown.
So we want to run six Pods.
There are two common ways to scale a ReplicaSet.
Method 1: update the YAML and apply it
First, open the YAML file.
The previous configuration:
replicas: 3
Change it to:
replicas: 6
Then:
kubectl apply -f replicaset-definition.yaml
This command applies the updated YAML configuration to the cluster.
Before scaling
ReplicaSet
|
▼
replicas: 3
|
├── Pod 1
├── Pod 2
└── Pod 3
After scaling
ReplicaSet
|
▼
replicas: 6
|
├── Pod 1
├── Pod 2
├── Pod 3
├── Pod 4
├── Pod 5
└── Pod 6
Important: here the YAML file is edited by hand, and then kubectl apply updates the cluster state.
kubectl apply does not edit the local YAML file itself.
Method 2: use kubectl scale
You can also scale the live ReplicaSet without editing the YAML file.
Scaling with a file reference
kubectl scale --replicas=6 -f replicaset-definition.yaml
Scaling by ReplicaSet name
kubectl scale --replicas=6 replicaset myapp-rs
Here, Kubernetes sets the live ReplicaSet's desired replica count to six.
An important difference
The kubectl scale command updates the live object in the cluster.
But it does not update the local YAML file automatically.
Say the YAML file still contains:
replicas: 3
But the cluster has been scaled to:
Desired Replicas: 6
Now there is a difference between the YAML file and the live cluster configuration.
Later, when the declarative configuration is reconciled, the desired replica count may change back.
So if you use Git-based configuration management, it is better to update the YAML file too.
15. Deleting a ReplicaSet
To remove a ReplicaSet:
kubectl delete replicaset myapp-rs
By default, Kubernetes also tries to delete the Pods the ReplicaSet manages.
Workflow
Delete ReplicaSet
|
▼
ReplicaSet Removed
|
▼
Managed Pods Deleted
In other words, deleting a ReplicaSet usually deletes its managed Pods as well.
16. Useful Kubernetes commands
| Command | Purpose |
|---|---|
kubectl create -f file.yaml | Create an object from a YAML file |
kubectl get rc | List ReplicationControllers |
kubectl get rs | List ReplicaSets |
kubectl get pods | List Pods |
kubectl delete replicaset myapp-rs | Delete a ReplicaSet |
kubectl replace -f file.yaml | Replace an existing object's configuration |
kubectl apply -f file.yaml | Apply declarative configuration |
kubectl scale --replicas=6 -f file.yaml | Scale using a file reference |
kubectl scale --replicas=6 replicaset myapp-rs | Scale by ReplicaSet name |
17. A simple mental model of a ReplicaSet
You can think of a ReplicaSet as a supervisor.
Say you told the supervisor:
Always keep three workers on the job.
The supervisor checks:
Required Workers: 3
Available Workers: 3
Action: Nothing
Now one worker leaves.
Required Workers: 3
Available Workers: 2
Action: Hire 1 New Worker
That is the main concept of a ReplicaSet.
Kubernetes example
ReplicaSet
|
▼
Desired: 3 Pods
|
▼
Actual: 2 Pods
|
▼
Create 1 New Pod
|
▼
Actual: 3 Pods
A ReplicaSet's job is to maintain the desired number of matching Pods.
18. How ReplicaSets and Deployments relate
In an earlier tutorial, we saw how a Deployment manages Pods through a ReplicaSet.
In modern Kubernetes, applications usually use a Deployment instead of creating a ReplicaSet directly.
Architecture
Kubernetes Deployment
|
▼
ReplicaSet
|
▼
Desired Replicas
|
+-------+-------+
| | |
▼ ▼ ▼
Pod 1 Pod 2 Pod 3
| | |
▼ ▼ ▼
App App App
A Deployment provides higher-level application management features.
For example:
- Replica management
- Rolling updates
- Rollbacks
- Scaling
A ReplicaSet mainly maintains the desired number of Pods.
That is why a Deployment is preferred for production stateless applications.
Deployment vs ReplicaSet
| Feature | ReplicaSet | Deployment |
|---|---|---|
| Maintain Pod Replicas | Yes | Through a ReplicaSet |
| Pod Replacement | Yes | Yes |
| Manual Scaling | Yes | Yes |
| Rolling Updates | Not a direct feature | Yes |
| Rollback Support | Not a direct feature | Yes |
| Recommended for Stateless Applications | Usually indirectly | Yes |
19. Complete hands-on example — ReplicaSet
Now let's look at the complete workflow for creating, checking, scaling and deleting a ReplicaSet.
Step 1: create the YAML file
File name:
replicaset-definition.yaml
YAML configuration
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs
labels:
app: myapp
type: frontend
spec:
replicas: 3
selector:
matchLabels:
app: myapp
type: frontend
template:
metadata:
labels:
app: myapp
type: frontend
spec:
containers:
- name: nginx-container
image: nginx
Step 2: create the ReplicaSet
kubectl create -f replicaset-definition.yaml
Step 3: check the ReplicaSet
kubectl get rs
Expected example:
NAME DESIRED CURRENT READY
myapp-rs 3 3 3
Step 4: check the Pods
kubectl get pods
Expected example:
NAME READY STATUS
myapp-rs-xxxxx 1/1 Running
myapp-rs-yyyyy 1/1 Running
myapp-rs-zzzzz 1/1 Running
Step 5: scale the ReplicaSet
kubectl scale --replicas=6 replicaset myapp-rs
Step 6: check the updated replica count
kubectl get rs
Then:
kubectl get pods
The ReplicaSet will now try to maintain six Pods.
Step 7: delete the ReplicaSet
kubectl delete replicaset myapp-rs
Once testing is done, the ReplicaSet and its managed Pods are removed.
20. Final takeaway — ReplicationControllers & ReplicaSets
The main goal of this tutorial was to understand how Kubernetes controllers maintain the desired number of Pods.
We learned:
ReplicationController: Kubernetes' older controller, which maintains the desired number of Pod replicas.
ReplicaSet: the newer controller, which manages matching Pods using labels and selectors.
Replicas: multiple Pod instances of the same application.
Self-healing: when a Pod is missing, the controller creates a replacement Pod.
Scaling: increasing or decreasing the desired replica count.
Selector: determines which Pods the controller manages.
Template: the blueprint for creating new Pods.
Final architecture
Kubernetes Controller
|
▼
Desired State: 3 Pods
|
▼
Check Current State
|
+------------------+
| |
▼ ▼
3 Pods 2 Pods
| |
▼ ▼
No Action Create 1 Pod
|
▼
3 Pods
The final memory rule
ReplicationController
|
▼
Older Pod Replication Controller
ReplicaSet
|
▼
Newer Pod Replication Controller
|
▼
Labels + Selectors
|
▼
Desired Pod Count
Deployment
|
▼
ReplicaSet
|
▼
Pods
|
▼
Containers
Final one-line summary:
Kubernetes ReplicationControllers and ReplicaSets are used to maintain the desired number of Pod replicas. The ReplicaSet is the more modern controller, which identifies matching Pods using labels and selectors. Real Kubernetes applications usually use a Deployment, which manages Pods through a ReplicaSet.
Official Documentation
- Kubernetes — ReplicaSet
- Kubernetes — ReplicationController
- Kubernetes — Deployments
- Kubernetes — Labels and Selectors
- kubectl scale
- kubectl apply
- kubectl create
The key point: a Kubernetes controller's job is to detect the difference between the current state and the desired state, and make the necessary changes. A ReplicaSet uses this mechanism to maintain the desired number of Pods for an application.
