Replica Controller and ReplicaSet
Website Visitors:ReplicaController in Kubernetes
Overview
The ReplicaController (RC) is a legacy workload API object that maintains a stable set of pod replicas. It continuously monitors the current state and creates or deletes pods to match the desired replica count defined in its spec. RCs are still supported for backward compatibility but are superseded by ReplicaSets and Deployments for most use‑cases. Even if you have single pod you can still use replica controller so that the pod is redeployed if it is crashed. Replica controllers spans across multiple nodes in the configuration. If the demand increases, pods are created on other nodes. Replica Controllers is the old deprecated feature.
Core Functionality
- Desired state enforcement: The
spec.replicasfield defines the target number of identical pods. The controller reconciles the live pod count to this target. - Pod template:
spec.templatesupplies the pod specification (containers, volumes, etc.) used when spawning new pods. - Label selector:
spec.selectorselects pods belonging to the RC. Only pods whose labels match the selector are managed; mismatched pods are ignored. - Self‑healing: If a managed pod terminates unexpectedly, the RC creates a replacement pod with the same template.
Lifecycle Mechanics
- Creation: API server stores the RC object; the controller manager’s RC controller reads the spec.
- Reconciliation loop: The controller lists pods matching the selector, compares the count to
spec.replicas, and creates or deletes pods accordingly. - Scaling: Updating
spec.replicastriggers immediate creation or termination of pods to reach the new count. - Deletion: Deleting the RC removes all pods that have the RC’s selector label, unless the pods have a different owner reference.
Spec Fields (Key Elements)
| Field | Type | Description |
|---|---|---|
replicas |
integer | Desired number of pod instances. |
selector |
LabelSelector |
Mandatory; defines which pods are owned. Must be immutable after creation. |
template |
PodTemplateSpec |
Pod definition applied to newly created replicas. |
minReadySeconds |
integer | Optional; pods must be ready for this duration before being counted as available. |
revisionHistoryLimit |
integer | Ignored by RC (present for compatibility with Deployments). |
Limitations Compared to Modern Controllers
- No rolling updates: Changing
templatedoes not trigger a gradual replacement; the RC simply creates new pods with the updated template while old pods remain until manually deleted. This can cause service disruption. - Immutable selector: The selector cannot be changed after creation, restricting flexible pod adoption.
- No declarative rollout control: Features such as pause, resume, or rollback are unavailable.
- Limited adoption of orphaned pods: Existing pods that match a new selector are not automatically adopted; they must be manually re‑created or their owner reference adjusted.
Example YAML Manifest
|
|
Defining Pods and Containers in a Configuration File
The number of pods and containers is defined in the replicas and containers sections of a Deployment, ReplicaSet, or Pod configuration file.
replicas: Specifies the number of pods to run.containers: Specifies the containers that run in a pod.
Here’s an example configuration file (deployment.yaml) that defines a Deployment with 3 replicas of a pod, each containing 2 containers:
|
|
Here 3 replicas are created, ie., 3 pods are created. Two containers container1 and container2 are created. If you need more containers, you have to specify same code again and specify new name. In this above example, for creating new container called container3 you have to specify name, image, ports and containerport as shown below. If you need 10 containers, you have to add 10 containers to the containers section.
|
|
Migration to Deployment
- Export the existing RC definition.
- Create a Deployment manifest using the same pod template and selector.
- Apply the Deployment; Kubernetes will create a ReplicaSet that adopts the pods managed by the RC.
- Delete the RC after confirming the Deployment controls the pods.
|
|
Practical Guidance
- Use RC only when interacting with legacy clusters that lack the
apps/v1API group. - For any new application, define a Deployment to benefit from rolling updates, revision history, and automated pod adoption.
- Verify that the selector uniquely identifies the intended pods; overlapping selectors can cause multiple controllers to contend for the same pods, leading to undefined behavior.
ReplicaSets in Kubernetes
ReplicaSet Overview
Replica Controllers have limitations, especially in how they select Pods using labels. This led to the introduction of ReplicaSets, which are more flexible and are now the preferred approach. ReplicaSets support set-based selectors (e.g., matching multiple label conditions), making them more expressive and powerful. They serve the same fundamental purpose—maintaining a desired number of Pods—but are typically not used directly. Instead, higher-level abstractions like Deployments manage ReplicaSets and provide additional features such as rolling updates and rollbacks.
A ReplicaSet (RS) ensures that a specified number of pod replicas are running at any time. The controller continuously monitors the cluster state; if the actual replica count diverges from the desired count, the RS creates or deletes pods to reconcile the difference.
When a change is needed, and matchlabel is used in RS, existing pods that match the matchlabel are deleted and new pods are created with this new change.
There may be 100s of pods on the same node. How does replicaset know which pods to recreate when one of them fails? This is done by using labels in replicaset under selector section matchlabel value.
If we only have to monitor the deployment, and you create a replicaset for it. do we still need template section in the deployment file? Yes we need it because that template section is used to create new pod.
If we create new pods from deployment or standalone pod using the same label used in a replicaset, the new pod/pods created will be terminated automatically. This is because in the initial rs definition file, there are specific replicas defined with a label. when we create new pod using same label, it treats it as a new pod created with same label, and terminates it.
Core Fields
| Field | Description | Required |
|---|---|---|
apiVersion |
Must be apps/v1 for modern clusters. |
Yes |
kind |
Set to ReplicaSet. |
Yes |
metadata.name |
Unique identifier within the namespace. | Yes |
spec.replicas |
Desired number of pod instances. | No (defaults to 1) |
spec.selector |
Label selector that determines which pods belong to the RS. Must match spec.template.metadata.labels. |
Yes |
spec.template |
Pod template that defines containers, volumes, etc. | Yes |
Example: Basic ReplicaSet
|
|
- The selector (
app: nginx) must exactly match the pod template labels. A mismatch prevents the RS from managing its own pods, leaving them orphaned. - A ReplicaSet selector supports exactly two fields:
matchLabelsandmatchExpressions. These are part of the label selector mechanism used to determine which Pods the ReplicaSet manages.matchLabelsis the simpler form. It specifies a set of key–value pairs, and a Pod must match all of them to be selected. This is equivalent to logical AND conditions.matchExpressionsis more advanced and allows set-based selection using operators such asIn,NotIn,Exists, andDoesNotExist. This gives more flexibility compared to exact matching.
Common Pitfalls
- Selector–Template Mismatch – If
spec.selector.matchLabelsdiffers fromspec.template.metadata.labels, the RS will never adopt the pods it creates, resulting in perpetual recreation loops. - Immutable Selector – Once a RS is created, its selector cannot be changed. Modifying it requires deleting the RS (or scaling to zero) and recreating a new one.
- Direct Use vs. Deployment – Deployments wrap ReplicaSets to provide rolling updates, rollback, and declarative history. Using a RS alone bypasses these features, making version management manual.
- Pod Disruption Budgets (PDB) – A PDB applies to pods regardless of controller type, but a RS does not automatically respect a PDB during scaling events; the controller may violate the budget if not coordinated with a higher‑level controller.
Example: ReplicaSet with Rolling Update via Deployment
Although the question targets RS, demonstrating the typical pattern clarifies why direct RS usage is discouraged.
|
|
The Deployment creates an underlying RS. Updating the image field triggers the Deployment controller to create a new RS, scale it up while scaling the old RS down, and maintain the replicas count throughout.
Scaling a ReplicaSet
There are multiple ways on how we can do this. Goto the rc definition file and change the replicas value from current value to more. In this example, change it to 5. New pods are deployed to match the new value we enter there and run kubectl apply command.
Other way is to use kubectl scale command. use the resource type as rs (replicaset) and name of the deployment (nginx-rs)
|
|
The controller adds new pods to meet the new desired count.
You can also add the replica count to the definition file. Note that this wont change the value in the file.
|
|
Scaling to zero (--replicas=0) is a valid way to pause a workload without deleting the RS definition.
You can also change the configuration from already deployed file. When you run below command, it will open a file which was used to deploy the rs. Note that this is in-memory file. Any changes you make are applied immediately, just after the file is saved. In your initial file, you wont see this change.
|
|
After we make the changes with the in-memory file and you try to run the initial yaml file with different replica number, it will fail. You will get an error to match the value changed: “please apply your changes to the latest version and try again”. so you have to change the value in your yaml file as you used in the in-memory file and try again.
Deleting a ReplicaSet
|
|
By default, pod termination follows the RS’s ownerReference. The pods are garbage‑collected automatically. Adding --cascade=orphan retains the pods, which can be useful for debugging but leaves orphaned resources.
When to Use a ReplicaSet Directly
- Stateless batch jobs that require a fixed number of parallel workers without the need for rolling updates.
- Testing controller behavior where a minimal controller footprint is desired.
- Legacy clusters lacking Deployment support (pre‑v1.2). Modern clusters should prefer Deployments.
Summary of Guarantees
- Exact replica count – RS strives for the
spec.replicasvalue, not a range. - Self‑healing – Failed pods are replaced automatically.
- Label‑based ownership – Only pods matching the selector are managed; external pods with matching labels are also adopted, which can be exploited unintentionally.
Use ReplicaSets only when you need fine‑grained control over pod lifecycle without the additional abstraction of Deployments. Otherwise, Deployments provide safer, version‑aware management.
RC vs RS Differences
In Kubernetes, both Replica Controllers (RC) and ReplicaSets (RS) are workload resources used to ensure that a specified number of identical Pods are running at all times. This is a core concept for achieving high availability and fault tolerance in containerized applications (often built with Docker).
In practice, ReplicaSets are critical for modern Kubernetes applications because they enable declarative scaling and self-healing systems. For instance, when deploying a web application containerized with Docker, a Deployment creates and manages ReplicaSets to ensure zero downtime during updates. While Replica Controllers are largely deprecated, understanding them helps in grasping Kubernetes evolution. ReplicaSets, on the other hand, remain a foundational building block for scalable and resilient microservices architectures.
First, the big picture
Both ReplicaSet and ReplicationController do the same basic job:
👉 Maintain a stable number of Pods
But ReplicaSet is the next-generation, more powerful version of ReplicationController.
Key benefits of ReplicaSet over ReplicationController
1. More expressive label selectors (major upgrade)
This is the biggest difference.
🔸 ReplicationController (old)
- Only supports equality-based selectors
|
|
🔸 ReplicaSet (new)
- Supports set-based selectors
|
|
👉 This gives much more flexibility:
-
Select multiple labels
-
Use
In,NotIn,Exists, etc.
2. Better integration with Deployments
-
ReplicaSet is designed to work with Deployments
-
When you use a Deployment:
-
It automatically creates and manages ReplicaSets
-
Handles rolling updates, rollbacks, etc.
-
👉 ReplicationController does NOT integrate with Deployment
3. More future-proof (ReplicationController is legacy)
-
ReplicationController is deprecated in practice
-
ReplicaSet is part of the modern Kubernetes API (
apps/v1)
👉 In real-world usage:
- You almost never use ReplicationController anymore
4. Cleaner and more consistent API
ReplicaSet uses:
|
|
ReplicationController uses:
|
|
👉 ReplicaSet aligns with newer Kubernetes resource design
What’s NOT different?
-
Both:
-
Maintain Pod count
-
Replace failed Pods
-
Do NOT handle rolling updates themselves
-
Real-world takeaway
👉 You should:
-
Use Deployment → which uses ReplicaSet internally
-
Avoid ReplicationController entirely
One-liner
ReplicaSet replaces ReplicationController by supporting advanced label selectors and integrating with Deployments, making it more flexible and production-ready.
Your inbox needs more DevOps articles.
Subscribe to get our latest content by email.
