Web Server with Live Updates Roll Out using Jenkins and Kubernetes
This task will help us deploy a Web Server using Distributed Jenkins where a dynamic slave will deploy the webserver on Kubernetes. Jobs have been pipelined in such a way that either a new Deployment will be done and exposed else update will be rolled out on the already existing deployment of Web Server. The complete setup is automated and the pipeline will run every time a developer pushes any changes to the web page or for any configuration changes in the docker image. The update will be rolled out in such a way that downtime is not caused for the clients.
This task has been completed on:
- RHEL 8
- Docker-CE (Client — 19.03.10, Server — 18.09.1)
- Kubectl will be set up on the dynamic slave
- MiniKube is set up Windows.
We will install the required plugins in Jenkins:
- Workspace Cleanup
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. The steps for it can be found in a previous article of mine :
Automated Web Deployment Setup
Problem Statement - Problem is divided into three main parts: Create a git repository and develop a Jenkins job that…
Moving on to the next step, the job will copy all the files inside the docker image to be built and then will be further pushed to Docker Hub. This all will be done using the Docker Plugin.
We need to allow docker daemon to be accessed remotely. For that, we need to edit /usr/lib/systemd/system/docker.service.
The following has been appended to ExecStart. You can bind it with any available port. 0.0.0.0 denotes any IP that will be given to the host.
Then restart the services.
systemctl restart docker.service
So before using the Docker Plugin, we will set up the Docker Cloud on Jenkins.
Manage Jenkins > Manage Nodes and Clouds > Configure Clouds > Add A New Cloud — Docker > Set the required parameters > Test connection
** Docker Host URI is the remote docker host where all the containers will run. In my case, I have set it on my localhost as well.
Now moving back to configuring the Job 1.
The workspace will be cleaned before every build and then pull the repository.
The Directory is default set to the workspace so it will auto pick the Dockerfile. Set image name and credentials and you are good to go.
The files used in the task are available at :
Contribute to devil-test/dockerfile-deploycodes development by creating an account on GitHub.
The pushed image is available at :
Job 2 will build on the successful build of Job 1. This job will create a new deployment if does not exist else it will rollout update to the existing deployment. This Job has to run on a dynamic container slave whose template will be configured on the docker cloud. First, we will build the image to be used via a Dockerfile.
## The base code has been picked from https://docs.docker.com/engine/examples/running_ssh_service/ and edit further to setup kubectl. ##
FROM ubuntu:16.04RUN apt-get update && apt-get install -y openssh-server && apt-get install openjdk-8-jre -yRUN mkdir /var/run/sshdRUN echo 'root:password' | chpasswdRUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config# SSH login fix. Otherwise user is kicked off after loginRUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd#ENV NOTVISIBLE "in users profile"#RUN echo "export VISIBLE=now" >> /etc/profile#Kubectl SetupRUN apt-get install curl -yRUN curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectlRUN chmod +x ./kubectlRUN mv ./kubectl /usr/local/bin/kubectlEXPOSE 22CMD ["/usr/sbin/sshd", "-D"]
Next, We will add Docker template in the Docker Cloud settings.
Docker Agent templates…
Labels: This will be used in jobs to refer and call the specifically required slave.
Name: The Node Name that appears in Agents list.
Docker Image: The image used to create the slave container.
** In Container Settings, add the mount point where the files required for kubectl configuration are stored.
These files have been copied from windows where my MiniKube is set up and running as 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.
Now moving on to the setup in job 2.
export len=$(kubectl get deployments | grep webserver | wc -l)if [ $len -eq 0 ]thenkubectl create deployment webserver --image=ashishkr99/httpd_serverkubectl scale deployment webserver --replicas=3kubectl expose deployment webserver --port 80 --type NodePortkubectl get svc webserverelsekubectl rollout restart deployment/webserverkubectl rollout status deployment/webserverfi
Job 1 Build Output
Job 2 Build Output
When no deployments:
Deployment exists, therefore rolling out updates:
Testing the webpage: