Jenkins CI/CD Pipeline Migration to Kubernetes for Enhanced Scalability (Part -1)
Abhijeet R. Katore ?
DevOps Engineer | CKA | CKAD | Terraform Certified | GCP ACE Certified
Scenario: Migrating a Jenkins CI/CD pipeline to Kubernetes to overcome scalability limits resulting from a growing number of clients. Using the Kubernetes plugin in Jenkins to run jobs as Kubernetes pods ensures adequate resources for the tasks. The deployment includes enabling Ingress to access the Jenkins UI, configuring persistent storage, and setting appropriate RBAC permissions for Jenkins to create Kubernetes pods. Confirm that Jenkins jobs run as Kubernetes pods.
This will be done in two parts. Part 1 includes:
- Jenkins deployment,
- Service creation, and
- Configuring persistent storage for Jenkins.
Part 2 will involve:
- Configuring RBAC permissions for the Jenkins executors,
- Installing the Kubernetes Plugin in Jenkins.
Steps to Deploy the Solution
Set Up Kubernetes Cluster
- Create a Kubernetes Cluster: Use a managed Kubernetes service like GKE, EKS, or AKS, or set up your own cluster using tools like kubeadm or minikube.
- Install kubectl: Ensure kubectl is installed and configured to interact with your Kubernetes cluster.
Install Jenkins on Kubernetes
- Create a Namespace for Jenkins:
k create ns jenkins
- Create a Deployment
We'll start by creating a simple Jenkins deployment using below imperative command:
k create deploy -n jenkins jenkins-deploy --image=jenkins/jenkins --dry-run=client -oyaml
The namespace is 'jenkins', ensuring that the Jenkins deployment resides within the 'jenkins' namespace.
Let's extract the YAML manifest from our imperative command and update it, ensuring correct pod selectors.
k create deploy -n jenkins jenkins-deploy --image=jenkins/jenkins --dry-run=client -oyaml > jenkins-deploy.yaml
and create using k create -f jenkins-deploy.yaml
Let's verify again, this time by checking the logs of the Jenkins pod.
k get -n jenkins po
NAME READY STATUS RESTARTS AGE
jenkins-deploy-7bb5bfd4f4-dgjw9 1/1 Running 0 11m
k logs -n jenkins jenkins-deploy-7bb5bfd4f4-dgjw9
This way we have ensured that our app is fully up and running.
Create a Service of type LoadBalancer? for Jenkins
Here our main goal will be to expose the main UI outside of the K8s Cluster, for us to interact with it
Lets create a Service of type LoadBalancer making the Jenkins server accessible through a web browser.
for simplification we'll use imperative command
领英推è
k expose -n jenkins deploy jenkins-deploy --port=8080 --target-port=8080 --type=LoadBalancer
The Jenkins server listens on port 8080. Therefore, the targetPort on the Service, which corresponds to the container port inside the Pod, also uses port 8080. Note that while the containerPort within the Pod and the targetPort of the Service are both set to 8080, they are terminologically different between the Service (svc) and Pod (pod) objects.
VOILA, our server is now in the running state!
fill the password from the logs and proceed with the installation.
But there's one more thing remaining to do: mounting a persistent volume to ensure data persistence, allowing new pods to continue work from where earlier ones left off, even after restarts.
Configure Persistent Storage
Create Persistent Volume and Persistent Volume Claim: Create a file named jenkins-pv-pvc.yaml with the following content:
Apply the PV and PVC configuration:
k apply -f jenkins-pv-pvc.yaml
Update Jenkins Deployment to Use PVC: Edit the jenkins-deployment to use the PVC:
spec:
volumes: #updated
- name: vol
persistentVolumeClaim:
claimName: volu
containers:
- image: jenkins/jenkins
name: jenkins
volumeMounts: # updated
- name: vol
mountPath: /var/jenkins_home
Part 1 concluded.
Note: If PV is on the host machine, one might face permission issues for the volume hostPath. For such cases, try to change the access of the provided path on the host machine.
Bonus: Creating multiple deployments with the same specifications except for the name. These deployments will utilize the same volume, and their pods will act as replicas. This is similar to scaling the same deployment by increasing the replica set count.
Here, I've kept the specifications identical except for the deployment names.
Let's create and see if it continues from where we left off or starts anew when we set up our Jenkins.
The behavior occurs because the Service routes traffic to pods that have labels matching its selector specification.