Deployments

A deployment is a declarative way to manage the state of pods and replicas.

Module

A Deployment controller provides declarative updates for Pods and ReplicaSets.

Overview

At the end of this module, you will :

  • Learn the format of a YAML Deployment file

  • Learn how to manage a Deployment

  • Learn how to manage the lifecycle of an application

Prerequisites

Create the directory data/deployment in your home folder to manage the YAML file needed in this module.

mkdir ~/data/deployment

Create

A Deployment controller provides declarative updates for Pods and ReplicaSets.

Describe a desired state in a Deployment object, and the Deployment controller changes the actual state to the desired state at a controlled rate. A Deployment object can create, update or delete resources or parameters.

The create command can directly ask the API resource to create a Deployment in command line or create a Deployment object based on a yaml file definition.

Exercise n°1

Create a Deployment object in command line named mynginxdeploymentcli to deploy an Nginx Pod.

kubectl create deployment mynginxdeploymentcli --image=nginx

Exercise n°2

Deploy an Nginx Pod in a declarative way with a Deployment object. The ReplicaSet associated has to manage 3 replicas of the Pod. The rolling update strategy will be the default update strategy for this Deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mynginxdeploymentyaml
  labels:
    app: mynginxdeploymentyaml
spec:
  replicas: 3
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  selector:
    matchLabels:
      app: mynginxdeploymentyaml
  template:
    metadata:
      labels:
        app: mynginxdeploymentyaml
    spec:
      containers:
      - name: nginx
        image: nginx
kubectl apply  -f data/deployment/01_deployment.yaml

Exercise n°3

Deploy a PostgreSQL database in a declarative way with a Deployment object. The ReplicaSet associated has to manage one replica of the Pod. The recreate strategy will be the default update strategy for this Deployment.

PostgreSQL need three environment variables to start correctly :

  • POSTGRES_DB : the database name to be created at the Pod creation

  • POSTGRES_USER : the username owner of the default database

  • POSTGRES_PASSWORD : the password of the newly created user

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - env:
            - name: POSTGRESQL_DATABASE
              value: "postgresdb"
            - name: POSTGRES_USER
              value: "postgresadmin"
            - name: POSTGRES_PASSWORD
              value: "admin123"
          image: postgres:10.4
          imagePullPolicy: "IfNotPresent"
          name: postgres
          ports:
            - containerPort: 5432
kubectl apply  -f data/deployment/02_deployment.yaml

Get

The get command list the object asked. It could be a single object or a list of multiple objects comma separated. This command is useful to get the status of each object. The output can be formatted to only display some information based on some json search or external tools like tr, sort, uniq.

The default output display some useful information about each services :

  • Name : the name of the newly created resource

  • Desired : the number of desired running Pods, similar to a ReplicaSet output

  • Current : the number of current running Pods, similar to a ReplicaSet output

  • Up-to-date : the number of up to date Pods when a Deployment is updated

  • Available : the number of production ready Pods, similar to a ReplicaSet output

  • Age : the age since his creation

Exercise n°1

Get a list of the existing deployment object in the default namespace.

kubectl get deployment

Describe

Once an object is running, it is inevitably a need to debug problems or check the configuration deployed.

The describe command display a lot of configuration information about the Deployment(s) (labels, resource requirements, etc.) or any other Kubernetes objects, as well as status information about the Deployment(s) and Pod (state, readiness, restart count, events, etc.).

This command is really useful to introspect and debug an object deployed in a cluster.

Exercise n°1

Describe a deployment in the default namespace.

kubectl describe deployment mynginxdeploymentcli

Explain

Kubernetes come with a lot of documentation about his objects and the available options in each one. Those information can be fin easily in command line or in the official Kubernetes documentation.

The explain command allows to directly ask the API resource via the command line tools to display information about each Kubernetes objects and their architecture.

Exercise n°1

Get the documentation of a specific field of a resource.

kubectl explain deployment.spec

Add the --recursive flag to display all of the fields at once without descriptions.

Update

Users expect applications to be available all the time and developers are expected to deploy new versions of them several times a day. In Kubernetes this is done with rolling updates. Rolling updates allow Deployments' update to take place with zero downtime by incrementally updating Pods instances with new ones. The new Pods will be scheduled on Nodes with available resources.

Similar to application Scaling, if a Deployment is exposed publicly, the Service will load-balance the traffic only to available Pods during the update. An available Pod is an instance that is available to the users of the application.

Rolling updates

The updates can be done based on the yaml file update or in command line depending on the kind of update needed. Remember, the command line modification are temporary and can be overwritten by an automated lifecycle manage like a Continuous Deployment tool. In production, it is highly recommended to versioned the yaml file in a git repository and ensure that each modification are tested on multiple environment before the production deployment.

The Kubernetes basic Rolling Updates architecture can be schematized like this :

The rollout command allows to directly ask the API resource via the command line tools to manage the life cycle of a Deployment like displaying the older release with the history parameter.

The rolling update method does not apply only to the Deployment object but to the DaemonSet and the StatefulSet too.

Exercise n°1

  1. Check the history of the previous Nginx deployment

  2. Describe the deployment to note the current version

  3. In command line, update the Nginx version to the 1.9.1 in the previous deployment

  4. Describe the deployment to ensure the version has changed

  5. Check the history of the deployment to note the new entry

kubectl rollout history deployment mynginxdeploymentyaml
kubectl get deployment mynginxdeploymentyaml -o=jsonpath='{$.spec.template.spec.containers[:1].image}'
kubectl set image deployment/mynginxdeploymentyaml nginx=nginx:1.9.1
kubectl get deployment mynginxdeploymentyaml -o=jsonpath='{$.spec.template.spec.containers[:1].image}'
kubectl rollout history deployment mynginxdeploymentyaml

Exercise n°2

Do the same operation to update Nginx in the 1.12.3 version but with a yaml file and add the --record parameter to the command. Get the deployment history to understand the difference between an update with or without the --record parameter.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mynginxdeploymentyaml
  labels:
    app: mynginxdeploymentyaml
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mynginxdeploymentyaml
  template:
    metadata:
      labels:
        app: mynginxdeploymentyaml
    spec:
      containers:
      - name: nginx
        image: nginx:1.19

Update the Deployment in command line.

kubectl apply -f ~/data/deployment/03_deployment.yaml --record
kubectl rollout history deployment mynginxdeploymentyaml

Rollback

In a Kubernetes cluster, a Rollback mean scaling up the corresponding ReplicaSet and scaled down the current one.

This can be done easily in command line by specifying the revision to rollback the deployment.

The rollout command allows to directly ask the API resource via the command line tools to manage the life cycle of a Deployment like revert to an older version with the undo parameter.

The rolling update method does not apply only to the Deployment object but to the DaemonSet and the StatefulSet too.

Exercise n°1

Rollback the Nginx deployment to the previous revision and check that the version of Nginx is back to 1.9.1.

kubectl rollout undo deployment mynginxdeploymentyaml --to-revision=2

Delete

The delete command delete resources by filenames, stdin, resources and names, or by resources and label selector.

Deleting a Deployment will automatically delete each resources associated like Pods and ReplicaSet.

Note that the delete command does NOT do resource version checks, so if someone submits an update to a resource right when you submit a delete, their update will be lost along with the rest of the resource.

Exercise n°1

Delete the previous deployment in command line.

kubectl delete deployment mynginxdeploymentcli mynginxdeploymentyaml postgres

Module exercise

The purpose of this section is to manage each steps of the lifecycle of an application to better understand each concepts of the Kubernetes course.

The main objective in this module is to understand how to manage deployment object and their relation with Pods and ReplicaSet.

For more information about the application used all along the course, please refer to the Exercise App > Voting App link in the left panel.

Based on the principles explain in this module, try by your own to handle this steps. The development of a yaml file is recommended.

The file developed has to be stored in this directory : ~/data/votingapp/03_deployments

  1. Delete the ReplicaSet deployed in the previous module exercise

  2. Develop the Deployment yaml file to deploy the Voting App microservices.

  3. Update the vote Deployment to attach two environment variables :

    1. Name the first OPTION_A, her value has to be CATS

    2. Name the second OPTION_B, her value has to be DOGS

  4. Update the db, result and worker Deployment to attach three environment variables :

    1. Name the first POSTGRES_NAME, her value has to be "voting"

    2. Name the second POSTGRES_USER, her value has to be "voting"

    3. Name the third POSTGRES_PASSWORD, her value has to be "password"

  5. Ensure each Pods are up and running

External documentation

Those documentations can help you to go further in this topic :

Last updated