The Outage Risk of Standalone Pods
If you run an application on a single pod, you are exposed to downtime. The host VM running that pod could run out of memory or crash. When this happens, your pod goes offline immediately, and your users will see errors until the Kubelet restarts the host.
Additionally, if your application experiences a sudden traffic spike, a single container can easily get overwhelmed, causing timeouts. Copying and running multiple copies of the pod specification manually is a clumsy way to handle scaling and redundancy.
Automated Scaling and Label Selection
Kubernetes addresses this using replication controllers. Over time, this evolved from the older Replication Controller to the modern ReplicaSet.
- The legacy Replication Controller ensures that a set number of pods matching a specific label are active. It uses equality-based selectors, which limit you to matching a single exact key-value pair (e.g.,
app = frontend). - The modern ReplicaSet supports set-based selectors, allowing you to match multiple values or evaluate label existence. Set-based selectors support four operators:
In: The label key must match one of the specified values (e.g.,tier in (frontend, cache)).NotIn: The label key must not match any of the specified values.Exists: The label key must be present on the resource, regardless of its value.DoesNotExist: The label key must not be present on the resource.
A ReplicaSet monitors the cluster state by querying the API Server for pods matching its selector. If it expects three pods but finds only two, it uses its embedded template to launch a replacement. If it finds four pods matching its label selector, it immediately deletes one of them to restore the target count.
Important Rule: The labels defined in your Pod template (spec.template.metadata.labels) must match the labels specified in your selector (spec.selector.matchLabels). If they do not match, the API Server will reject the configuration file when you try to apply it, because the ReplicaSet would immediately create pods that it doesn’t recognize and try to create more pods in an infinite loop.
Creating and Scaling a ReplicaSet
Let’s define a ReplicaSet and scale it. Save this configuration as nginx-replicaset.yaml:
apiVersion: apps/v1 # Note the API group!
kind: ReplicaSet
metadata:
name: my-nginx-rs
labels:
app: webserver
spec:
replicas: 3
selector:
matchExpressions:
- key: app
operator: In
values:
- nginx-app
- key: environment
operator: NotIn
values:
- production
template:
metadata:
labels:
app: nginx-app
environment: staging # Matches the selector criteria!
spec:
containers:
- name: nginx
image: nginx:1.25
Deploy the ReplicaSet:
$ kubectl apply -f nginx-replicaset.yaml
replicaset.apps/my-nginx-rs created
Check the status to verify three replicas are running:
$ kubectl get replicaset
NAME DESIRED CURRENT READY AGE
my-nginx-rs 3 3 3 15s
You can view the active pods:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-rs-8k2lh 1/1 Running 0 20s
my-nginx-rs-ml7z5 1/1 Running 0 20s
my-nginx-rs-s4v2n 1/1 Running 0 20s
To scale this ReplicaSet up to five instances, you can use one of two methods:
The Declarative Method (Recommended)
Edit the replicas: 3 field in your nginx-replicaset.yaml file to replicas: 5, then apply the changes:
$ kubectl apply -f nginx-replicaset.yaml
replicaset.apps/my-nginx-rs configured
The Imperative Method
Scale the resource directly via the CLI:
$ kubectl scale --replicas=5 replicaset/my-nginx-rs
replicaset.apps/my-nginx-rs scaled
Let’s list the pods again to confirm that five instances are active:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-rs-8k2lh 1/1 Running 0 45s
...
my-nginx-rs-df3a4 1/1 Running 0 3s
my-nginx-rs-y8b9c 1/1 Running 0 3s
ReplicaSets are highly effective for maintaining pod counts. However, in production environments, you will typically deploy your applications using Deployments, which manage ReplicaSets automatically and support rolling updates and rollbacks.

