ReplicaSets: The Key to Resilient and High Availability Applications in Kubernetes
ReplicaSet is a Kubernetes object that ensures that a specified number of replicas of a pod are running at any given time.
A pod is the smallest unit of deployment in Kubernetes, and it usually contains one or more containers that share the same network and storage resources.
A ReplicaSet manages the lifecycle of pods and provides a way to scale and maintain the desired state of the application.
A ReplicaSet is defined with fields, including:
- selector that specifies how to identify pods it can acquire
- number of replicas indicating how many pods it should be maintaining
- pod template specifying the data of new pods it should create to meet the number of replicas criteria
Why use ReplicaSet?
A ReplicaSet ensures that a specified number of pod replicas are running at any given time. This is useful for ensuring the availability and scalability of the application. For example, if one pod fails due to an error or node failure, the ReplicaSet will create a new one to maintain the desired state. Similarly, if there is an increase in demand for the application, the ReplicaSet can scale up by creating more pods.
However, a ReplicaSet does not provide any mechanism for updating or rolling back the application. For example, if we want to deploy a new version of our application, we cannot simply change the pod template in the ReplicaSet. This will not trigger any update or create any new pods. Instead, we have to manually delete or modify the existing pods to match the new template.
This is where Deployments come in handy. A Deployment is a higher-level concept that manages ReplicaSets and provides declarative updates to pods along with a lot of other useful features.
Therefore, use Deployments instead of directly using ReplicaSets, unless you require custom update orchestration or don’t require updates at all.
How do ReplicaSet work and Manage Pods?
A ReplicaSet works by constantly monitoring the state of the pods it controls and comparing it with the desired state specified in its spec. If there is any discrepancy between the current and desired state, it will take action to reconcile them.
For example, if one of the pods fails or is deleted, the ReplicaSet will create a new one to replace it. Conversely, if there are more pods than specified in the spec, the ReplicaSet will delete some of them to maintain the desired number.
A ReplicaSet is linked to its pods via the pods’ metadata.ownerReferences
field, which specifies what resource the current object is owned by. All pods acquired by a ReplicaSet have their owning ReplicaSet’s identifying information within their ownerReferences field. It’s through this link that the ReplicaSet knows of the state of the pods it is maintaining and plans accordingly.
A ReplicaSet identifies new pods to acquire by using its selector. If there is a pod that has no OwnerReference
or the OwnerReference
is not a Controller and it matches a ReplicaSet’s selector, it will be immediately acquired by said ReplicaSet.
An OwnerReference is a field in the pod’s metadata that specifies what resource owns the current object. All pods acquired by a ReplicaSet have their owning ReplicaSet’s identifying information within their OwnerReference
field. It is through this link that the ReplicaSet knows of the state of the pods it is maintaining and plans accordingly.
ReplicaSet in Action
Create ReplicaSet
To create a ReplicaSet, you need to define a YAML
file that specifies the following fields:
apiVersion
: API version of the Kubernetes object. For ReplicaSets, it is apps/v1kind
: kind of the Kubernetes object. For ReplicaSets, it is ReplicaSetmetadata
: metadata of the Kubernetes object, such as name and labelsspec
: specification of the Kubernetes object, such as replicas, selector, and templatespec.replicas
: number of replicas of the pod that you want to runspec.selector
: selector that matches the pods controlled by the ReplicaSet. It can be based on labels or expressionsspec.template
: template that defines the pod configuration that the ReplicaSet will create
Here is an example YAML
file for a ReplicaSet
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-replicaset
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: myapp:latest
ports:
- containerPort: 80
To create the ReplicaSet from the YAML file, you can use the kubectl apply
command
kubectl apply -f myapp-replicaset.yaml
This will create a ReplicaSet named myapp-replicaset
that will manage three replicas of the pod with the label app:myapp
. Each pod will run a container named myapp-container
with the image myapp:latest
and expose port 80
.
Scaling and Auto-scaling ReplicaSet
There are a few simple ways to alter the number of pods managed by a specific ReplicaSet
- Modify the controller’s configuration using
kubectl edit rs ReplicaSet_name
and adjust the replicas count to your desired value - Modify the
YAML
file and apply the changes usingkubectl apply -f myapp-replicaset.yaml
- Use
kubectl
directly, for example,kubectl scale --replicas=2 rs/ReplicaSet_name
. This command scales down the ReplicaSet from 3 to 2. The ReplicaSet will remove 1 pod to maintain the desired count - You can also use the Horizontal Pod Autoscaler (HPA) with the ReplicaSet to increase the number of pods when the CPU load gets higher. When the load decreases, it cannot have fewer than the number of pods specified before in
YAML
file by running commandkubectl autoscale rs myapp-replicaset --max=5
Delete ReplicaSet
There are a few ways to delete ReplicaSet
- using
kubectl delete
command likekubectl delete rs myapp-replicaset
- remove the file and all the resources defined in it with
kubectl delete -f myapp-replicaset.yaml
. This will delete the ReplicaSet and all the pods that it manages. There may be instances where you would like to delete the ReplicaSet resource while keeping the pods unowned, or orphaned. This could be because you want to manually delete the pods and prevent the ReplicaSet from restarting them. To achieve this, you can use the following commandkubectl delete rs myapp-replicaset — cascade=false
. After running the commandkubectl get rs
, you should see that there are no ReplicaSets present. However, if you run the commandkubectl get pods
, all the pods that were previously managed by the deleted ReplicaSet should still be running. To have these pods managed by a ReplicaSet again, you must create a new ReplicaSet with the same selector and pod template as the previous one.
Best Practices
Conclusion
ReplicaSets are a fundamental concept in Kubernetes that enable you to run multiple replicas of your pods and ensure their availability and scalability. However, they also require some careful planning and configuration to use them effectively.