In the previous article, we discussed how to Setup self-hosted Gitea private repository on a Kubernetes cluster. This article will discuss how to install Jenkins server on a Kubernetes/OpenShift cluster.

Kubernetes/OpenShift adds an additional automation layer on Jenkins server which in turn makes sure that the resources allocated to the Jenkins deployment are efficiently utilized. This means that with the use of an orchestration layer such as Kubernetes/OpenShift, resources can be scaled up/down depending on consumption/usage.

This article will discuss the available methods of setting up Jenkins server on a Kubernetes/OpenShift cluster.

Install Jenkins on Kubernetes using Helm3

In our guide we assume that you have a fully fuctional Kubernetes/OpenShift cluster. You also need access to the control plane either natively or remote.

Helm is a package manager for Kubernetes/OpenShift that packages deployments in a format called chat. The installation of Helm3 is covered in the article below

Install and Use Helm 3 on Kubernetes Cluster

Step 1. Create Jenkins namespace

Create the jenkins namespace that will be used for this deployment.

kubectl create ns jenkins

Once you have Helm3 installed, add Jenkins repo to your environment

$ helm repo add jenkinsci https://charts.jenkins.io
$ helm repo update

Step 2. Create a Persistent Volume

Once the Jenkins repo is added, we need to configure a persistent volume since Jenkins is a stateful application and needs to store persistent data on a volume.

Creating Persistent Volume from Host Path

Create a PersistentVolume on your Kubernetes cluster:

$ vim jenkins-localpv.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: jenkins-sc
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
  labels:
    type: local
spec:
  storageClassName: jenkins-sc
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
spec:
  storageClassName: jenkins-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Apply the configuration

kubectl apply -f jenkins-localpv.yaml

The above command creates a persistent volume and persistentVolumeClaim using hostPath. The volume will be saved at /mnt path of the node.

Dynamic Persistent Volume creation using StorageClass

If you have any StorageClass provided by a custom storage solution, create new file called jenkins-pvc.yaml

vim jenkins-pvc.yaml

Modify below configuration to provide StorageClass name:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: storage-class-name
  resources:
    requests:
      storage: 10Gi

Then apply the configuration after modification:

kubectl apply -f jenkins-pvc.yaml

Using openEBS Storage

You can use dynamic storage provisioning using tools such as openEBS and provision storageClasses.

For dynamic storage, create a storageClass config:

$ vim jenkins-sc.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: jenkins-sc
  annotations:
    openebs.io/cas-type: jiva
    cas.openebs.io/config: |
      - name: ReplicaCount
        value: "2"
      - name: StoragePool
        value: gpdpool
provisioner: openebs.io/provisioner-iscsi

Apply the configuration

kubectl apply -f jenkins-sc.yaml

Create a persistenVolume and PersistenVolumeClaim based on the above storageClass

$ vim  dynamic-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
  labels:
    type: local
spec:
  storageClassName: jenkins-sc
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data/jenkins-volume"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
spec:
  storageClassName: jenkins-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Apply the configuration

kubectl apply -f dynamic-pv.yaml

More about persistent volumes on Kubernetes/OpenShift has been covered on the article below:

Deploy and Use OpenEBS Container Storage on Kubernetes

Step 3. Create a service account

Create a service account for the pods to communicate with ther API server. We will also create the ClusterRole and the permissions.

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: jenkins
rules:
- apiGroups:
  - '*'
  resources:
  - statefulsets
  - services
  - replicationcontrollers
  - replicasets
  - podtemplates
  - podsecuritypolicies
  - pods
  - pods/log
  - pods/exec
  - podpreset
  - poddisruptionbudget
  - persistentvolumes
  - persistentvolumeclaims
  - jobs
  - endpoints
  - deployments
  - deployments/scale
  - daemonsets
  - cronjobs
  - configmaps
  - namespaces
  - events
  - secrets
  verbs:
  - create
  - get
  - watch
  - delete
  - list
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
  - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:serviceaccounts:jenkins
EOF

Step 4. Install Jenkins on Kubernetes

Download the Jenkins chart and make some modifications before the deployment.

wget https://raw.githubusercontent.com/jenkinsci/helm-charts/main/charts/jenkins/values.yaml

Open the downloaded values.yaml file with your favorite text editor and make the changes below.

  • Modify the storage class. In this guide, I have used a storage class called jenkins-sc. You might as well use your own storage class. Locate the storageClass field in the file and modify it adding the storageClass.
storageClass: jenkins-sc
  • Edit the serviceAccount entries to look as below:
serviceAccount:
create: false
# Service account name is autogenerated by default
name: jenkins
annotations: {}
  • Modify the serviceType to NodePort. You can also use loadbalancer if your environment supports that.
servicePort: 8080
  targetPort: 8080
  # For minikube, set this to NodePort, elsewhere use LoadBalancer
  # Use ClusterIP if your setup includes ingress controller
  serviceType: NodePort
  # Jenkins controller service annotations

Finally install the Jenkins chart by running the command below:

$ chart=jenkinsci/jenkins
$ helm install jenkins -n jenkins -f values.yaml $chart

Verify that the deployment is up and running

$ kubectl get pods -n jenkins

Step 5. Access Jenkins dashboard

When the pods deploy successfully and are running. The next thing is to access the web interface. But first, we need to retrieve the login details.

Obtain Jenkins password

Run the commands below to obtain the jenkins password:

jsonpath="{.data.jenkins-admin-password}"
secret=$(kubectl get secret -n jenkins jenkins -o jsonpath=$jsonpath)
echo $(echo $secret | base64 --decode)

You will get an output similar to this below from decoding the secret

$ echo $(echo $secret | base64 --decode)
szxbmmqutyA4gtRaBDAQeC

Obtain Jenkins Login URL

Obtain the Jenkins URL by checking the port your deployment is exposed to via NodePort

kubectl get svc -n jenkins

Sample output:

$ kubectl get svc -n jenkins
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
jenkins         NodePort    10.233.35.23    <none>        8080:30375/TCP   20m
jenkins-agent   ClusterIP   10.233.14.243   <none>        50000/TCP        20m

From the above, we can tell that the service is running on port 30375. We can access the Jennkins server via http://worker-node-ip:NodePort/login.

To get the details of your worker nodes:

$ kubectl get nodes -o wide
NAME     STATUS   ROLES                  AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION    CONTAINER-RUNTIME
node01   Ready    control-plane,master   25d   v1.21.1   172.20.5.220   <none>        Debian GNU/Linux 10 (buster)   4.19.0-16-amd64   docker://20.10.7
node02   Ready    <none>                 25d   v1.21.1   172.20.5.221   <none>        Debian GNU/Linux 10 (buster)   4.19.0-16-amd64   docker://20.10.7
node03   Ready    <none>                 25d   v1.21.1   172.20.5.222   <none>        Debian GNU/Linux 10 (buster)   4.19.0-16-amd64   docker://20.10.7

In my case my login details will be: http://172.20.5.221:30375/login. Note that you can use any node IP to access the web interface.

setup jenkins on kubernetes openshift

Login with the username admin and the password we obtained in the commands above.

setup jenkins on kubernetes openshift1

Manually Install Jenkins using YAML File

You can manually install Jenkins using a few simple steps with YAML configuration files.

Create Jenkins deployment file

$ vim jenkins-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts-jdk11
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: jenkins-home
          mountPath: /var/jenkins_home
      volumes:
        - name: jenkins-data
          persistentVolumeClaim:
              claimName: jenkins-pvc

Apply the deployment:

$ kubectl apply -f jenkins-deploy.yaml

Create Jenkins service:

$ vim jenkins-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: jenkins
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
  selector:
    app: jenkins

Apply the service

kubectl apply -f jenkins-service.yaml

Verify that the deployment has been successful

kubectl get deploy -n jenkins

Check the services created

kubectl get svc -n jenkins

Sample output:

$ kubectl get svc -n jenkins
jenkins                     NodePort       10.233.45.90    <none>        8080:30793/TCP               21d

Access Jenkins Dashboard

After the above steps the next step will be to access Jenkins on a web interface.

You can access the dashboard via http://worker-nodeIP:nodePort

how to setup jenkins on kubernetes

To get past the above interface, we need to obtain a first-time password provided in the Jenkins pod logs. We therefore need to identify the name of the pod and get the logs.

$ kubectl get pods -n jenkins
NAME                       READY   STATUS    RESTARTS   AGE
jenkins-585799558b-mhfbb   1/1     Running   0          49m

We can then get the logs of the pod.

$ kubectl logs jenkins-585799558b-mhfbb -n jenkins

Trace in the logs for the part that looks like this below:

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

bc174736af3a48ac9796c749e43f119c

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************

We can then use the password identified in the logs to get past the first screen.

You will then be required to install plugins for Jenkins. You can opt to install the suggested plugins or customize those that you need.

how to setup jenkins on kubernetes2

The installation of plugins takes sometime to complete

setup jenkins on kubernetes

You will then be required to setup an admin user:

setup jenkins on kubernetes4

You will then be asked to provide a Jenkins URl. In this case, use the worker-node URL or IP and the NodePort for the url as shown below:

setup jenkins on kubernetes 5

This is the last step as the next interface is a confirmation that the installation has been successful.

setup jenkins on kubernetes 6

Click on “Start Using Jenkins” to be redirected to the Jenkins dashboard.

setup jenkins on kubernetes6 1

Video Courses For Learning Jenkins:

Conclusion

At this point, Jenkins is ready to be used. We have setup persistent volume for data storage incase the pods are rescheduled. You can now proceed with your CI/CD practices using Jenkins on Kubernetes/OpenShift.

Cheers and please have a look on other interesting articles on this website.

How To Install Jenkins on Rocky Linux 8

Install and Configure Gitea Git Service on Kubernetes / OpenShift

Deploy and Use OpenEBS Container Storage on Kubernetes

Install Gitea self-hosted Git service on CentOS with Nginx Reverse Proxy

Your support is our everlasting motivation,
that cup of coffee is what keeps us going!


As we continue to grow, we would wish to reach and impact more people who visit and take advantage of the guides we have on our blog. This is a big task for us and we are so far extremely grateful for the kind people who have shown amazing support for our work over the time we have been online.

Thank You for your support as we work to give you the best of guides and articles. Click below to buy us a coffee.

LEAVE A REPLY

Please enter your comment!
Please enter your name here