DEV Community

Cover image for Deploying Jenkins on Kubernetes using Helm
Oloruntobi Olurombi
Oloruntobi Olurombi

Posted on

Deploying Jenkins on Kubernetes using Helm

This article walks through creating and deploying a custom Helm chart to deploy Jenkins on Kubernetes. Helm is a package manager for Kubernetes, which helps automate the deployment of applications by packaging them into charts. Helm simplifies application deployment by managing Kubernetes resources as a single unit.

The deployment involves creating a Helm chart, defining the necessary configurations, deploying Jenkins, and accessing the Jenkins console through the web browser.

Why Helm?

Helm streamlines Kubernetes application deployments by:

  • Packaging Kubernetes resources: Helm charts contain all the manifests required to deploy an application, allowing easier management and updates.

  • Version control: Helm maintains release versions, making it easy to upgrade or rollback applications.

  • Customisation: Helm charts allow parameterisation, so you can use the same chart to deploy different instances of the same application by tweaking configuration values.

  • Repeatability: Helm makes it easy to deploy applications consistently across multiple environments.

Step 1: Creating a Helm Chart

To begin, we will create a Helm chart called myhelmchart that will deploy Jenkins.

helm create myhelmchart
Enter fullscreen mode Exit fullscreen mode

This command generates a directory structure with the basic files and templates needed for a Kubernetes deployment. Let’s break down the structure of the generated chart:

Helm Chart Directory Structure

  • Chart.yaml: Defines the metadata of the Helm chart, such as the chart name, version, and appVersion (version of the deployed application).

  • values.yaml: Default values that the chart uses, such as image name, ports, and service type. These values can be overridden during installation.

  • templates/: Contains the Kubernetes manifests (YAML files) for deployments, services, and other Kubernetes resources.

  • NOTES.txt: Provides instructions after a chart is installed.

Step 2: Update Chart.yaml

Next, update Chart.yaml to specify the Jenkins version we want to deploy:

cd myhelmchart
vim Chart.yaml
Enter fullscreen mode Exit fullscreen mode

Modify the appVersion field to reflect the Jenkins version:

appVersion: "2.249.2"
Enter fullscreen mode Exit fullscreen mode

Step 3: Clean Up Unnecessary Files

We will delete unnecessary files and directories to simplify our Helm chart:

rm -rf templates/*.yaml templates/tests
Enter fullscreen mode Exit fullscreen mode

Step 4: Create Deployment and Service Manifests

In the templates/ directory, create two files: one for the Jenkins deployment and one for the service.

1. Create Jenkins Deployment Manifest

cd templates
touch jenkins-deployment.yaml
vim jenkins-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Add the following code to jenkins-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "myhelmchart.fullname" . }}
  labels:
    app: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
        - name: jenkins
          image: {{ printf "%s:%s" .Values.image.repository .Values.image.tag | quote }}
          env:
            - name: JENKINS_USERNAME
              value: {{ default "test" .Values.jenkinsUsername | quote }}
            - name: JENKINS_PASSWORD
              {{- if .Values.jenkinsPassword }}
              value: {{.Values.jenkinsPassword }}
              {{- else }}
              value: testPassword
              {{- end }}
          ports:
            {{- range .Values.containerPorts }}
            - name: {{ .name }}
              containerPort: {{ .port }}
            {{- end }}
Enter fullscreen mode Exit fullscreen mode

This manifest defines a Deployment with the following key elements:

  • metadata: Specifies the name and labels for the deployment.

  • spec.replicas: Ensures there is only one replica (Jenkins instance) running.

  • spec.template: Describes the pod template with metadata and containers. It sets environment variables JENKINS_USERNAME and JENKINS_PASSWORD from the chart’s values.yaml file, with default values if not provided.

  • containers: Defines the Jenkins container, using the image specified in values.yaml, and exposes ports from the same file.

2. Create Jenkins Service Manifest

touch jenkins-service.yaml
vim jenkins-service.yaml
Enter fullscreen mode Exit fullscreen mode

Add the following content to jenkins-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: {{ template "myhelmchart.fullname" . }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - name: http
      port: 8080
      targetPort: http
      nodePort: {{ .Values.service.nodePort }}
  selector:
    app: jenkins
Enter fullscreen mode Exit fullscreen mode

This manifest defines a Service to expose the Jenkins pod:

  • spec.type: Sets the service type to NodePort, which exposes the application on a specific port of the node (EC2 instance).

  • ports: Maps port 8080 of the Jenkins pod to a NodePort specified in values.yaml.

  • selector: Ensures the service targets pods labeled with app: jenkins.

Step 5: Update NOTES.txt

The NOTES.txt file provides information after a successful Helm installation. Let’s update it:

echo “This is my first chart” > NOTES.txt
Enter fullscreen mode Exit fullscreen mode

Step 6: Update values.yaml

The values.yaml file stores default values used by the templates. Update it with the following configuration:

image:
  repository: bitnami/jenkins
  tag: latest

jenkinsUsername: ""
jenkinsPassword: ""

containerPorts:
  - name: http
    port: 8080

service:
  type: NodePort
  nodePort: 30080
Enter fullscreen mode Exit fullscreen mode

This configuration:

  • image.repository: Uses the official Bitnami Jenkins image.

  • jenkinsUsername and jenkinsPassword: Default values can be passed during installation.

  • service: Sets the service type to NodePort, exposing Jenkins on port 30080.

Step 7: Run the Helm Template Command

Before installing the chart, verify the templates using the helm template command, which renders the Kubernetes manifests without applying them:

helm template myhelmchart . -s templates/jenkins-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Step 8: Install the Helm Chart

Now install the Helm chart using the helm install command:

helm install myhelmchart ./myhelmchart
Enter fullscreen mode Exit fullscreen mode

This deploys Jenkins to your Kubernetes cluster.

Step 9: Get Public IP of the Node and Access Jenkins

To access Jenkins via the web browser, we need the public IP of the node (EC2 instance) hosting the Jenkins pod.

  1. Get the public IP of the node:
kubectl get nodes -o wide
Enter fullscreen mode Exit fullscreen mode

Look for the external/public IP address of the node that the Jenkins pod is running on.

  1. Access Jenkins in the browser:

Open your web browser and navigate to:

http://<Public_IP>:30080
Enter fullscreen mode Exit fullscreen mode

Image description

Step 10: Access Jenkins Console

When you access Jenkins in the browser, it will prompt you for a username and password. Use the credentials set in your Helm chart:

  • Username: The value of jenkinsUsername (or test if not set).

  • Password: The value of jenkinsPassword (or testPassword if not set).

Once you log in, you’ll have access to the Jenkins dashboard.

Image description

Conclusion

In this article, we created a Helm chart to deploy Jenkins on Kubernetes, customised the chart with a deployment and service manifest, and accessed Jenkins via a browser. Helm makes managing Kubernetes applications more efficient by providing easy-to-use templates and a simple installation process.

☕️ If this article helped you avoid a tech meltdown or gave you a lightbulb moment, feel free to buy me a coffee! It keeps my code clean, my deployments smooth, and my spirit caffeinated. Help fuel the magic here!.

Happy deploying!

Top comments (0)