Web Server with Live Updates Roll Out using Jenkins and K8s
JENKINS : Jenkins is an open-source automation tool written in Java with plugins built for Continuous Integration purposes. Jenkins is used to build and test your software projects continuously making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build. It also allows you to continuously deliver your software by integrating with a large number of testing and deployment technologies.
Kubernetes (K8s) is an open-source system for automating deployment, scaling, and management of the containerized applications. It groups containers that make up an application into logical units for easy management and discovery. Kubernetes builds upon 15 years of running production workloads at Google, combined with best-of-breed ideas and practices from the community.
Problem Statement :
- 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:
a. Create the new image dynamically for the application and copy the application code into that corresponding docker image
b. 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:
a. 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.
b. If Application created first time, then Expose the application. Else don’t expose it.
NOTE :- First of all we have to do some setup like add -H tcp://0.0.0.0:4243 in /usr/lib/systemd/system/docker.service file so that docker service of this VM can be used by another machine[this process is called socket binding ].
Now reload and restart Docker service
systemctl daemon-reload
systemctl restart docker
Step 1 : Creating the container image that’s has Linux and other basic configuration required to run Slave for Jenkins. ( example here we require kubectl to be configured ).
Now for creating docker Image , we use Dockerfile with following code :
FROM centos:latest
COPY kubernetes.repo /etc/yum.repos.d/kubernetes.repo
RUN yum install kubectl -y
RUN chmod +x ./kubectl
RUN mv ./kubectl /usr/bin/
RUN kubectl version --client
RUN mkdir /root/.kube
COPY config /root/.kube/
COPY *.crt /root/
COPY client.key /root/
RUN yum install java -y
RUN yum install openssh-server -y
RUN mkdir /root/jenkins-ws
RUN ssh-keygen -A
COPY ssh_config /etc/ssh/
RUN echo root:redhat | chpasswd
CMD ["/usr/sbin/sshd" , "-D"] && / bin/bash
RUN yum install sudo -y
RUN yum install git -y
Since we want kubectl to be configured in the dynamic slave so we have to download and install kubectl in it using Dockerfile .
I have installed kubectl using Native Package Management . So first we create a kubernetes.repo file using cmd :-
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
kubernetes.repo file
Then install kubectl cmd using :-
yum install kubectl -y
Create a .kube folder and copy config file in it.
Config file :-
apiVersion: v1
kind: Configclusters:
- cluster:
server: https://192.168.99.105:8443
certificate-authority: /root/ca.crt
name: pgclustercontexts:
- context:
cluster: pgcluster
user: Priyanshiusers:
- name: Priyanshi
user:
client-key: /root/client.key
client-certificate: /root/client.crt
Also copy all the certificates and keys using COPY cmd in /root folder of node. Install ssh software so that Jenkins can connect to the newly launched dynamic node through ssh . Set a password to login using ssh . Also create a ssh_config file .
ssh_config file :-
Port 22
Protocol 2
Hostkey /etc/ssh/ssh_host_rsa_key
Hostkey /etc/ssh/ssh_host_dsa_key
Hostkey /etc/ssh/ssh_host_ecda_key
Hostkey /etc/ssh/ssh_host_ed25519_keyLoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
usePAM yes
Create a directory which is used as jenkins working directory “/root/jenkins-ws” so all the github files will be downloaded in it by default . Install git and sudo software also .
Now we have to build the image using cmd :-
docker build -t k8s:v1 .
So our image is ready . Now we have to setup Jenkins Cloud . For this we have to install Docker , Build Pipeline , GitHub plugins .
JOB 1 : Pull the Github repo automatically when some developers push repo to Github and perform the following operations as:
a. Create the new image dynamically for the application and copy the application code into that corresponding docker image
b. Push that image to the docker hub (Public repository)
( Github code contain the application code and Dockerfile to create a new image )
Dockerfile for the creation of image which is used to lauch application:
FROM centos:latest
RUN yum install httpd -y
WORKDIR /root/jen-ws
COPY *.html /var/www/html
CMD /usr/sbin/httpd -DFOREGROUND && /bin/bash
EXPOSE 80
In this I have installed httpd ( apache webserver ) for deploying website . Created working directory “/root/jen-ws” and copied all the webpages in it . Started httpd services and exposed port number 80 .
Added Build triggers so that whenever the developer uploads a new code jenkins JOB automatically gets triggered . Here I have used Poll SCM .
Execute Shell
Create a seperate Workspace “/dev-task4” and copy the GitHub files in it .
Now add Post Build Actions : [ Biuld / Publish Docker Image ] for building and pushing the image to docker hub using Jenkins .
Specify the Directory for Dockerfile . Since I have copied all the GitHub files in “/dev-task4” directory so I have to specify this particular directory only . Give the cloud name “docker” . Then Give the name to the image which is to be build . And specify the docker hub credentials so that jenkins can login and push the image .
Console output after Build :-
JOB 2 : ( 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.
Since we want that this Job run on the above created cloud , so we have to Restrict where this project builds . While setting up cloud I have gave the label “dyn-k8s” to it , so I have specified this .
Execute Shell :-
So I have copied the “task4.yml” file in “/root/” folder of the dynamic jenkins slave . Created deployment and exposed it an if already exists then rollout .
My “task4.yml” file :-
apiVersion: apps/v1
kind: Deployment
metadata:
name: t4-deploy
spec:
replicas: 3
selector:
matchLabels:
env: production
template:
metadata:
name: t4-con
labels:
env: production
spec:
containers:
- name: t4-con
image: priyanshigarg/webserver:latest
I have created a deployment so that without any downtime our application can be rolled out . For load balancing created 3 replicas . And used the image which is created in JOB 1 .
Now we can see our Website using [ IP of minikube ]:[ Port number on which our pod is exposed ] ie [ 192.168.99.105:32608 ]
Now If I change the code of my webpage I can see my new webpage without any downtime .
Since I change the code and pushed to GitHub so JOB 1 will automatically start and build the image with new application . After successful build of JOB 1 , JOB 2 automatically trigger and rollout pods .
Console Output of JOB 2
Hope You Liked This Article
Thanks For Reading :-)