Website Rollout Feature Updates Zero Downtime

If you happen to use established online applications like e.g. Gmail, or some the biggest social media or e-commerce platforms, you probably never encountered a static page asking you “Please wait while we update our application”.

Sathvika Kolisetty
6 min readJun 11, 2020

In fact, more and more services need to be always up and reachable for a variety of possible reasons:

  • If none of your competitors has any downtime then you can’t afford it either. On the contrary, if your competitors have downtime, then your application always being available is a competitive advantage.
  • Globally the user experience quality is rising, and users expect higher availability with time passing.
  • If your application has a direct impact on your revenue e.g. a point-of-sales in the form of an e-commerce app — then you are probably already aware of the business impacts that downtime can cause.

While some accidental downtime is hard to avoid completely, updating one’s application with zero downtime is actually possible. This task will help us deploy a Web Server using Distributed Jenkins where a dynamic slave will deploy the webserver on Kubernetes. I’ll show you how to do this in detail.

Problem Statement

1. Create a container image that has Linux and other basic configuration required to run Slave for Jenkins. ( example here we require kubectl to be configured )

2. When we launch the job it should automatically start the job on slave based on the label provided for a dynamic approach.

3. Create a job chain of job1 & job2 using the build pipeline plugin in Jenkins

4. Job1: Pull the Github repo automatically when some developers push the repo to Github and perform the following operations as:

4.1 Create the new image dynamically for the application and copy the application code into that corresponding docker image

4.2 Push that image to the docker hub (Public repository)

( Github code contain the application code and Dockerfile to create a new image )

5. Job2 ( Should be run on the dynamic slave of Jenkins configured with Kubernetes kubectl command): Launch the application on the top of Kubernetes cluster performing following operations:

5.1 If launching the first time then creates a deployment of the pod using the image created in the previous job. Else if deployment already exists then do a rollout of the existing pod making zero downtime for the user.

5.2 If Application created the first time, then Expose the application. Else don’t expose it.

Tools required to complete this task -

  • Git / GitHub -> Source Code Management & Version Controlling
  • Jenkins -> Automate software development related to deploying
  • Kubernetes -> container-orchestration system for automating application deployment, scaling, and management
  • Docker -> Container Engine Kubernetes will manage
  • RHEL8
  • Minnikube on MacOS

Then now firstly, We will start by setting up a GitHub repository. A Webhook is configured as well so that whenever a push is done, Job 1 build starts.When Developer changed something into GitHub then Jenkins Job-1 should be triggered automatically. For this, we have to create webhook trigger on Github so that it automatically can trigger. But we have to remember one thing, Github is belongs to the public world and my Jenkins is running into my RHEL8 which has private IP. So the Public world can’t connect to private world. But we have one way. We can create a tunnel something like this so that the public world connect to my private world. ngrok is a software that I used to expose my private IP on the internet.

Command to tunneling

./ngrok http 8080

after it starts it will show you a page which I’ve shown below

You’ll find my repository in the following link

https://github.com/satvikakolisetty/dynamicjen

Now, Go to your Repository ->Settings->WebHooks

In the Payload URL we have to put URL/GitHub-webhook/

Then select application/json in the content type

We need to allow docker daemon to be accessed remotely. Make the changes as shown below. The following changes have to made so that you can bind it with any available port. 0.0.0.0 denotes any IP that will be given to the host.

-H tcp://0.0.0.0:1234

If any changes made into the docker.service file then we have to reload the services by using the commands

systemctl daemon-reload
systemctl restart docker.service

We have to set up a docker cloud on Jenkins. Now follow these steps in order to configure the cloud.

Go to Manage Jenkins->Manage Plugins->Manage nodes and clouds

Docker Host URL is the one which we configured in docker.service file

In container settings, we have to add the mount point where the kubectl configuration files to be stored

These files have been copied from windows where my MiniKube is set up and running as a Virtual machine. And the config file has been set up accordingly.

These files are to be mounted at /root/.kube so that the configuration is setup globally.

JOB1

Now moving on to the Job1

The docker image can be found in my Docker Hub

The directory is default set to the workspace from there it will pick the docker file. If you want you can set the path of your Docker file. You can find the docker file in my GitHub Repo

JOB2

After successful build of job1 I will be doing Job 2 using a Dynamic Slave Node i.e. Kubernetes will do its work on a slave node. When job 2 will be triggered, it will ask for a slave node to be created. Then job 2 will do its work of deploying the pods as per requirement. When the job is completed it will terminate the slave node.

Dockerfile for Kubectl client and ssh

This job just creates the deployment using basic Kubernetes commands and for rolling update replaces the deployment and the pods if they already exist.

export len=$(kubectl get deployments | grep webserver | wc -l)
if [ $len -eq 0 ]
then
kubectl create deployment webserver --image=1811003010583/http_cont
kubectl scale deployment webserver --replicas=3
kubectl expose deployment webserver --port 80 --type NodePort
kubectl get svc webserver
else
kubectl rollout restart deployment/webserver
kubectl rollout status deployment/webserver
fi

Output of job1
job2 output

--

--

No responses yet