Discovering Deployments

Objectives

After completing this lesson, you will be able to:
  • Identify the benefits of using Deployments
  • Describe the deployment manifest
  • Choose appropriate deployment strategies
  • Learn how to use the deployment history feature
  • Understand how to scale Deployments

Introducing Deployments and their Benefits

Overview

We have already introduced Deployments as higher-level abstractions of ReplicaSets. You can use Deployments 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.

A Kubernetes architecture diagram showing a Deployment managing a ReplicaSet, which in turn manages three Pods. Each Pod contains a main Container and a Sidecar container.

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. To do this, you must 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 error-prone, manual work.

This is where Deployments come into play to automate this process. You can use Deployments to declaratively define the new desired state of your application and roll out the new version reliably, without causing any downtime of the currently running application.

Click on the buttons below to discover the main benefits of Deployments.

The Deployment Manifest

Since a Deployment manages the ReplicaSet, which, in turn, manages the Pods, the Deployment manifest is very similar to the ReplicaSet manifest. However, the Deployment manifest uses Deployment-specific fields and objects, for example, the strategy object.

Code Snippet
12345678910111213141516171819
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

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

The Deployment has three replicas and the Pod template uses the label app: hello-kyma. The Pod template has a container with the name hello-kyma and the image hello-kyma:1.0.0 pulled from the GitHub Container Registry (ghcr.io). The container exposes the port: 8080.

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

The Deployment spec section in detail

FieldDescriptionRequiredPossible values
ReplicasThe number of replicas of the application.YesInteger
SelectorThe selector to identify the Pods managed by the Deployment.YesAt least a subset of the labels defined in the Pod template.
TemplateThe Pod template used to create the Pods managed by the Deployment.YesPod labels 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's spec.template.spec field:

Code Snippet
12345678910111213
... 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

Concerning the containers object of the Pod template, the following attributes are recommended:

Recommended attributes in the containers object

FieldDescriptionRequiredPossible values
NameThe name of the container.YesString
ImageThe image of the container.YesString
ResourcesThe resources of the container.NoResource requirements
ImagePullPolicyThe image pull policy.NoAlways, IfNotPresent, Never
PortsThe container's ports.NoContainer 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 always pull the image, you can set the ImagePullPolicy to Always.

Note

If you specify an image with the latest tag and you or the system create 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.

See an example Deployment manifest:

Code Snippet
1234567891011121314151617181920212223242526272829
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: [ ] 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

For all other fields, see the Kubernetes Deployment documentation.

Advanced 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. During a roll out, new Pods incrementally replace the old Pods. Kubernetes waits for the new Pods to start before removing the old ones.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:

YAML
123456789101112131415161718192021222324
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%

For the strategy.type field, you can either specify RollingUpdate or Recreate. Since, the RollingUpdate is the default and recommended strategy, it's the focus of this lesson.

As mentioned, the RollingUpdate strategy 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. To do this, use 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 must make sure that the new version of the application is compatible with the old one. This requirement is known as API Compatibility. It's highly recommended to have a versioning concept for your APIs so that they're 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 goes wrong.

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

Code Snippet
1
kubectl rollout history deployment hello-kyma

To roll back to a previous version of your application, you can use kubectl rollout undo command:

Code Snippet
1
kubectl rollout undo deployment hello-kyma

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
1
kubectl scale deployment hello-kyma --replicas=5

Running the command updates the underlying ReplicaSet and creates two new Pods. You can verify this by using:

Code Snippet
1
kubectl get deployments hello-kyma

The output looks like this:

A table with columns: NAME, READY, UP-TO-DATE, AVAILABLE, and AGE. The row data is: hello-kyma, 5/5, 5, 5, and 18h respectively.

Summary

Deployments in Kubernetes are high-level abstractions of Pods and ReplicaSets, allowing you to declaratively define the desired state of your application. Deployments automate processes like updates and rollbacks, reducing manual work and potential errors. They support two main deployment strategies: Rolling Update for zero-downtime updates and Recreate for updates that tolerate downtime. Additionally, Deployments maintain a history of changes, allowing you to easily roll back to a previous version if needed, and can be scaled seamlessly by adjusting the number of replicas.

Further Reading about Kubernetes Deployment