Now that we have a running application hooked up to a database, we will explore how to go about rolling updates (zero-downtime updates) of the application.

Series

This is Part 6 of the 9-part series:

Rolling Updates

Kubernetes has the ability to automatically perform rolling updates of your application. What this means is if your application is designed to function in a split version scenario (i.e. multiple application containers behind a load balancer, possibly running different versions of the application) you can utilize the Deployment construct of Kubernetes to automatically handle rolling updates of your application.

Let’s try this out - first, make a change to your application to indicate a difference you can detect in the version when visiting the web page. For instance, let’s update the app/__init__.py file to show a version of the application:

import os
from flask import Flask
import socket
import mysql.connector

app = Flask(__name__)

@app.route('/')
def hello():
    # construct HTML output
    html = "<h3>Hello World from {hostname}!</h3>"
    html += "<h3>Your random word is: {random_word}</h3>"
    html += "<h3>The version of this app is: {version}</h3>"

    # yes, this is a terrible way to do this, but it works/is simple
    db = mysql.connector.connect(
              host=os.getenv("MYSQL_SERVICE_HOST"),
              port=os.getenv("MYSQL_SERVICE_PORT"),
              user="root",
              passwd="Passw0rd",
              database="randomizer",
              auth_plugin="mysql_native_password"
         )

    cursor = db.cursor()
    cursor.execute("select word from random_words order by rand() limit 1;")
    res = cursor.fetchall()

    return html.format(random_word=res[0][0], version="4.0", hostname=socket.gethostname())

Now, let’s package this new version of the application as a new Docker image:

$ docker build -t randomizer:v4 .
# inspect that v3 of the docker image is available
$ docker image ls

We can now perform a rolling update. This concept previously utilized a Replication Controller as the means for deploying the new software but the recommendation has since changed to utilize the Deployment object instead. There are two main ways to accomplish this - via command-line (being explicit to change the image of the deployed application) or via the kubectl edit command, which will allow updating the Deployment YAML config file and then handling the changes for you. Since we have YAML configuration files driving our application, we will use the kubectl edit command.

First, run the kubectl edit command and update the respective parameters for the Docker image:

$ kubectl edit deployment/randomizer
# edit the .spec.template.spec.container.image
# value to reflect the new docker image
#   image: randomizer:v4
# then save/quit the file

# list the pods and you should see updates to the
# pods being made in a rolling fashion
$ kubectl get pods

# list the rollout status for the update
$ kubectl rollout status deployment/randomizer

What you’ll notice when running the last command (kubectl get pods) several times is a rolling update of the application via a “create 1/remove 1 pod” strategy. This is the default setting for the rolling update - as many things in Kuberetes, this can also be changed/refined to your liking.

Rolling Rollbacks

As a note, you can easily revert a deployment in the same fashion (rolling update). First, let’s check out the deployment history:

# information about deployment history
$ kubectl rollout history deployment/randomizer

# more detail about a specific deployment
$ kubectl rollout history deployment/nginx-deployment --revision 6

To roll back the application to the last revision previous to the current update, use the following command:

$ kubectl rollout undo deployment/randomizer

The above command performs a rolling update of the application back to the revision/version previous to the current deployment, again in a non-disruptive/non-downtime fashion. You can inspect the pods and the rollout status similarly to the previous update steps to see what is occurring. There is a major benefit to using the undo option for the rollout, which is that it is not only a quick way to revert but it also takes care of reverting the Deployment configuration file changes made as part of that update.

Next Steps

Now that we have the core functionality built for creating and deploying applications in a rolling fashion, we will switch gears in our next post to focus on the security components of storing passwords and other sensitive information in a secure manner via Kubernetes Secrets.

Credit

The above tutorial was pieced together with some information from the following sites/resources: