Computer scienceSystem administration and DevOpsKubernetes

Deployment and ReplicaSet

16 minutes read

Pods in Kubernetes can fail or terminate for various reasons, one of which can be a lack of sufficient resources on the node where they are scheduled. By default, Kubernetes does not automatically reschedule pods that fail or terminate. It is up to the cluster administrator or controllers such as Deployment or ReplicaSet to maintain a desired state in response to failures.

Controllers like ReplicaSets and Deployments are pivotal in maintaining the reliability and availability of your applications within Kubernetes. In this discussion, we'll delve into the functions of both ReplicaSets and Deployments. We'll explore their distinct roles, highlight key differences between them, and provide guidance on when to employ each one effectively.

ReplicaSets and Deployments

A ReplicaSet is a Kubernetes object designed to ensure that a specified number of pod instances are running at any given time. Replicasets play an important role in simplifying the management of pods in Kubernetes. Without replicasets, we would need to create separate pod manifests for every desired replica, and this alone would not address the challenge adequately. Kubernetes doesn't automatically reschedule pods that fail or terminate by default. Consequently, managing pods without replicasets necessitates continuous monitoring and manual efforts to recreate pods in case of failures. Using replicasets, we abstract away the manual effort of managing individual pods and let Kubernetes automatically maintain the desired number of replicas, replacing any that have stopped or failed. In this way, replicasets greatly simplify the operational aspect of maintaining a set of pods.

Replicasets provide valuable benefits in Kubernetes. ReplicaSets promote load balancing by ensuring a consistent number of replica pods. Having multiple instances of a pod available allows Kubernetes to evenly distribute traffic among those pods, often achieved through complementary Kubernetes resources like Services (which we'll explore in-depth later in this course). This approach helps prevent overloading any single pod instance. Replication enhances the reliability of your applications. With multiple pod instances, even if one container fails, others can seamlessly pick up the workload to ensure uninterrupted operation. Replicasets also simplify scalability. An application can be scaled up or down by simply adjusting the replicas field in the manifest file, offering flexibility in handling varying workloads.

A Deployment is a Kubernetes object that helps manage the lifecycle of your applications in Kubernetes. It ensures that your application runs reliably, can be easily updated, and is highly available. It provides declarative updates to pods and replicasets. You can define an application's desired state, including the number of replica pods, the container image to use, and how to update the application. The deployment controller then changes the actual state to the desired state. Deployments offer a higher-level abstraction compared to replicasets. Deployments go a step further than the replicaset as they not only provide all the benefits that a replicaset offers but also the ability to update your application in a more declarative and controlled manner. The official documentation provides a Use Case section that lists and explains the various uses of Deployments.

Creating a ReplicaSet

Let us see an example of how to define a replicaset:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myApp-replicaset
spec:
  # number of pod replicas to create
  replicas: 3

  selector:
    # This tells the replicaset to select those pods whose labels "match" to 'app: myApp'
    matchLabels:
      app: myApp

  # All the pods will be created with the following as a blueprint
  template:
    metadata:
      labels:
        # All the pods created with this template will have the label 'app: myApp'.
        # It is important to note that this label must match the label listed in the
        # 'matchLabels' subfield nested within the 'selector' field.
        app: myApp
    spec:
      containers:
        - name: myAppContainer
          image: myApp

The replicas field specifies the number of pod instances to run, the above manifest indicates that we want to run 3 replicas of the myApp container.

The template field specifies the pod template used to create new pods. Any changes made to this template result in the creation of new pods with the updated configuration. The pods that were created before the modification of the pod template are not automatically updated. They continue to run based on the original template that was in place when they were created. Kubernetes does not automatically modify running pods when you update the replicaset's template. To apply the changes to existing pods, we need to use Deployments.

The selector field specifies which pods to control. In the example above, this replicaset will control only those pods that have the label app: myApp. It is important to note that the matchLabels subfield within the selector field must match the labels subfield nested within the metadata subfield of the template field. This is how a replicaset knows which pods to monitor.

To deploy a ReplicaSet, you first have to create a YAML file. Let's call it rs.yaml, where you can copy the example manifest shown above. Once the ReplicaSet manifest is ready, you can use the kubectl command to deploy it to your Kubernetes cluster. Open your terminal and navigate to the directory where you saved the rs.yaml file. Then, run the following command:

kubectl apply -f rs.yaml

The official documentation offers advanced techniques such as scaling a replicaset, isolating pods from a replicaset, and many other in-depth explanations for working with replicasets.

Creating a Deployment

Let us see an example that shows how you can define a Deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myApp-deployment
spec:

  # number of pod replicas to create
  replicas: 3

  selector:
    # This tells the deployment to select only those pods whose labels "match" to 'app: myApp'
    matchLabels:
      app: myApp

  # Strategy type to use when updating an application in kubernetes.
  # There are two strategy types. This is an example of RollingUpdate,
  # The other type is Recreate.  
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1

  # All the pods will be created with the following as a blueprint
  template:
    metadata:
      labels:
        # All the pods created with this template will have the label 'app: myApp'.
        # It is important to note that this label must match the label listed in the
        # 'matchLabels' subfield nested within the 'selector' field.
        app: myApp
    spec:
      containers:
        - name: myAppContainer
          image: myApp

To create a Deployment, you first have to create a YAML file. Let's call it deployment.yaml where you can copy the example manifest shown above. Once the deployment manifest is ready, you can use the kubectl command to deploy it to your Kubernetes cluster. Open your terminal and navigate to the directory where you saved the deployment.yaml file and run the following command:

kubectl apply -f deployment.yaml

When a deployment is created, it creates and manages a replicaSet which in turn will create and manage exactly n number of pods with the pod template as specified by the template field. Here, n equals the number specified by the replicas field in the above manifest file. The official documentation offers an in-depth explanation of the various stages involved in the creation of a deployment.

As you have learned in a previous section, deployments provide the ability to update your application in a more declarative and controlled manner. The strategy field specifies how to carry out the update process, whenever there is a change in the pod template.

In the context of Kubernetes Deployments, Rolling Updates and Recreate are the two strategy types for managing changes to your application.

Recreate, Rolling updates, and Rollbacks

recreate strategy

Recreate is a strategy for transitioning from one version of your application to another in which all existing pods are terminated before Kubernetes creates new pods with the updated configuration. This means that there is a period of unavailability during the update, as all pods are taken down simultaneously. This strategy is less common and is typically used when downtime during updates is acceptable or when specific application requirements dictate it.

rollingupdate strategy with percentages rollingupdate strategy with integers

Rolling updates is a strategy for smoothly transitioning from one version of your application to another without causing downtime. When you make changes to the pod template in the Deployment manifest, such as updating the container image, the Deployment controller creates a new ReplicaSet with the updated configuration. It then gradually replaces the old pods managed by the previous ReplicaSet with new Pods from the new ReplicaSet, one at a time. This ensures that a certain number of pods are always available, maintaining the desired replica count throughout the update. For this strategy, you have to define additional fields, maxSurge and maxUnavailable. These fields can be defined either as integers or percentages. maxSurge subfield specifies the maximum number of additional pods that can be created beyond the replica count. The maxUnavailable subfield specifies the maximum number of pods that are unavailable (not running) at any given time during the update. In the example above, let's say replicas is equal to 5, then maxSurge = .25x5 = 1 and maxUnavailable = .25x5 = 1. To actually see how rolling update is done, you can recreate the deployment with the following command:

kubectl rollout restart deployment/myApp-deployment

The command triggers Kubernetes to initiate a rolling restart. Kubernetes gradually replaces the existing pods with new ones, one at a time, while maintaining the desired replica count, maxSurge, and maxUnavailable constraints. Now use the command below to monitor the progress of the deployment.

kubectl rollout status deployment/myApp-deployment

Rollback is a process of reverting to a previous state of your application if something goes wrong during a rolling update. If an issue is detected during a rolling update, you can instruct Kubernetes to roll back to a previous revision of the Deployment. Kubernetes will then follow a similar process to a rolling update but in reverse. It gradually replaces the new Pods with the older pods from the previous replicaset. This allows you to quickly recover from update-related problems. To initiate a rollback, use the following command:

kubectl rollout undo deployment myApp-deployment

The official documentation Updating a Deployment offers an in-depth explanation of the different strategy types discussed here.

Conclusion

In this topic, you have learned about the most common yet important Kubernetes controllers — ReplicaSets and Deployments. They are pivotal in maintaining the reliability and availability of your applications within Kubernetes.

ReplicaSets offer reliability, scalability, and load balancing. Deployments, while also offering these benefits, go further by providing the additional capability to update your application in a declarative and controlled manner.

Deployments in Kubernetes offer two update strategies: Recreate and Rolling Updates. With the Recreate strategy, all existing application pods are terminated before deploying pods with the updated application. This can result in some downtime. On the other hand, Rolling Updates allow for a smoother transition, ensuring that a specific number of pods are always available. This allows you to maintain the desired replica count throughout the update. The application does not suffer from downtime during the update process but the update process will consume extra resources such as CPU and memory.

4 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo