Introduction
Jenkins is a continuous integration tool that automates a large portion of the software development process. Several development teams working on multiple projects in a complex microservices environment can put a strain on limited resources. Jenkins helps you deliver a flawless final product on schedule.
A Kubernetes cluster adds a new automation layer to Jenkins. Kubernetes makes sure that resources are used effectively and that your servers and underlying infrastructure are not overloaded.
This tutorial will show you how to install Jenkins on a Kubernetes cluster.
Prerequisites
- Access to a command line/terminal
- Kubernetes cluster
- A fully configured kubectl command-line tool on your local machine
Installing Jenkins on Kubernetes Cluster
Kubernetes' ability to orchestrate container deployment ensures that Jenkins always has the right amount of resources available. The example below shows you how to use a set of YAML files to install Jenkins on a Kubernetes cluster. The YAML files are easily tracked, edited, and can be reused indefinitely.
Note: The YAML files in this article illustrate the Jenkins deployment process. They should not be used in a production environment without modifying them to accommodate your clusters' specific settings and network resources.
Create a Namespace for the Jenkins Deployment
A distinct namespace provides an additional layer of isolation and more control over the continuous integration environment. Create a namespace for the Jenkins deployment by typing the following command in your terminal:
kubectl create namespace jenkins
The name of the namespace should be a DNS compatible label. This example uses the name jenkins.
Use the following command to list existing namespaces:
kubectl get namespaces
The output confirms that the jenkins namespace was created successfully.
Create a Service Account
Service accounts provide identities that are used to control pod processes. Use a text editor to create a YAML file where you will store the service account declarations:
nano sa-jenkins.yaml
The file defines the cluster role with administrative permissions. It also creates a new service account named admin
and binds it with the previously defined cluster role.
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: admin
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: ServiceAccount
name: admin
namespace: jenkins
Save the file and exit. Apply the configuration with kubectl apply
.
kubectl apply -f sa-jenkins.yaml
Note: Learn about the key differences between Jenkins and Kubernetes.
Create Jenkins Persistent Volume and Persistent Volume Claim
The role of a persistent volume is to store basic Jenkins data and preserve it beyond the lifetime of a pod. Create a YAML file that will define storage-related components of the deployment:
nano volume-jenkins.yaml
In the first section, the file declares the local-storage
storage class. The second section defines the jenkins-pv
persistent volume, while the third creates a persistent volume claim jenkins-pvc
that will be bound to the jenkins-pv
volume.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-pv
labels:
type: local
spec:
storageClassName: local-storage
claimRef:
name: jenkins-pvc
namespace: jenkins
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
local:
path: /mnt
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- minikube
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
storageClassName: local-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Note: The values
item in the nodeAffinity
section should provide the name of the node Jenkins will use. The example above uses minikube, so the name of the node is minikube
.
Save the file and exit. Next, apply the file.
kubectl apply -f volume-jenkins.yaml
Create and Apply Jenkins Deployment File
Create a YAML file to store Jenkins deployment information.
nano deploy-jenkins.yaml
The deployment file in this example utilizes the jenkins/jenkins:lts Docker image and creates 1 replica that is going to be exposed on port 8080.
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins-server
template:
metadata:
labels:
app: jenkins-server
spec:
securityContext:
fsGroup: 1000
runAsUser: 1000
serviceAccountName: admin
containers:
- name: jenkins
image: jenkins/jenkins:lts
resources:
limits:
memory: "2Gi"
cpu: "1000m"
requests:
memory: "500Mi"
cpu: "500m"
ports:
- name: httpport
containerPort: 8080
- name: jnlpport
containerPort: 50000
livenessProbe:
httpGet:
path: "/login"
port: 8080
initialDelaySeconds: 90
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 5
readinessProbe:
httpGet:
path: "/login"
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- name: jenkins-data
mountPath: /var/jenkins_home
volumes:
- name: jenkins-data
persistentVolumeClaim:
claimName: jenkins-pvc
The volumeMounts
section of the file mounts the persistent volume created in the previous step. The livenessProbe
and readinessProbe
sections declare probes that restart failed pods and detect when pods are ready.
Exit the file and save the changes. Use the newly created file to deploy Jenkins:
kubectl apply -f deploy-jenkins.yaml
Create and Apply Jenkins Service File
A Kubernetes Service is an abstraction that exposes Jenkins to the wider network. It allows us to maintain a persistent connection to the pod regardless of the changes taking place within the cluster.
Create a YAML file in which you will define the service:
nano service-jenkins.yaml
Add the following content:
apiVersion: v1
kind: Service
metadata:
name: jenkins-svc
namespace: jenkins
annotations:
prometheus.io/scrape: 'true'
prometheus.io/path: /
prometheus.io/port: '8080'
spec:
selector:
app: jenkins-server
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 44000
Save the file and exit. Now create the service by typing:
kubectl apply -f jenkins-service.yaml
You can now access the Jenkins dashboard.
Note: Check out our detailed Jenkins tutorial to learn everything you need to know about using Jenkins.
Access Jenkins Dashboard
Before you proceed to start Jenkins, check if all the components you deployed are working as intended. Use the kubectl get all
command and specify the correct namespace:
kubect get all -n jenkins
The example shows a properly functioning deployment:
- The pod is marked as
READY
andRunning
. - The service's Cluster IP and ports have been successfully allocated.
- The deployment is marked as
READY
andAVAILABLE
. - The desired number of replicas (1) has been reached.
Go to your browser and access the node by using its IP address and the port you defined in the service file. If you don't know the IP address of your node, find it in the output of the following command:
kubectl get nodes -o yaml
The node IP address is located in the status
section of the output.
Using the information from the example, the address of the Jenkins dashboard is:
http://192.168.49.2:44000
To access Jenkins, you initially need to enter your credentials. The default username for new installations is admin.
To obtain the password:
1. Find the name of the pod in the output of the kubectl get all
command above.
Note: Alternatively, find the name of the pod in the output of the following command:
kubectl get pods -n jenkins
2. Once you locate the name of the pod, use it to access the pod’s logs.
kubectl logs jenkins-56c9d59dc-pv8kc --namespace jenkins
3. Find the password at the end of the log, formatted as a long alphanumerical string.
You have successfully installed Jenkins on your Kubernetes cluster and can use it to create new and efficient development pipelines.
Note: Sometimes, you will need to restart Jenkins while troubleshooting or installing plugins. Refer to our article How to Restart Jenkins Manually to learn more.
Conclusion
Now you know how to install Jenkins on a Kubernetes cluster. Jenkins can automate many tasks and help developers submit code efficiently and consistently. Jenkins on Kubernetes, combined with the cloud agility of Bare Metal Cloud, can help you fully automate your workflow and improve the speed and quality of your software.