The GROOVY with JENKINS and KUBERNETS
Ashutosh Kumar Sah
DevOps Engineer @CoffeeBeans | Ex - Kredifi | Ex - Teqfocus | Microsoft Azure Certified: Az-900, Ai -900, Dp-900 | Oracle cloud infrastructure certified fundamental 2022 | Aviatrix certified DevOps cloud engineer |
So the first thing first why i started this project . the only reason for making this projest is to full fill the need the of a customer if they want to do fully automatic project automation.That was the reason from a customer's view or user's view. This is the task 6 of my Devops Training under the mentorship of the Worlds record holder Mr.vimal daga.
What new we are using in comparing to my other task project is "GROOVY" what is it :
Groovy is an object-oriented programming language used for JVM platform . This dynamic language has a lot of features drawing inspiration from Python, Smalltalk & RUBY. It can be used to orchestrate your pipeline in Jenkins and it can glue different languages together meaning that teams in your project can be contributing in different languages.
Groovy can seamlessly interface with the Java language and the syntax of Java and Groovy is very similar. If you forget the syntax when writing Groovy, you can continue to write directly in Java syntax. Groovy can also be used as one of the scripting languages for the Java platform. Groovy scripts can be called in Java, which effectively reduces time spent on Java development.
It also offers many productivity features like DSL support, closures, and dynamic typing. Unlike some other languages, it functions as a companion, not a replacement, for Java.Groovy source code gets compiled to JVM Bytecode so it can run on any platform.
Why use Groovy?
Here are the major reasons why you should consider using Groovy, a commonplace option for creating pipeline files.
1. As we said earlier, Groovy is an agile and dynamic language. It has seamless integration with all existing Java objects and libraries.
Groovy is Java without types, so without defining the basic data types like int, float, String, etc. Basically it’s the same as Java: defining variable without specifying a type. Groovy will judge the type based on the value of the object.
So lets start the work :
The task is:
Perform third task with the help of Jenkins coding file ( called as jenkinsfile approach ) and perform the with following phases:
1. Create container image that’s has Jenkins installed using dockerfile Or You can use the Jenkins Server on RHEL 8/7
2. When we launch this image, it should automatically starts Jenkins service in the container.
3. Create a job chain of job1, job2, job3 and job4 using build pipeline plugin in Jenkins
4. Job2 ( Seed Job ) : Pull the Github repo automatically when some developers push repo to Github.
5. Further on jobs should be pipeline using written code using Groovy language by the developer
6. Job1 :
1. By looking at the code or program file, Jenkins should automatically start the respective language interpreter installed image container to deploy code on top of Kubernetes ( eg. If code is of PHP, then Jenkins should start the container that has PHP already installed )
2. Expose your pod so that testing team could perform the testing on the pod
3. Make the data to remain persistent using PVC ( If server collects some data like logs, other user information )
7. Job3 : Test your app if it is working or not.
8. Job4 : if app is not working , then send email to developer with error messages and redeploy the application after code is being edited by the developer
And What i did first ,
Written DockerFiles for two images one for HTML
HTML
FROM centos:latest RUN yum install httpd -y COPY *.html /var/www/html/ CMD /usr/sbin/httpd -DFOREGROUND && /dev/bash
PHP:
FROM centos:latest RUN yum install httpd -y RUN yum install php -y COPY *.php /var/www/html/ CMD /usr/sbin/httpd -DFOREGROUND && /dev/bash
Why we use Persistent Volume:
Here we are going to store all the log files and other files into it , but why persistent if container got hacked or crashed then the stored data in it also will be removed so we have to mount a persistent data in our containers , log files are useful to know the reason why our container stopped or crashed . It will help in future to remove such error or bug from beginning.
So we are creating a Persistent volume :
HTML (PV and PVC):
apiVersion: v1 kind: PersistentVolume metadata: name: pvvolhtml labels: type: local spec: storageClassName: manual capacity: storage: 2Gi accessModes: - ReadWriteOnce hostPath:
path: "/mnt/sdr/data/website"
Use command to create: kubectl create -f pvvolhtml.yml and this code is also Saved in github repository.
And PHP (PV and PVC)
Persistent Volume
apiVersion: v1 kind: PersistentVolume metadata: name: pvvolphp labels: type: local spec: storageClassName: manual capacity: storage: 2Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/sdr/data/website"
Used command to create: kubectl create -f pvvolphp.yml
This will create PV for our php container means that container which we will use for php web page.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: volclaimhtml spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests:
storage: 2Gi
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: volclaimphp spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests:
storage: 2Gi
We are going to create Jenkins Job using Groovy:
job("GroovyCodeInterpreter") { steps { scm { github("ashu-cybertron/devops-task6", "master") } triggers { scm("* * * * *") } shell("sudo cp -rvf * /task6") if(shell("ls /task6/ | grep html")) { dockerBuilderPublisher { dockerFileDirectory("/task6/") cloud("Kube_slave") tagsString("ashucybertron/html:v1") pushOnSuccess(true) fromRegistry { url("ashucybertron") credentialsId("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") } pushCredentialsId("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") cleanImages(false) cleanupWithJenkinsJobDelete(false) noCache(false) pull(true) } } else { dockerBuilderPublisher { dockerFileDirectory("/task6/") cloud("Kube_slave") tagsString("ashucybertron/php:v1") pushOnSuccess(true) fromRegistry { url("ashucybertron") credentialsId("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") } pushCredentialsId("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") cleanImages(false) cleanupWithJenkinsJobDelete(false) noCache(false) pull(true) } } } } job("GroovyDeployment") { triggers { upstream { upstreamProjects("GroovyCodeInterpreter") threshold("SUCCESS") } } steps { if(shell("ls /task6 | grep html")) { shell("if sudo kubectl get pv html-pv-vol; then if sudo kubectl get pvc html-pv-vol-claim; then echo "volume present"; else kubectl create -f volclaimhtml.yml ; fi; else sudo kubectl create -f pvvolhtml.yml; sudo kubectl create -f volclaimhtml.yml ; fi; if sudo kubectl get deployments html-deploy; then sudo kubectl rollout restart deployment/html-deploy; sudo kubectl rollout status deployment/html-deploy; else sudo kubectl create -f webdphtml.yml; sudo kubectl create -f webexpose.yml; sudo kubectl get all; fi") } else { shell("if sudo kubectl get pv php-pv-vol; then if sudo kubectl get pvc php-pv-vol-claim; then echo "volume present"; else kubectl create -f volclaimphp.yml; fi; else sudo kubectl create -f pvvolphp.yml; sudo kubectl create -f volclaimphp.yml; fi; if sudo kubectl get deployments php-deploy; then sudo kubectl rollout restart deployment/php-deploy; sudo kubectl rollout status deployment/php-deploy; else sudo kubectl create -f webdpphp.yml; sudo kubectl create -f webexpose.yml; sudo kubectl get all; fi") } } } job("Monitor") { triggers { scm("* * * * *") } steps { shell('export status=$(curl -siw "%{http_code}" -o /dev/null 192.168.99.105:30303); if [ $status -eq 200 ]; then exit 0; else python3 mail.py; exit 1; fi') } } job("Redeployment") { triggers { upstream { upstreamProjects("Monitor") threshold("FAILURE") } } publishers { postBuildScripts { steps { downstreamParameterized { trigger("GroovyCodeInterpreter") } } } } }
run a command "kubectl get all" then the output
deployment of html :
apiVersion: apps/v1 kind: Deployment metadata: name: html-deploy labels: app: webserver spec: replicas: 2 selector: matchLabels: app: webserver template: metadata: name: deployhtml labels: app: webserver spec: volumes: - name: pvvolhtml persistentVolumeClaim: claimName: volclaimphp containers: - name: html-deploy image: ashucybertron/html:v1 imagePullPolicy: IfNotPresent volumeMounts: - mountPath: "/var/log/httpd"
name: pvvolhtml
deployment of php
apiVersion: apps/v1 kind: Deployment metadata: name: deployphp labels: app: webserver spec: replicas: 2 selector: matchLabels: app: webserver template: metadata: name: deployphp labels: app: webserver spec: volumes: - name: pvvolphp persistentVolumeClaim: claimName: volclaimphp containers: - name: deployphp image: ashucybertron/php:v1 imagePullPolicy: IfNotPresent volumeMounts: - mountPath: "/var/log/httpd"
name: pvvolphp
docker images created :
there is my github link:https://github.com/ashu-cybertron/devops-task6.git
any thing missing plz feel free to connect .