Discovering Deployments

Objectives
After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Identify the benefits of using deployments
  • Describe the deployment manifest
  • Apply appropriate deployment strategies depending on the application downtime
  • Use the deployment history feature to check or roll back on previous version of the application
  • Understand scale deployments

Deployments, Overview, and Benefits

Introduction

You have heard of deployments as a high-level abstraction of Pods and ReplicaSets. Now, you want to learn more about deployments and how to use them to manage your applications.

Overview

We have already introduced deployments as higher-level abstractions of ReplicaSets. Deployments can be used to define the desired state of your application declaratively. This includes the number of replicas, the container images, and further configuration. Deployments manage ReplicaSets, and ReplicaSets manage Pods.

Benefits of Deployments

Consider the following scenario:

You have manually created a pod for an application with version 1.0.0. After some time, you want to update the application to version 1.0.1. You would have to create a new pod based on the new image, update the service to point to the new pod, and delete the old pod. This is a lot of manual work and is error-prone. Deployments can be used to automate this process.

This is where deployments come into play. Deployments can be used to declaratively define the new desired state of your application to roll out the new version reliably and with zero downtime of the currently running application.

Click on the four buttons below to discover the main benefits of deployments.

The Deployment Manifest

Since a deployment manages the ReplicaSet, which is, in turn, managing the Pods, the deployment manifest is very similar to the ReplicaSet manifest. The only difference is that the deployment manifest has deployment-specific fields and objects, for example, the strategyobject.

Code snippet
apiVersion: apps/v1
kind: Deployment
metadata:
   name: hello-kyma
spec:
   replicas: 3
   selector:
     matchLabels:
       app: hello-kyma
   template: # Pod template
     metadata:
       labels:
         app: hello-kyma
     spec:
       containers:
         - name: hello-kyma
           image: ghcr.io/sap-samples/kyma-runtime-learning-journey/hello-kyma:1.0.0
           ports:
           - containerPort: 8080
Copy code

This example shows a deployment manifest with the name hello-kyma.

The deployment has three replicas and the pod template has the labelapp: hello-kyma. The pod template has a container with the namehello-kymaand the image hello-kyma:1.0.0 from the GitHub Container Registry (ghcr.io). The container exposes the port: 8080

Let's have a look at the deployment manifest spec section in detail:.

The deployment spec section in detail

FieldDescriptionRequiredPossible values
replicasThe number of replicas of the applicationYesInteger
selectorThe selector to identify the pods managed by the deploymentYesAt least a subset of the labels defined in the pod template
templateThe template used to create the pods managed by the deploymentYesLabels and pod manifest

If you want to pull the image from a private registry, you can do so by providing the credentials in the deployment manifest to spec.template.spec:

Code snippet
...
spec:
...
  template:
  ... 
    spec:
      imagePullSecrets:
        - name: myregistrykey
      containers:
        - name: hello-kyma
          image: ghcr.io/sap-samples/kyma-runtime-learning-journey/hello-kyma:1.0.0
          ports:
            - containerPort: 8080
Copy code

We cover secrets later in this course.

Concerning the containers object in the manifest, the following attributes are recommended:

Recommended attributes in the containers object

FieldDescriptionRequiredPossible values
nameThe name of the containerYesString
imageThe image of the containerYesString
resourcesThe resources of the containerNoResource requirements
ImagePullPolicyThe image pull policyNoAlways, IfNotPresent, Never
portsThe ports of the containerNoContainer ports

The ImagePullPolicy is set to IfNotPresent by default. This means that the image is pulled only if it is not present locally on the cluster node. If you want to pull the image always, you can set the ImagePullPolicy to Always.

Note
If you specify an image with the latest tag and you or the system creates a new pod, Kubernetes always downloads the most recent latest version. This can lead to unexpected behavior, since other pods can still use the old image. Therefore, it is recommended to use a specific version of the image, for example, 'hello-kyma:1.0.0'.

So, a good manifest might look like this:

Code snippet
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kyma
  labels:
    app.kubernetes.io/name: hello-kyma
spec:
   replicas: 3
   selector:
     matchLabels:
       app: hello-kyma
   template:
     metadata:
       labels:
         app: hello-kyma
     spec:
        imagePullSecrets: [ ] # optional
        containers:
         - name: hello-kyma
           image: 'ghcr.io/sap-samples/kyma-runtime-learning-journey/hello-kyma:1.0.0'
           resources:
            requests:
              memory: 64Mi # 64MiB (2^26 bytes)
              cpu: 50m # 50 millicores (1/20th of a core), 500m = 0.5 cores
            limits:
              memory: 128Mi
              cpu: 100m # 100 millicores (1/10th of a core), 1000m = 1 core
           ports:
           - containerPort: 8080
Copy code

For all other fields, please refer to the official documentation.

Advanced Deployment Strategies

The Kubernetes deployment object also comes with different deployment strategies. Kubernetes supports the following two deployment strategies:

Supported deployment strategies

StrategyExplanationComment
Rolling UpdateThe default strategy. The new version of the application is rolled out in a rolling fashion.When you want to update your application without downtime.
RecreateThe new version of the application is rolled out by first deleting all pods of the current version and then creating the pods of the new version.When you want or can update your application with downtime.

You can specify the deployment strategy in the deployment manifest:

Code snippet
apiVersion: apps/v1
kind: Deployment
metadata:
   name: hello-kyma
spec:
   replicas: 3
   selector:
     matchLabels:
       app: hello-kyma
   template:
     metadata:
       labels:
         app: hello-kyma
     spec: 
        containers:
         - name: hello-kyma
           image: ghcr.io/sap-samples/kyma-runtime-learning-journey/hello-kyma:1.0.0
           ports:
           - containerPort: 8080 
     strategy:
       type: RollingUpdate
       rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
Copy code

For the strategy.type field, you can either specify RollingUpdate or Recreate. Since, the `RollingUpdate' is the default and recommended strategy, we will focus on this one.

As mentioned, the RollingUpdate doesn't delete the old pods before creating the new ones. Instead, it performs the update in a rolling fashion. You can define exactly the percentage of pods that can be updated at the same time. This is done by the maxSurge and maxUnavailable fields:

  • The maxSurge field defines the maximum number of pods that can be created above the desired number of pods.
  • The maxUnavailable field defines the maximum number of pods that can be unavailable during the update.

The default values for both fields are 25%. With this, the old pods still retrieve traffic, while you are already creating and serving the new pods.

Note

Serving two versions of an application simultaneously, behind the same service, also comes with some challenges. For example, you have to make sure that the new version of the application is compatible with the old one, also known as API Compatibility. It is highly recommended to have a versioning concept for your APIs to be both forward and backward compatible.

Deployment History

Each deployment also contains an entire deployment history. This allows you to roll back to a previous version of your application if something went wrong.

You can use kubectl to check the deployment history of a deployment:

Code snippet
kubectl rollout history deployment hello-kyma
Copy code

You can simply roll back to a previous version of your application by using the kubectl rollout undo command:

Code snippet
kubectl rollout undo deployment hello-kyma
Copy code

Scaling Deployments

You can scale your deployment by simply updating the replicas field in the deployment manifest. Likewise, you can also use kubectl to scale your deployment:

Code snippet
kubectl scale deployment hello-kyma --replicas=5
Copy code

This will update the underlying ReplicaSet and create two new pods. You can verify this by using:

Code snippet
kubectl get deployments hello-kyma
Copy code

The output should look like this:

Summary

This lesson taught you how to deploy your application to Kubernetes based on a Deployment manifest. You also learned about the different deployment strategies and how to scale your deployment and roll it back.

Further Reading about Kubernetes Deployment

Read more about Kubernetes Deployment here: Kubernetes Deployment

Log in to track your progress & complete quizzes