We have seen a lot of things with Jenkins, Kubernetes and have deployed the websites using these tools and it really do give a lot many great features. Moreover, technology has unlimited corners and its widening in the blink of an eye and there are many such features been continuously added to upgrade our lives by making things easy. In this article, I will be discussing about one such feature which is more feasible to use Jenkins, i.e Groovy script. It’s a very powerful language and has a capability to do anything practically.
It reads the files in which Jenkins master has access to on the host. Groovy is used as a scripting language for Java offering many active features like DSL support, dynamic typing, etc. Earlier, we used to create freestyle jobs and then configure, build it. We used to create Jenkins pipeline for job execution, here, we can use Jenkinsfile in this case.
So, its an object oriented programming language, mainly used for Java platform which manages Jenkins pipeline, where we can use different languages together. Groovy is and agile and dynamic language having seamless integration with all java objects and libraries. Let’s move towards the task execution. I’ve attached the screenshots of steps that I followed to complete the task.
I’ve used technologies like Github, Docker, Jenkins, Kubernetes, Groovy. Java and Groovy has a same syntax. I created a Dockerfile, groovy file for Jenkins named Jenkins.groovy and a normal php or html file for testing, PVC and service file for deployment purpose. I will list out the codes of all those files below-
Dockerfile-
FROM centos:latest RUN cd /usr/local/bin && curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl && \ chmod +x kubectl &&\ mkdir /root/task && \ yum -y install java-11-openjdk-devel && \ yum -y install wget && \ rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key && \ wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo && \ yum install -y initscripts &&\ yum install sudo -y &&\ yum install net-tools -y &&\ yum install git jq -y && \ mkdir /root/YML &&\ yum install jenkins -y && \ sed -i '100i\jenkins ALL=(ALL) NOPASSWD: ALL ' /etc/sudoers COPY ca.crt client.key client.crt /root/ COPY config /root/.kube COPY php.yml pvc.yml service.yml /root/YML/ EXPOSE 8080 CMD ["java", "-jar", "/usr/lib/jenkins/jenkins.war"]
Groovy code-
job('Job-1') { scm { github('Shreya-cyber/Devops6','master') } steps{ shell('sudo cp -rvf * /root/task') triggers { upstream('JOB DSL', 'SUCCESS') } } } //-----------------------------------------------------------JOB-2------------------------------------------------------------------------- job('JOB-2') { steps { shell('''#!/bin/bash cd /root/task/ output=$(find -name "*.php") if [[ $output == *".php"* ]]; then kubectl apply -f /root/YML/pvc.yml kubectl apply -f /root/YML/php.yml sleep 25 kubectl get pods --output json > /root/pods.json parser=$(jq -r ".items[]?.status.containerStatuses[]?.ready" /root/pods.json) if [[ $parser == *"true"* ]]; then trans=$(jq -r ".items[].metadata.name" /root/pods.json) #parsing kubectl cp /root/task/*.php $trans:/var/www/html #paste file in container kubectl apply -f /root/YML/service.yml # service creation kubectl get all --output json > /root/pods.json else echo "NO" fi fi #optional jq -r ".items[]?.status.containerStatuses[]?.ready" /root/pods.json jq -r ".items[].metadata.name" /root/pods.json port=$(jq -r ".items[2]?.spec.ports[].nodePort" /root/pods.json) #store value ip=$(jq -r ".items[]?.status.hostIP //empty " /root/pods.json) echo $ip:$port # pass this into new job ''') triggers { upstream('Job-1', 'SUCCESS') } } } //----------------------------------------------------------JOB-3------------------------------------------------------------------------ job('JOB-3') { steps{ shell('''port=$(jq -r ".items[2]?.spec.ports[].nodePort" /root/pods.json) ip=$(jq -r ".items[]?.status.hostIP //empty " /root/pods.json) if curl -s --head --request GET http://$ip:$port | grep "200 OK" > /dev/null; then echo "Working" else curl http://192.168.198.128:1999/job/JOB-4/build?token=redhat --user admin:redhat exit 1 fi ''') triggers { upstream('JOB-2', 'SUCCESS') } } } //--------------------------------------------------------------JOB-4---------------------------------------------------------------------- job('JOB-4') { authenticationToken('redhat') publishers { extendedEmail { recipientList('shreya02santoshwar@gmail.com') defaultSubject('Job status') defaultContent('Status Report') contentType('text/html') triggers { always { subject('build Status') content('Body') sendTo { developers() recipientList() } } } } } } // ++++++++++++++++++++++++++++++++++++++++++++++++++BUILD_PIPELINE+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==== buildPipelineView('project-A') { filterBuildQueue() filterExecutors() title('Project A CI Pipeline') displayedBuilds(5) selectedJob('Job-1') alwaysAllowManualTrigger() showPipelineParameters() refreshFrequency(60) }
Service –
apiVersion: v1 kind: Service metadata: name: mysvc spec: type: NodePort selector: type: php ports: - port: 80 nodePort: 30300
protocol: TCP
PVC-
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: php-html-vol1 labels: name: data-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: log-vol2 labels: name: logpvc spec: accessModes: - ReadWriteOnce resources: requests:
storage: 1Gi
After saving all the files in one folder, I have uploaded the Groovy code and php code to Github, so that my Jenkins job will fetch the code after building. I have added the rest files to redhat root directory using Winscp.
Below is my Dockerfile, this will create a container image that has Jenkins installed in it. It will download all the required files needed for Jenkins setup. Then it will copy the cert files for configuring Kubernetes. After the image is created, you can launch the container where you will get Jenkins and Kubernetes readily available.
Use the command for building an image-
# docker build -t jenkins6:v1 /root
Jenkins6 will be the name of my image having v1 as version 1. /root is the path of where my Dockerfile resides.
Image is been created successfully. Now, we are ready to launch a container and execute the task. Its more fun now! After you launch the container by using command-
# docker run -it –name <container_name> -p <port no.> :8080 <image_name>
Container name would be of your choice. You have to assign any port no. where your Jenkins will be running, eg: 8088:8080. Jenkin runs on default port no 8080, so we have to use it for assigning port no. 8088, so your container will be exposed in outside world, and you are free to use it from browser. Image name will be the image you created. Finally, go to the assigned port and configure Jenkins.
You will be asked to download some plugins, so I am listing some names below to install-
Build pipeline, Email Extension, Job-DSL, Github, etc.
Initially, you might not get some of the plugins available, but after configuring the Jenkins, and when you are done with username and password setup, you can go to the Manage Jenkins section and can install the rest plugins.
Configure your port no. and proceed ahead.
Your Jenkins is ready and finally you are good to go!
After you are done installing all the plugins, first we will create a Seed Job in Jenkins, which will fetch the Github repository for the groovy file. Its important to have Job-DSL plugin installed completely, or else this task will not be executed. Job-DSL plugin generally used for managing Jobs through Groovy. In the seed job select the Job-DSL from the > build drop-down section.
Add your github repo here.
Add the DSL script and keep everything default. Apply and save it.
Apparently it will show you error when you build the job because we have not approved the groovy script. To approve go to Manage Jenkins > In-process Script Approval.
Click on Approve and then run the job again. You will see new jobs come up automatically on your dashboard.
Lets move ahead with Job-1-
Everything will be pre-created and the code will also be fetched from the github repo as you save it. It will also copy the code from Jenkins and will paste it in the directory that we mention.
See the console output, the job is build successfully.
In Job-2, we need to choose the container type according to the code developer push. So we create multiple containers are we are not knowing which code will be fetched. We have used jq here which will fetch the data from JSON file. It fetches a required value from pods.json, and I need Status of Deploymentof K8s. if its true then it’ll go inside those conditions and it contains one more condition which provide k8s pod name to $trans variable which also exposes the pod to outside world. It will also store the ip and port of the pod exposed in the $ip and $port. You will get to see all this after the job is built successfully. Check the console output-
Job-3 tests the working of ip and port that pod gives and if it does not work then it triggers the next job. If the website is working then the job stops. It has a code which retrieve data from json and store it.
Job-4- In my case, website was running well so it wont send me any mail. But in case your website is not been working, it sends the email to debveloper. Email plugin helps us in this setup.
This is how my dashboard looks after successful build of all the jobs.
The website is also running well.
Check whether the pods are running just to re-verify by the cmd shown in the image. You can also view the status of all the pods. I’ve used deployment so in case my pod fail to work, automatically replicas will be launched so that website will run smoothly.
So, this is how I executed the task.
Thank you for reading, stay safe and happy learning!