Introduction to Kubernetes

With containerization growing in popularity and altering the process of developing, distributing, and sustaining applications, there was a need to handle these containers effectively. To manage the lifetime of these containers in large-scale systems, many container orchestration solutions have been introduced.

Provisioning and deployment, resource allocation and load distribution, service discovery, and high availability are just a few of the many functions handled by orchestration tools like Kubernetes. With this platform, we can break down our applications into smaller systems (known as microservices) during development and then compose (or orchestrate) these systems together during deployment.

The use of a cloud-native strategy has led to an increase in the development of micro-service-based applications. Deployment is a significant issue for these kinds of apps. It is critical to have a well-thought-out deployment strategy. There are several ways to release an application in Kubernetes, and you must choose the best technique to ensure the reliability of your infrastructure during the deployment or update of an application. You must constantly ensure that end-users will not be affected by any downtime in a production environment, for example. The optimal method for Kubernetes orchestration ensures the effective management of various container image versions. To summarize, the focus of this post will be on Kubernetes’ many deployment options.

What is Kubernetes Deployment?

In Kubernetes, a Deployment is a resource object that defines the desired state of our program. Deployments are declarative, which means that we do not define how the state is achieved. Rather than that, we declare the intended state and let the Deployment-controller determine the most efficient path to that state. A deployment enables us to specify the lifecycle of an application, including which images to use, the number of pods to utilize, and how they should be updated.

The Advantages of Kubernetes Deployment

Manually updating containerized programs is a time-consuming and arduous operation. A Kubernetes deployment automates and repeats this operation. The Kubernetes backend manages deployments entirely, and the entire update process occurs purely on the server-side, without client interaction.

Additionally, the Kubernetes deployment controller monitors the health of pods and nodes at all times. It can be used to replace a failing pod or to bypass down nodes, ensuring the continued operation of mission-critical applications.

Features of Kubernetes Deployment

A Deployment possesses the following characteristics:

  • Create a Replica Set and its associated Pods
  • Replica Set Update
  • Scale-up/Scale-down a Deployment
  • Continuation/Pause of a Deployment
  • Revert to a prior version
  • Eliminate unused Replica Sets

Creating a Kubernetes Deployment Strategy

We will design a Deployment that deploys a ReplicaSet and starts three instances of an Nginx Pod. To complete this experiment, you must have a working Kubernetes cluster with the kubectl command-line tool configured and linked to it. Consult the KubeOne documentation for instructions on setting up a Kubernetes cluster using KubeOne. Following this hands-on experience, it is recommended that you have a working knowledge of Pod and ReplicaSet.

Generating a Deployment is similar to creating a ReplicaSet, except that Deployment is the value of the kind property. In addition, strategy properties and values must be included in the manifest file.

Step 1: Create a my-deployment.YAML manifest file. YAML on the command line with vim

$ Vim my-deployment.YAML

Step 2: Paste the configuration below into your YAML file and save it.

—————————————————————————————————————

apiVersion: apps/v1

kind: Deployment

metadata:

  name: my-deployment

spec:

  replicas: 3

  strategy:

    type: Recreate

  selector:

    matchLabels:

      app: my-app

  template:

    metadata:

      labels:

        app: my-app

    spec:

      containers:

      – name: my-deployment-container

        image: nginx

—————————————————————————————————————-

The metadata.name field in the above configuration file defined a Deployment object named my-deployment, with Deployment as the value of its kind property.

—————————————————————————————————————-

Spec. replicas:

## the Deployment will create the number of replicated Pods specified in this field

spec.strategy.type:

## the desired strategy type is declared in this field the strategy is a child of the spec while the type is a child of the strategy and grandchild of spec

Spec.selector:

 ## this field defines how the Deployment determines which Pods to manage

Spec.containers:

 ## the container name and image are declared in this field

—————————————————————————————————————-

Note: To avoid errors, the file must be properly indented.

Step 3: To create a Deployment, run this command

—————————————————————————————————————-

$ kubectl create -f my-deployment.YAML

deployment.apps/my-deployment created

—————————————————————————————————————-

Step 4: Check the status of the deployment to see if it has been created.

—————————————————————————————————————-

$ kubectl get deployments my-deployment

NAME                    READY     UP-TO-DATE   AVAILABLE   AGE

my-deployment          0/3                0                        0           2s

—————————————————————————————————————-

If you get an output like this, it signifies the Deployment is still in the process of being generated. Wait a few seconds before rerunning the kubectl get command. This is what the output will look like after it’s finished.

—————————————————————————————————————-

$ kubectl get deployment my-deployment

NAME                      READY   UP-TO-DATE   AVAILABLE     AGE

my-deployment         3/3                    3                  3                 95s

—————————————————————————————————————-

The following is a breakdown of the status output:

—————————————————————————————————————-

Name: ## Shows the name of the Deployment as declared in the manifest file

Ready: ## This shows the number of replicas that are ready for use. In this case, all 3 out of 3 are ready for use

Up-To-Date: ## This shows the up-to-date number of replicas out of the desired number declared in the YAML file

Available: ## This shows the number of replicas that are available for use

Age: ## Shows the duration the application has been running

—————————————————————————————————————-

Step 5: Verify that the desired number of Pods is running by checking the Pod status.

—————————————————————————————————————-

$ kubectl get pods

NAME                                               READY      STATUS     RESTARTS     AGE

my-deployment-6b9b97d749-4fv5n    1/1        Running             0             3m58s

my-deployment-6b9b97d749-lscf2      1/1       Running             0             3m58s

my-deployment-6b9b97d749-p422m   1/1       Running             0             3m58s

—————————————————————————————————————-

To delete one of the Pod’s instances:

—————————————————————————————————————-

$ kubectl delete pod my-deployment-6b9b97d749-4fv5n

pod “my-deployment-6b9b97d749-4fv5n” deleted

—————————————————————————————————————-

Check to see whether it was deleted.

—————————————————————————————————————-

$kubectl get pods

NAME                                                  READY         STATUS      RESTARTS    AGE

my-deployment-6b9b97d749-lscf2        1/1           Running             0              8m3s

my-deployment-6b9b97d749-p422m     1/1           Running             0              8m3s

my-deployment-6b9b97d749-t2zmh      1/1           Running             0               54s

—————————————————————————————————————-

Three instances of Pod are currently running, while the previous ones have been destroyed or deleted. This was made feasible through ReplicaSet. One of the most critical functions of a ReplicaSet in a Deployment is to ensure that the desired instances of a Pod are always up to date and operating on the cluster. The number of running instances is determined by the value of the ReplicaSet attribute in the YAML manifest.

To view the Deployment’s description:

—————————————————————————————————————-

$ kubectl describe deployments my-deployment

Name:               my-deployment

Namespace:          default

CreationTimestamp:  Mon, 27 Jul 2020 17:22:40 +0000

Labels:             <none>

Annotations:        deployment.kubernetes.io/revision: 1

Selector:           app=my-app

Replicas:           3 desired | 3 updated | 3 total | 3 available | 0 unavailable

StrategyType:       Recreate

MinReadySeconds:    0

Pod Template:

  Labels:  app=my-app

  Containers:

   my-deployment-container:

    Image:        nginx

    Port:         <none>

    Host Port:    <none>

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

  Type              Status             Reason

  —-              ——          ——

  Available          True        MinimumReplicasAvailable

  Progressing        True       NewReplicaSetAvailable

OldReplicaSets:  <none>

NewReplicaSet:   my-deployment-97cfc859f (3/3 replicas created)

Events:

  Type       Reason                   Age          From                               Message

    —-           ——                      —-            —-                                    ——-

 Normal  ScalingReplicaSet  7m25s   deployment-controller  Scaled up replica set my-deployment-97cfc859f to 3

—————————————————————————————————————-

The next section expands on the deployment description:

—————————————————————————————————————-

Name ## The name of the Deployment as specified in the manifest file.

Namespace: ## It is always a default if no namespace is specified in the manifest file.

Replicaset: ## The desired number of replicas specified in the manifest file.

Strategy.recreate ## The strategy to be used for the Deployment. You can find more info on Deployment strategy in the next part of this series.

Containers.image: ## This field specifies the container and container image names.

Events: ## Shows the Deployment activities since it was created.

—————————————————————————————————————-

Kubernetes Deployment Update

You can update a Deployment by changing the container image from one version to another, adjusting the ReplicaSet value to decrease or increase the number of instances, and so on. For example, the Nginx container image we’ve been utilizing in our exercises comes in a variety of flavors. The newest version will be pulled from the image repository if no version is given in the manifest YAML file. As an example, we’ll update the current image version to a different one.

There are two ways to update deployment to use a fresh image:

Method 1: Using the kubectl command-line tool, you can give the updated image tag straight to the Deployment. We’ll update our manifest file’s Nginx to utilize the nginx:1.18.0 version.

—————————————————————————————————————

kubectl –record deployment.apps/my-deployment set image deployment.v1.apps/my-deployment my-deployment-container=nginx:1.18.0

deployment.apps/my-deployment image updated

or

$kubectl set image deployment/my-deployment my-deployment-container=nginx:1.18.0 –record

deployment.apps/my-deployment image updated

—————————————————————————————————————-

The name of the Deployment is my-deployment, and the name of the container is my-deployment-container, as defined in the YAML file. Examine the description once more and compare it to the original setup.

—————————————————————————————————————-

$kubectl describe deployment my-deployment

Name:               my-deployment

Namespace:          default

CreationTimestamp:  Mon, 27 Jul 2020 17:22:40 +0000

Labels:             <none>

Annotations:        deployment.kubernetes.io/revision: 2

                    kubernetes.io/change-cause:

                    kubectl deployment.apps/my-deployment set image deployment.v1.apps/my-deployment          my-deployment-container=nginx:1.18.0 –record=true

Selector:           app=my-app

Replicas:           3 desired | 3 updated | 3 total | 3 available | 0 unavailable

StrategyType:       Recreate

MinReadySeconds:    0

Pod Template:

  Labels:  app=my-app

  Containers:

   my-deployment-container:

    Image:        nginx:1.18.0

    Port:         <none>

    Host Port:    <none>

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

TypeStatusReason
 AvailableTrueMinimumReplicasAvailable
ProgressingTrueNewReplicaSetAvailable  

OldReplicaSets:  <none>

NewReplicaSet:   my-deployment-79f645dc59 (3/3 replicas created)

Events:

TypeReasonAgeFromMessage
NormalScalingReplicaSet  12mdeployment-controller  Scaled up replica set my-deployment-97cfc859f to 3  
NormalScalingReplicaSet  32sdeployment-controller  Scaled down replica set my-deployment-97cfc859f to 0  
NormalScalingReplicaSet  23sdeployment-controllerScaled up replica set my-deployment-97cfc859f to 3  

—————————————————————————————————————-

We adjusted the image version from Nginx to nginx:1.18.0 as indicated in the Pod template by comparing the description outputs of the original and modified versions. In addition, compared to before the update, there are more events outlining the rolling update’s internal procedures. The Deployment updated the Pods by generating and scaling a new ReplicaSet of three replicas and destroying the old one, as shown above. For more information, look at the ReplicaSet status.

—————————————————————————————————————

$kubectl get replicaset

NAME                                     DESIRED   CURRENT   READY    AGE

my-deployment-79f645dc59     3                    3                   3      76s

my-deployment-97cfc859f        0                    0                   0      4m53s

—————————————————————————————————————-

Method 2: Editing the manifest YAML file directly. Alternatively, you can execute the following command to modify the Deployment YAML file and update the current image version from nginx:1.18.0 to nginx:1.19.1, then save and quit the terminal:

—————————————————————————————————————-

$kubectl edit deployment.v1.apps/my-deployment

deployment.apps/my-deployment edited

—————————————————————————————————————-

We still have three deployments ready, as you can see from the Deployment Status page.

—————————————————————————————————————-

$kubectl get deployment my-deployment

NAME                        READY    UP-TO-DATE   AVAILABLE    AGE

my-deployment              3/3              3                       3             29m

—————————————————————————————————————-

To see if the image has been updated, look at the Deployment’s description.

—————————————————————————————————————-

$kubectl describe deployment my-deployment

Name:               my-deployment

Namespace:          default

CreationTimestamp:  Mon, 27 Jul 2020 18:18:58 +0000

Labels:             <none>

Annotations:        deployment.kubernetes.io/revision: 3

                    kubernetes.io/change-cause: kubectl set image deployment/my-deployment my-deployment-container=nginx:1.18.0 –record=true

Selector:           app=my-app

Replicas:           3 desired | 3 updated | 3 total | 3 available | 0 unavailable

StrategyType:       Recreate

MinReadySeconds:    0

Pod Template:

  Labels:  app=my-app

  Containers:

   my-deployment-container:

    Image:        nginx:1.19.1

    Port:         <none>

    Host Port:    <none>

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

TypeStatusReason
 AvailableTrueMinimumReplicasAvailable
ProgressingTrueNewReplicaSetAvailable  

OldReplicaSets:  <none>

NewReplicaSet:   my-deployment-5997f87f5f (3/3 replicas created)

Events:

TypeReasonAgeFromMessage
NormalScalingReplicaSet  30mdeployment-controller  Scaled up replica set my-deployment-97cfc859f to 3  
NormalScalingReplicaSet  27mdeployment-controller  Scaled down replica set my-deployment-97cfc859f to 0  
NormalScalingReplicaSet  27mdeployment-controllerScaled up replica set my-deployment-97cfc859f to 3  
NormalScalingReplicaSet  2m39sdeployment-controller  Scaled down replica set my-deployment-97cfc859f to 0  
NormalScalingReplicaSet  2m31sdeployment-controllerScaled up replica set my-deployment-97cfc859f to 3  

—————————————————————————————————————-

Finally, we started a new Deployment and scaled it up to 3 replicas, while the old one was scaled down to 0. Check the state of the ReplicaSet:

—————————————————————————————————————-

$ kubectl get replicaset

NAME                                         DESIRED    CURRENT     READY     AGE

my-deployment-5997f87f5f            3                  3                  3             72s

my-deployment-79f645dc59          0                  0                  0            25m

my-deployment-97cfc859f             0                  0                  0            29m

—————————————————————————————————————-

Clean-up: Using the kubectl delete command, delete the Deployment.