Integrating Jenkins & Kubernetes
Building a CI/CD pipeline to deploy a WebApp according to the code
This small project is to demonstrate how to build a CI/CD pipeline which can be used to deploy a WebApp. The CI/CD pipeline is built using Jenkins and use a Kubernetes Single-node Cluster to launch a deployment using Docker Container image suitable for the webpage.
If the webpage is created using PHP then a docker image with PHP software installed is used else image with HTML software installed is used for webpage created using HTML.
For this some basic pre-requisites are as follows:
- For Jenkins, it will be better to use one installed on top of a Docker Container. To create one a Dockerfile can be used to achieve automation. So the BaseOS must have docker-ce software pre-installed. For this, I will be using a RHEL8 (with docker-ce installed) as a Virtual Machine over Windows.
- A pre-configured Kubernetes Single-Node Cluster. To get one either launch over Cloud or install Minikube over BaseOS as a Virtual Machine. To get Minikube, follow the instructions given on this link. In this project, I will be installing Minikube on-top of Windows itself.
Note: to use such a setup, configure Network settings for both VMs to have connectivity between them.
Login to RHEL8 VM as root user. Create a local directory to use as workspace and create a Dockerfile.
Before building the docker image, 4 files need to be copied from Windows OS to RHEL8 VM. These files will be used by kubectl program in the Jenkins container to contact the Single-Node Cluster as a client. The four files are config, ca.crt, client.crt & client.key; config file is present in the .kube folder under root directory & the other 3 files are available in the .minikube folder. Copy these files using tools like WinSCP.
Copy the files into some directory & create a Dockerfile.
The Dockerfile is available on this GitHub repository.
# dockerfile to create a Jenkins Image. FROM centos:latest RUN yum install wget -y RUN yum install sudo -y RUN yum install python38 -y RUN sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo RUN sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key RUN yum install java-11-openjdk.x86_64 -y RUN yum install jenkins -y RUN yum install git -y RUN yum install initscripts -y RUN yum install /sbin/service -y RUN sed -i "102i jenkins ALL=(ALL) NOPASSWD: ALL" /etc/sudoers # RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers CMD sudo service jenkins start -DFOREGROUND && /bin/bash RUN chmod 0440 /etc/sudoers 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/bin/ RUN mkdir /root/.kube COPY ca.crt /root/ COPY client.crt /root/ COPY client.key /root/ COPY config /root/.kube CMD ["java","-jar","/usr/lib/jenkins/jenkins.war"] EXPOSE 8080
Switch to the same directory & use the given command to create a Docker Image. Use the complete path where the Dockerfile is located or use "." if present at the same location.
docker build -t jenkube:v1 /root/dev_task3 docker images | grep jenkube
Use docker images command to view the just created image. To launch a container and use Jenkins WebUI use the docker run command and use "-p" option for PATting; a port is assigned to access the WebUI from a web-browser.
docker run -it -p 8085:8080 --name myjenkins jenkube:v1
The Output of the docker run command will consist of password for Admin user which will be used to access Jenkins WebUI. This password will also be available in the given file.
Use the IP address of the RHEL8 system and the port to get the WebUI and proceed with further installation; open a web-browser and use the URL: IP:8085
4 jobs/items have to be created for this project with configurations provided below.
Job 1: get_repocode
Configure this first job to get the codes uploaded by Developer to GitHub. Use Poll SCM to keep check over the code and pull as & when there is some change and copy the codes to some local workspace.
Job 2 : initiate_deployment
This Job is triggered when Job 1 executes completely. It checks the language used to create the webpage and launches a deployment suitable for the webpage. The deployment uses either an httpd image if HTML is used or a PHP-installed image. Kubernetes program will download the docker image behind-the-scene to be used from hub.docker.com. To launch the deployments YAML codes are used provided in this GitHub repository.
The code used will first create a PVC for the deployments if not created before, to use to keep the data for webpage persistent/permanent.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvweb labels: app: myweb spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
Then create a deployment according to the code. For eg, manifest file for HTML is given below:
apiVersion: apps/v1 kind: Deployment metadata: name: httpdeploy labels: app: myweb spec: replicas: 3 selector: matchLabels: app: myweb env: production template: metadata: name: httppod labels: env: production app: myweb spec: containers: - name: httpcont image: httpd ports: - containerPort: 80 volumeMounts: - mountPath: "/usr/local/apache2/htdocs" name: mypvc volumes: - name: mypvc persistentVolumeClaim: claimName: pvweb
This deployment is then exposed at some port.
apiVersion: v1 kind: Service metadata: name: mysvc labels: app: web-svc spec: selector: app: myweb type: NodePort ports: - nodePort: 31180 port: 80 targetPort: 80
Job 3 : check_status
Job triggered after a successful execution of Job 2. This job will check the "Status Code" of the WebApp. The status-code returned will be equal to 200 iff the webpage shows no errors. If status is 'not OK' then a mail is sent to the Admin or the Developer by calling Job 4 using curl command; configure Job 4 to use build trigger using scripts.
Job 4 : mail_dev
This job is triggered by Job 3 iff there is/are some error(s) in the WebApp. It will send a mail to the specified mail address by running a python code, provided on the GitHub repository specified at last. Changes required to the code are mentioned in README.md
When an error a mail as shown below is sent to the specified mail address
Install Build-pipeline plugin to have a better view of the CI/CD pipeline
After a successful execution of the pipeline, the WebApp is ready and deployed!!
To cross-check,
- Use command: kubectl get all on Windows Command Prompt or RHEL8 Terminal to view the different resources created.
- View the webpage by using the MinikubeIP:31180; the port must be same as provided in the YAML codes. To get Minikube IP use command, minikube ip on Command Line
- On the browser,
- On a Command Line or terminal, using curl command
Finally, the goal of this project is achieved and a WebApp is deployed and available for Clients in the same network. Even if a pod goes down or forcibly terminated, another is launched with the same specifications automatically. Update the codes for webpage and watch how the WebApp is deployed with all the new changes automatically.
The GitHub repository containing all the necessary codes is available on the link given below:
I would like to thank my mentor Mr. Vimal Daga and LinuxWorld Informatics Pvt Ltd for guiding me with the Right Education and helping me to learn the different aspects of the DevOps world.