Jenkins is an open-source automation server, mainly used for continuous integration and continuous delivery (CI/CD). It's extensible and widely used, so you can almost always find a plugin that fits your CI/CD or automation needs. This tutorial will show you how to install Jenkins using Civo and how to troubleshoot the installation. It will also show you how data persistence works for Jenkins in Civo. By the end of this tutorial, you will have enough knowledge that you can use to implement your own CI/CD system with Jenkins.
Prerequisites
Before starting this tutorial, you will need the following in place:
In addition to the tools, you need to have basic knowledge about Kubernetes Objects such as namespaces, pods, ingress, and ingress controllers.
Installing Jenkins using Civo Marketplace
To install Jenkins using the Civo Marketplace UI, login to your account on your dashboard and go to Kubernetes > Kubernetes cluster > Marketplace. You will have a screen, as shown below:
After you have this screen up, select the CI/CD tab under the Marketplace section and click the Jenkins option.
Scroll to the bottom of the page and click the Create cluster button. Wait a few minutes until your cluster's status is Running.
Under the Cluster Information section, click the link to download your cluster's kubeconfig file. Once it's downloaded, take note of its file path. Open your terminal application and run the following command. Replace <download-file-path>
with the actual file path.
$ export KUBECONFIG=<downloaded-file-path>
With that, any command that you run using kubectl
moving forward will be run in the context of your newly created jenkins
cluster. Run the following command to check. The output should be jenkins
, your cluster name:
$ kubectl config current-context
Now, run the following command to check the namespaces in your cluster. Since you just installed Jenkins in your cluster, there should be a namespace named jenkins
in the list of the namespaces:
$ kubectl get namespace
NAME STATUS AGE
kube-system Active 31m
kube-public Active 31m
kube-node-lease Active 31m
default Active 31m
jenkins Active 30m
If your Jenkins installation is successful, there should be a pod named jenkins-0
running in the jenkins
namespace. Run the following command to check:
$ kubectl get pods -n jenkins
NAME READY STATUS RESTARTS AGE
jenkins-0 2/2 Running 0 34m
Accessing the Jenkins web UI
Now, you already have Jenkins running in your cluster, but you still can't access the Jenkins web UI. To access a pod running inside a Kubernetes cluster, you need to create an ingress object. This type of object is controlled by an ingress controller. If you recall, when you created the cluster, 3 applications were selected to be installed. One of them is traefik2-nodeport
, which is an ingress controller. So, you already have an ingress controller running in your cluster.
Before creating an ingress, you need to find the DNS name for your Kubernetes cluster. To do this, open the details page of your cluster in the Civo dashboard. You can find the DNS name under the Cluster Information section. Take note of the DNS name.
Create a file named ingress-jenkins.yaml
, copy the following yaml code, and paste it into the newly created yaml file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: jenkins.<cluster-dns-entry>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jenkins
port:
number: 8080
Use the kubectl
and ingress-jenkins.yaml
file to create the ingress object:
$ kubectl apply -f ingress-jenkins.yaml
ingress.networking.k8s.io/jenkins-ingress created
Now run kubectl get ingress -n jenkins
to verify that an ingress object has been created. The output should show you the information about the ingress object you created.
$ kubectl get ingress -n jenkins
NAME CLASS HOSTS ADDRESS PORTS AGE
jenkins-ingress <none> jenkins.671d97a8-37df-4d01-81d6-58782b715386.k8s.civo.com 671d97a8-37df-4d01-81d6-58782b715386.k8s.civo.com 80 7s
Copy the URL under the HOSTS column for the jenkins-ingress object. Open the URL in your browser. It should now show you your Jenkins login page.
You can get the login credentials information from the cluster details page in the Civo dashboard. Click the Installed Applications tab.
You can find the login credentials under the Jenkins section.
Use the credentials to log into your Jenkins dashboard.
Congrats! Now, you have successfully logged into your Jenkins dashboard.
Creating a simple Jenkins job
To test your new Jenkins installation, let's create a new Jenkins job. On the Jenkins dashboard, click New Item.
Type in hello-world for the name and choose Freestyle project as the type of the job. Click OK.
In the configuration page, scroll down to the Build steps section and click Add build step. Click Execute shell as the type of the build step.
Type in echo "Hello, world!" inside the Command text area. Click Save.
The page for hello-world Jenkins job will open up. The job is ready to be executed. Before you click the Build Now button to execute the job, open your terminal and run the following command:
$ watch kubectl get pods -n jenkins
By running the previous command, you can monitor the pods running inside jenkins namespace. Now, click the Build Now button on the hello-world Jenkins job page.
Under the Build History section, you will now see a new build with status pending.
Go back to your terminal. You will now see that there is a new pod with status ContainerCreating. This pod is created by Jenkins when you click the Build Now button. The hello-world job will be executed by this pod.
Because this is the first time you have executed a job in Jenkins, Kubernetes will need time to pull the image needed to execute the job. After a few minutes, the pod's status will change to Running.
Once the status of the pod is Running, go back to your Jenkins UI. The job execution item under the Build History section should now show the date and time of the job and a status bar.
Click on the date to open the job execution details page.
Click Console Output on the left-side menu to view the output of the job execution. It should show you something like the following:
At the bottom of the console output, you should see the simple script that you typed in the job configuration previously executed by Jenkins.
Go back to your terminal. The pod created to run your Jenkins job is not in the list of running pods because it has been terminated by Kubernetes when the job is finished.
With that, you have successfully run a simple job on your Jenkins installation.
Jenkins data persistence
Since now your Jenkins server runs in a pod on a Kubernetes cluster, you might wonder whether its data will be persisted in case the pod is terminated or restarted by the cluster. The answer is yes, your Jenkins data persisted. When you created the cluster and installed Jenkins as one of the applications, the installation also set up the data persistence for you by creating a persistent volume claim object, and this object is used by the jenkins-0 pod.
You can run the following command to confirm that the jenkins-0 pod is indeed using a volume created from a persistent volume claim:
$ kubectl get pods -n jenkins -o jsonpath='{.spec.volumes[?(@.name=="jenkins-home")]}' jenkins-0
The previous command prints the information about a volume named jenkins-home inside the jenkins-0 pod. The output should be a JSON object like the following:
{"name":"jenkins-home","persistentVolumeClaim":{"claimName":"jenkins"}}
What the output tells you is that a volume named jenkins-home is created using a persistent volume claim named jenkins. Using kubectl, you can get the information about this persistent volume claim:
$ kubectl get persistentvolumeclaim -n jenkins
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jenkins Bound pvc-eb86b9ef-15ee-44bb-ae22-4c31aa3312d1 10Gi RWO civo-volume 24h
The output should tell you that there is a persistent volume claim named jenkins. Its size is 10 GB, just like the plan that you chose for Jenkins installation when you created the cluster. Under the VOLUME column is the name of the volume created for your Jenkins data. You can check that the volume exists by checking the volume lists on the Civo dashboard.
The information on that page shows you that the volume is attached to Kubernetes: jenkins, and the size is 10 GB. The name of the volume should match the name from the kubectl command output previously.
Test data persistence
To check whether your Jenkins data really persisted, you can try to kill the jenkins-0 pod by running the following command:
$ kubectl delete pod -n jenkins jenkins-0
As soon as you execute the previous command, the jenkins-0 pod's status will change to Terminated, but it will change back to Init:0/2. This is because the jenkins-0 is controlled by another Kubernetes object called StatefulSet. Because of this stateful set, anytime the jenkins-0 is terminated, Kubernetes will create a new pod with the same name and configuration. Run the following command to monitor the progression of the jenkins-0 pod created automatically by Kubernetes to replace the previous pod that you just deleted:
$ watch kubectl get pods -n jenkins
You will have to wait until the jenkins-0 pod returns to Running status. While the status is not Running, you will not be able to access the Jenkins UI.
It will come back to running after all the pod initialization process is finished.
Now that the jenkins-0 pod is back to running state, using your browser, access your Jenkins dashboard. You will be asked to re-login.
After logging in, you will see that the hello-world job that you created still exists.
If you click on the job, you will see that the build history data still exists. So does the console output of the job execution previously.
With this, you have confirmed that the data persistence in your Jenkins installation works.
Cleaning up
To clean up the resources that you created in this tutorial, go back to your Civo dashboard and access the Kubernetes clusters page. Click the X button at the right side of your cluster item.
Type in your cluster name on the pop-up confirmation dialog and click Delete.
Deleting your cluster will not automatically delete the volume storage used for your Jenkins, and the volume will incur some fee. To delete it, access the volumes page on your Civo dashboard.
You might not see the Actions drop-down on your volume item if you access the page immediately after you delete your cluster. This is because the cluster deletion process is still ongoing. Wait for a few minutes and refresh the page. You should now see the drop-down. Click it and then click delete. A confirmation dialog will pop up. Copy your volume name, paste it into the name field, and click Delete.
With that, all the resources created for this tutorial have been deleted.
Summary
In this tutorial, you have learned how to install Jenkins in your Kubernetes cluster and make it accessible from outside the cluster. You have also created a very simple Jenkins job using your new Jenkins installation. Lastly, you have learned how data persistence works in your Jenkins installation and tested it by deleting your Jenkins pod.
If you are interested in learning more about this topic, check out some of these additional resources:
- Installing Jenkins on Kubernetes: This is the official guide on Jenkins docs on installing Jenkins on Kubernetes. It shows you multiple ways to do it, and by learning it this way, you can learn in detail how Jenkins installations on Kubernetes actually works.
- Kubernetes plugin for Jenkins: This plugin is automatically installed when you install Jenkins on Kubernetes. Behind the scenes, this plugin is responsible for allocating the Jenkins agent to execute your build.
- Kaniko: A tool to build container images inside a Kubernetes cluster. You might need to build a docker image in your CI/CD pipeline. While it's possible to run Docker inside a Jenkins pod, it's not a good practice from a security point of view. For this purpose, you can use Kaniko.