Here’s how to make Simple Development Pipeline with Jenkins and Kubernetes

Salik Sayyed
5 min readDec 25, 2020

A CI/CD pipeline automates your software delivery process. The pipeline builds code, runs tests (CI), and safely deploys a new version of the application (CD).

Automated pipelines remove manual errors, provide standardized feedback loops to developers, and enable fast product iterations.

How to achieve Pipeline Kubernetes?

Deployments in Kubernetes lets us Recreate, Rollout new pods for newer versions.

The Rollout Strategy which we will use here, uses the replica sets created for the deployments, it keeps on updating and launching those replicas which are currently not in use and redirects the work to newer updated pods, until all the pods, deployment are up-to-date.

Using Rollout Strategy in Kubernetes we can have zero downtime while updating our Deployment and successful update and deployment of the product takes place on the go.

What is Jenkins Master-Slave architecture?

Jenkins uses a Master-Slave architecture to manage distributed builds. In this architecture, Master and Slave communicate through TCP/IP protocol. Your main Jenkins server is the Master. … A Master instance of Jenkins can also execute build jobs directly.

Here’s an overview of what we will be doing:

  1. Create container image that’s has Linux and other basic configuration required to run Slave for Jenkins.
  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:
  5. Create the new image dynamically for the application and copy the application code into that corresponding docker image
  6. Push that image to the docker hub (Public repository)
  7. 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:
  8. 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.

Step 1: Building a Dockerfile

Dockerfile is used to build the docker images of our requirement. We just need to give docker build command to make the image.

Since We need to require to run slave for jenkins we need to do two things,

First set the Docker as slave from host.

Second we need the Dockerfile which has Kubectl configured to our minikube server, or server running kubernetes. Also exposing the ports required for the slave.

Dockerfile used :

FROM centos CMD ["/bin/bash"] RUN yum install java-11-openjdk.x86_64 -y RUN yum install sudo -y RUN yum install git -y RUN yum install httpd -y RUN yum install initscripts -y RUN yum install /sbin/service -y RUN sudo yum install wget -y 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/ COPY config /root/.kube/ COPY ca.crt /root/ COPY client.crt /root/ COPY client.key /root/ COPY config /root/.kube EXPOSE 8080

Here we rewrote the config file, and certificate and key needed to configure kubectl in dockerfile.

Step 2: Making Jenkins Slave

Here we need to run slave of Jenkins on the Docker container.

Generally we can have slave for Jenkins on any machine but for docker we need to configure cloud for it.

For this we need Docker Plugin From jenkins.

Now we need to set the Docker daemon to work as Slave.

For this just edit [Service] section and give cidr block of 0.0.0.0:exposing_port needed in docker.service file located at /usr/lib/systemd/system/docker.service.

After this, just reload the docker daemon and restart and export the port used with DOCKER_HOST environment variable.

systemctl daemon-reload systemctl restart docker export DOCKER_HOST=--ip:port--

To put it in slave node of Master Jenkins, configure cloud from Manage Jenkins.

Provide the Label to the Slave so as to identify it.

After configuring this you will see the slave of Jenkins if connection is successfully made.

Here as u can see its connected.

Step 3: Our another main target is to run and test the webserver files on top of kubernetes. So we need to have two yaml files one for HTML and for PHP taking this file types just as a basic for this article.

httpweb.yaml

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-http spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: v1 kind: Service metadata: name: http-webserver-service labels: ws: httpserver-service spec: ports: - port: 8085 targetPort: 80 nodePort: 9222 selector: ws: httpserver-service type: NodePort --- apiVersion: apps/v1 kind: Deployment metadata: name: http-web-server labels: ws: httpserver-service spec: replicas: 3 selector: matchLabels: ws: httpserver-service strategy: type: RollingUpdate #This is due to above mentioned rsns template: metadata: labels: app: webserver spec: containers: - image: httpd name: http-web-server ports: - containerPort: 9111 name: http-port volumeMounts: - name: pvc-http mountPath: /usr/local/apache2/htdocs/ volumes: - name: pvc-http persistentVolumeClaim:claimName: pvc-http

Similar is phpweb.yaml

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-php spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: v1 kind: Service metadata: name: php-webserver-service labels: ws: phpserver-service spec: ports: - port: 8090 targetPort: 90 nodePort: 31115 selector: ws: phpserver-service type: NodePort ___ apiVersion: apps/v1 kind: Deployment metadata: name: php-web-server labels: ws: phpserver-service spec: replicas: 3 selector: matchLabels: ws: phpserver-service strategy: type: RollingUpdate template: metadata: labels: ws: phpserver-service spec: containers: - image: vimal13/apache-webserver-php name: php-web-server ports: - containerPort: 80 name: php-port volumeMounts: - name: pvc-php mountPath: /var/www/html volumes: - name: pvc-php persistentVolumeClaim:claimName: pvc-php

We will save this file in the slave node i.e docker so that later we can use this to create a deployment.

Step 4: Creating the First job of Jenkins to fetch the github repo containing files for testing and also one addition job to push our jenkinslave docker imge to the docker hub.

sudo cp -r * /root/task3dev docker build -t <dockerhub id>/<imagename>:<version> /<dockerfilelocation>

So Job1 ran on master.

Step 5: Running script on the slave where kubectl is configured.

Here we used to restrict where the project can be run option in Jenkins and provided the Label of our slave. And job1’s followup.

Now in the script we need to check for the type of file and each time if there is change we need to rollout the new deployment.

This is same code used in my previous article of webdeployment with a bit of change for rolling update. You can checkout out how to configure kubectl and other requirements from there.

Lets check this out in our minikube server which I used for main kubernetes service.

Yeh, it rollout out nicely. Now time to check for our deployment. So now we can update, use deployment at the same time!

Here it is. Thanks for Reading!

Originally published at https://www.linkedin.com.

--

--

Salik Sayyed

Machine Learning enthusiast. Getting help from Devops Tools,AWS,GKE and more. Expressing Creativity through Apps and writing blogs.A Computer Engineer.