# Create, View and Destroy a Deployment

In 
Published 2022-12-03

This tutorial explains to you how to create, view and destroy a Deployment in a Kubernetes cluster.

# Deployments - explanation

Replica set keeps the number of pods and performs load balancing, but is not able to change the image used for creating the containers. This is done by deployment object in Kubernetes.

A Deployment is a layer of abstraction over Replica Set. A Deployment could change, in addition to Replica Set, the image on which the containers are created. This feature let us deploy a new version of the container/application. We can also rollback a deployment.

The deployment, as any other K8s object has 3 parts:

  • the metadata : identifies the pods for that deployment
  • specification : how to create the objects (configuration we want to apply)
  • status : what we have (generated and added by Kubernetes)

When a deployment is created a Replica Set is created automatically and is managed by the deployment.

There are multiple strategies for deploying your application to your Kubernetes cluster:

  • RollingUpdate (default strategy) : New pods are brought online, and traffic is directed to them to ensure they are working as expected before old pods are removed.

This type of deployment can be fine-tuned by two more options:

  • maxSurge: The number of pods that can be created above the desired amount of pods during an update
  • maxUnavailable: The number of pods that can be unavailable during the update process

Example of defining Rolling Updates in deployment yaml file:

spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2        # how many pods we can add at a time
      maxUnavailable: 0  # how many pods can be unavailable during the rolling update

maxSurge: The number of pods that can be created above the desired amount of pods during an update maxUnavailable: The number of pods that can be unavailable during the update process

  • Recreate : Kills the currently running pod instances and creates other instances running the new version.

Example of defining Recreate in deployment yaml file:

spec:
  replicas: 3
  strategy:
    type: Recreate

We can use also various tools in order to implement other deployment types:

  • Blue/Green Deployment : new pods are deployed alongside the existing pods. The new pods are tested before redirecting traffic to them. This strategy requires double the resources for a period of time. On all looks good, the blue (old) pods/replica set are/is removed from Kubernetes.

Blue deployment = the old version Green deployment = the new version

  • Canary Deployment : Both old and new version are running simultaneous for a period of time. A small number of users are routed to the new version of the application. If an error occurs, the damage is limited, and the change can be rolled back. If there are no major issues and all looks ok with the new version, the canary (new) version is expanded to more users, until it completely replaces the old version.

  • A/B Testing Deployment : is usually used to see the users' response (for instance, how much they like a new feature), when we know that the new version works.

# Create a Deployment in a Kubernetes cluster

In order to create a Deployment, we need to create a file as my-first-deployment.yml which describes the Deployment object we want to create:

my-first-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-first-deploy
spec:
  replicas: 4
  selector:
    matchLabels:
      app: app1
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - name: app1-pod
        image: nginx:1.14.2
        ports:
        - containerPort: 8080

The following command will create a new Deployment:

kubectl apply -f my-first-deployment.yml

# View Deployment information

We can run the following command to see the result:

kubectl get deployments

NAME              READY   UP-TO-DATE   AVAILABLE   AGE
my-first-deploy   4/4     4            4           73s

Get more information on a specific Deployment:

kubectl describe deployment my-first-deploy

In my case the result is:

Name:                   my-first-deploy
Namespace:              default
CreationTimestamp:      Tue, 31 Jan 2023 22:30:13 +0200
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=app1
Replicas:               4 desired | 4 updated | 4 total | 4 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        10
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=app1
  Containers:
   app1-pod:
    Image:        nginx:1.14.2
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   my-first-deploy-6b7d8bbcfb (4/4 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m47s  deployment-controller  Scaled up replica set my-first-deploy-6b7d8bbcfb to 4

# Roll a new Deployment in a Kubernetes cluster

Consider we upgraded the image version of the container we have used:

my-first-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-first-deploy
spec:
  replicas: 4
  selector:
    matchLabels:
      app: app1
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - name: app1-pod
        image: nginx:1.16.1
        ports:
        - containerPort: 8080

The following command will update the image of the "old" Deployment:

kubectl apply -f my-first-deployment.yml

The following command will tell us the status of the rollout :

kubectl rollout status deployment/my-first-deploy

# Destroy a Deployment in a Kubernetes cluster

Delete the Deployment created above:

kubectl delete deployment my-first-deploy