Solving Downtime problem using Dynamic Jenkins cluster concept
Sourabh Choudhary
Software Engineer | Java | Spring Boot | RestFul WebServices | Microservices | DSA
This article is all about, how we can get Zero Downtime while updating any website i.e whenever we are updating anything in our website, client will not face any downtime problem, means our website is still accessible to the clients.
I am performing this task under the guidance of Mr. Vimal daga sir, in our Devops Assembly Lines training.
Task Overview :
1. Create container image that’s 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 starts job on slave based on the label provided for dynamic approach.
3. Create a job chain of job1 & job2 using build pipeline plugin in Jenkins
4. Job1 : Pull the Github repo automatically when some developers push repo to Github and perform the following operations as:
1. Create the new image dynamically for the application and copy the application code into that corresponding docker image
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:
1. If launching first time then create a deployment of the pod using the image created in the previous job. Else if deployment already exists then do rollout of the existing pod making zero downtime for the user.
2. If Application created first time, then Expose the application. Else don’t expose it.
Let's get started :
For performing this task, i am using 2 virtual machine(VMs)
1 - Where jenkins and docker engine is running(you can also run the docker engine in another VM)
2 - Where Kubernetes is running
In my VM1, our jenkins service and docker engine is running, also for accessing the docker service outside this VM, we need to add some commands in the docker.service file
For this : Open /usr/lib/systemd/system/docker.service file and add -H tcp://0.0.0.0:4243
(This command will help us to access the docker service of this VM from another machine[this process is called socket binding]).
I created an image for dynamic Kubernetes in VM1 which will help us to run our Kubernetes cluster on VM2.
After doing this step we have to reload our docker server. we can do this using following command :
systemctl daemon-reload systemctl restart docker
Now start the jenkins service in VM1 by running the below cmd:
systemctl start jenkins
After the above process done, we will configure the cloud on jenkins.
For this we need to install Docker plugin in jenkins.
After download the docker plugin, we can configure the cloud by going to
Manage Jenkins -> Manage nodes and clouds -> configure cloud -> add a new cloud-> docker
In the Docker Host Url, give your VM IP, where your docker engine is running, in my case i am giving my VM1 IP, because my docker engine is running in VM1.
POST-COMMIT file for auto push the code to github :
JOB1 : Whenever developer commit the code to github, this job will pull the repo automatically, here i used the poll scm concept :
This job will do below 2 things :
1. Create the new image dynamically for the application and copy the application code into that corresponding docker image
Note : We have to fill the below columns :
Cloud : cloud name that we have configured for docker, where the actual process like building the image will be done using that VM resources.
Image : Name of the image with tag
Registory Credentials: For pushing the image to "dockerhub", we need to give our dockerhub credentials.
2. Push that image to the docker hub (Public repository)
( Github code contain the application code and Dockerfile to create a new image )
JOB2(Prerequisite) :
Before going to JOB2, we need to do some more important things which is prerequisite to perform JOB2 :
we need to create a cloud where we want to run the kubernetes cluster.
Creating a Kubernetes Image using the below Dockerfile:
FROM centos RUN yum install java-11-openjdk.x86_64 -y RUN yum install openssh-server -y RUN yum install sudo -y RUN echo "root:redhat" | chpasswd RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl RUN chmod +x ./kubectl RUN mv ./kubectl /usr/local/bin/kubectl RUN mkdir /root/.kube COPY client.key /root/.kube COPY client.crt /root/.kube COPY ca.crt /root/.kube COPY config /root/.kube RUN mkdir /root/devops COPY deploy.yml /root/devops RUN ssh-keygen -A
CMD ["/usr/sbin/sshd", "-D"]
For Running this file create a new directory<any_name>
Inside this directory add your client.key, client.crt, ca.crt file
I will get this file from "C:\Users\<account_name>\.minikube" and "C:\Users\<Account_name>\.minikube\profiles\minikube"
and then create a config file in this directory :
config file :
apiVersion: v1 clusters: - cluster: certificate-authority: ca.crt server: https://192.168.99.101:8443 # Add your Minikube Ip here name: minikube contexts: - context: cluster: minikube user: minikube name: minikube current-context: minikube kind: Config preferences: {} users: - name: minikube user: client-certificate: client.crt client-key: client.key
create a deploy.yml file(Same directory)
apiVersion: apps/v1 kind: Deployment metadata: name: dev-deploy spec: replicas: 3 selector: matchLabels: env: prod template: metadata: name: dev-pod labels: env: prod spec: containers: - name: dev-con image: sourabhhcu/webserver:latest
Now lastly, create a Kubernetes cluster image using dockerfile :
docker build -t ssh_kube:latest .
Now we configure cloud for JOB2 :
Here, we enabled the Labels and providing the image name that we have created above to run our kubernetes.
Here we are providing the ssh key id and password to access it.
JOB2 : After the successful run of JOB1, this job will run, and perform following tasks :
( 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:
1. If launching first time then create a deployment of the pod using the image created in the previous job. Else if deployment already exists then do rollout of the existing pod making zero downtime for the user.
2. If Application created first time, then Expose the application. Else don’t expose it.
Build Pipeline View :
Output :
Thanks for Reading :)
Software Engineer @evalueserve | Full Stack developer (MERN) | Node.js | Python | JavaScript | DB | Docker
4 年Great sourabh
Backend Developer
4 年??