Deploy Jenkins On K8s With Helm

Hosting Jenkins on a Kubernetes Cluster is beneficial for Kubernetes-based deployments and dynamic container-based scalable Jenkins agents. Here, we see a step-by-step process for setting up Jenkins on a Kubernetes Cluster.

  • First Setup Jenkins On Kubernetes without helm

    • For Setting up a Jenkins Cluster on Kubernetes, we will do the following:

      1-Create a Namespace

      2-Create a service account with Kubernetes admin permissions.

      3-Create local persistent volume for persistent Jenkins data on Pod restarts.

      4-Create a deployment YAML and deploy it.

      5-Create a service YAML and deploy it.

Jenkins Kubernetes Manifest Files

   # Create a Namespace for Jenkins
   $ kubectl create namespace devops-tools
   # create the service account using kubectl
   $ kubectl apply -f serviceAccount.yaml          
  • Important Note: Replace worker-node01 with any one of your cluster worker nodes hostname
   # create the volume using kubectl
   $ kubectl create -f volume.yaml
   # Create the deployment using kubectl
   $ kubectl apply -f deployment.yaml
   # Check the deployment status.
   $ kubectl get deployments -n devops-tools
  • Note: Here, we are using the type as NodePort which will expose Jenkins on all kubernetes node IPs on port 32000. If you have an ingress setup, you can create an ingress rule to access Jenkins. Also, you can expose the Jenkins service as a Loadbalancer if you are running the cluster on AWS, Google, or Azure cloud.
   # Create the Jenkins service and map it to the deployment to Access Jenkins from outside.
   $ kubectl apply -f service.yaml
  • you will be able to access the Jenkins dashboard

    http://<node-ip>:32000
    
  • Jenkins will ask for the initial Admin password when you access the dashboard for the first time

   $ kubectl get pods --namespace=devops-tools
   $ kubectl logs $Jenkins_Pod_name --namespace=jenkins
   OR
   # run the exec command to get the password directly
   $ kubectl exec -it $Jenkins_Pod_name  cat  /var/jenkins_home/secrets/initialAdminPassword -n devops-tools

Second Deploy Jenkins On K8s using Helm V3

  • Install Helm To install Helm CLI, follow the instructions from the Installing Helm page
 * Configure Helm
  $ helm repo add jenkinsci https://charts.jenkins.io
  $ helm repo update
  $ helm search repo jenkinsci
* Create a volume which is called jenkins-pv
 $ kubectl apply -f jenkins-volume.yaml
 # Create a service account called jenkins
 $ kubectl apply -f jenkins-sa.yaml

Install Jenkins using Helm Charts

  • Open the jenkins-values.yaml file in your favorite text editor and modify the following

  • nodePort: Because we are using minikube we need to use NodePort as service type. Only cloud providers offer load balancers. We define port 32000 as port.

    • storageClass:
      storageClass: jenkins-pv
  • serviceAccount: the serviceAccount section of the jenkins-values.yaml file should look like this:
        serviceAccount:
          create: false
        # Service account name is autogenerated by default
        name: jenkins
        annotations: {}
  • Now you can install Jenkins by running the helm install command and passing it the following arguments:

    1- The name of the release jenkins

    2- The -f flag with the YAML file with overrides jenkins-values.yaml

    3- The name of the chart jenkinsci/jenkins

    4- The -n flag with the name of your namespace jenkins

$ chart=jenkinsci/jenkins
  helm install jenkins -n jenkins -f jenkins-values.yaml $chart
  • This outputs something similar to the following:
NAME: jenkins
LAST DEPLOYED: Wed Sep 16 11:13:10 2020
NAMESPACE: jenkins
STATUS: deployed
REVISION: 1
  • Get your 'admin' user password by running
printf $(kubectl get secret --namespace jenkins jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
  • Get the Jenkins URL to visit by running these commands in the same shell
jsonpath="{.spec.ports[0].nodePort}"
NODE_PORT=$(kubectl get -n jenkins -o jsonpath=$jsonpath services jenkins)
jsonpath="{.items[0].status.addresses[0].address}"
NODE_IP=$(kubectl get nodes -n jenkins -o jsonpath=$jsonpath)
echo http://$NODE_IP:$NODE_PORT/login

Reference