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”.
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.
This job just creates the deployment using basic Kubernetes commands and for rolling update replaces the deployment and the pods if they already exist.