Web-Server With Live Rolling Updates Using Dynamic Jenkins Slave Node and Kubernetes
The main motive of this article is to solve real-world problems. Can you imagine the loss of Instagram, not only loss but also hate of a million users it receives if it is even down by a few seconds, so nobody would want that, right?
It can be solved by using automatic rollout of updates using Kubernetes and managing the build triggers by Jenkins.
So let us get going, on how to solve this major issue in this easy way.
Our system requirements:
- 2 RHEL 8 VM’s (1 as docker server with Jenkins configured and the other as docker client)
- Jenkins(it should be updated as some plugins might not work with the outdated version)should have the following plugins installed
1. Build Pipeline Plugin
2. Docker Plugin
3.GitHub Plugin
- We need to create a Dockerfile with kubectl configured so that this image will run as a slave for Jenkins as well as SSH configured
- Minikube configured and it is running( to start do minikube start )
First of all, we need to set up socket binding so as to allow the docker services of this VM to be used by others also. For this, we need to enable TCP support also. This is done by adding -H tcp://0.0.0.0:1234 in /usr/lib/systemd/system/docker.service file in the docker server.
vim /usr/lib/systemd/system/docker.service
Now restart your docker services using:
systemctl daemon-reload
systemctl restart docker
Now, a container image is created that has Linux and other basic configuration required to run Slave for Jenkins.
Step by step explanation of the Dockerfile are:
- Use centos as the BaseOS
- Install java
- Install ssh
- Install sudo command so as there are no issues in permissions
- Set both the password and username as root, which will help in connect using ssh
- Install the kubectl command
- Make the kubectl command executable
- Move the kubectl command to the /usr/local/bin location,so as to make it accessible from anywhere
- Create .kube directory in the /root folder
- Copy the config file, client.key,client.crt,ca.crt file to the /root/.kube directory. (The permission files are those of kubectl configured of your HostOS)
11. Create /root/yml and copy the deployment.yml file in it.
12. Generate the SSH key in the container and expose 22 port.
The image can also be used from the docker hub:
We also need to configure our cloud (Jenkins Master-Slave)
To set up Jenkins as a Cloud server go to Jenkins>Manage Jenkins> Manage Nodes and Clouds> Configure Clouds. Now add Docker host details as follows:
So let us begin with Job1 and what all it will do:
- Jenkins will pull code from the GitHub repository and store it in its workspace using Poll SCM (set at intervals of 1 minute). Instead of using Poll SCM, you can also do the same using GitHub hook triggers and ngrok, to get a brief about how to do, refer to this article:
2. The developer has also pushed the Dockerfile with the image(shirsha30/httpd_server:latest) dynamically for the application and copy the application code(index.html) into that corresponding docker image.
The output of Job1:
Job2:
- Job 2 will run on the successful completion of Job1.
- This job deploys Webserver on top of the Kubernetes cluster on the Dynamic Jenkins Slave node.
You might get this error:
- This error is if your plugins or Jenkins are out of date.
- Minikube should be running in the base system. To check if it is running, run the command:
minikube ip
If it is not running, then start the services using
minikube start
- Or it may be because there is an error in your config file of Kubernetes. (check the cluster information by launching and going manually inside the docker container). The file name should be “config”. To check run the below command:
kubectl config view
Now all the errors are debugged.
Initially when the job starts building it shows
pending- ‘Jenkins’ doesn’t have label docker-agent ->docker agent offline->docker agent launching
The output of job2:
Site updated using rollouts:
Build-pipeline view:
Refer the git repository for more information:
That’s all for everybody. Thank you!