Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français
Lire en français

Jenkins on Kubernetes: installing with Helm and running a first pipeline

9 min read
Improve this page

jenkins logo

Jenkins is a self-hosted continuous integration server: a controller orchestrates pipelines described in a Jenkinsfile, and agents run them. This lesson installs it on Kubernetes with the official Helm chart, configures a controller without executors so that each build runs in an ephemeral pod, pins the plugins, then runs a first pipeline. Every command was run on 2 October 2026 on a kind cluster (Kubernetes 1.37), with chart 5.9.65, which deploys Jenkins 2.568.3.

What you will learn

  • Explain the role of the controller, the agents and the Jenkinsfile
  • Install Jenkins with Helm, pinning chart and plugins
  • Configure a controller without executors and ephemeral Kubernetes agents
  • Execute a first declarative pipeline and read its log
  • Recognise the security points specific to Jenkins

How is Jenkins organised?

Jenkins relies on a controller and agents architecture. The controller (formerly called "master") holds the configuration, the interface, the build history and the credentials; it decides which build goes to which agent. Agents run the steps: they are virtual machines installed once and for all (static agents) or pods created for a build then destroyed (dynamic agents).

The controller and its agents communicate over SSH, over WebSocket or over the "inbound" protocol on TCP port 50000, the one used by the official chart's Kubernetes agents. Pipelines are described in a Jenkinsfile file, versioned with the code, written in declarative syntax (pipeline, stages, steps directives) or scripted syntax (free-form Groovy). Prefer declarative: more readable, it is validated before running.

Plugins and credentials

Almost every Jenkins feature comes from plugins: Git integration, Kubernetes agents, pipelines, configuration as code. It is its strength and its main attack surface: an unmaintained plugin remains privileged code running on the controller. Choose them on the plugins site, which flags versions carrying security advisories, and keep them to a minimum.

Credentials (passwords, tokens, SSH keys) are stored encrypted on the controller and injected into pipelines by their ID, never in clear text in the Jenkinsfile. That is one more reason to never run a build on the controller: a build running there has access to its file system, and therefore to these secrets.

Installing Jenkins on Kubernetes with Helm

The official jenkins/jenkins chart deploys the controller in a StatefulSet, with a persistent volume for its configuration, and sets up out of the box a Kubernetes "cloud" that knows how to create agent pods. You need a Kubernetes cluster, kubectl and helm; a local kind cluster is enough to learn.

Preparing the values

The values file below makes two security choices. numExecutors: 0 removes every executor from the controller: each build will go to an agent. And each plugin is pinned to a precise version, in name:version format, so that two installations give exactly the same Jenkins. Without a version, the chart installs the latest one published at deployment time.

jenkins-values.yaml
controller:
numExecutors: 0 # no build on the controller
installPlugins:
- kubernetes:4557.ve746270f672f
- workflow-aggregator:608.v67378e9d3db_1
- git:5.10.1
- configuration-as-code:2131.vb_a_13ed96f755

These four plugins pull in others as dependencies: the tested installation had 68 in total. The chart's init container verifies the checksum of each downloaded plugin, which shows in its logs (Setting checksum for: kubernetes).

Deploying the chart

Add the chart repository, then install while pinning the chart version with --version. Chart 5.9.65 in turn sets the controller image, jenkins/jenkins:2.568.3-jdk21. The --wait option only returns once the controller is ready.

Terminal window
helm repo add jenkins https://charts.jenkins.io
helm repo update jenkins
helm upgrade --install jenkins jenkins/jenkins --version 5.9.65 \
--namespace jenkins --create-namespace \
-f jenkins-values.yaml --wait --timeout 10m

The controller reaches 2/2 in under a minute on the test cluster: one container for Jenkins, a second that reloads the configuration as code. The chart also creates two Services, the interface on port 8080 and the agent channel on port 50000.

Terminal window
kubectl get pods,svc -n jenkins
NAME READY STATUS RESTARTS AGE
pod/jenkins-0 2/2 Running 0 47s
NAME TYPE CLUSTER-IP PORT(S)
service/jenkins ClusterIP 10.96.53.132 8080/TCP
service/jenkins-agent ClusterIP 10.96.172.48 50000/TCP

Logging in

The admin user's password, generated at installation, is read from the jenkins Secret. To reach the interface without an ingress, a port-forward is enough; in production, Jenkins goes behind an HTTPS ingress. The X-Jenkins response header gives the version actually served.

Terminal window
kubectl get secret jenkins -n jenkins \
-o jsonpath='{.data.jenkins-admin-password}' | base64 -d; echo
kubectl port-forward -n jenkins svc/jenkins 8080:8080

The interface then answers on http://127.0.0.1:8080. Change this initial password, or better, connect Jenkins to your company directory through configuration as code: a shared admin account is the first flaw found in Jenkins audits.

Running a first pipeline

A declarative pipeline describes stages that contain steps. This one has two, build and test, each with a single echo step. agent any lets Jenkins choose an agent: since the controller has no executor, it provisions one in Kubernetes.

pipeline {
agent any
stages {
stage('build') {
steps {
echo 'First stage'
}
}
stage('test') {
steps {
echo 'Second stage'
}
}
}
}

In the interface, create an item of type Pipeline ("New Item"), then paste this script, or point the configuration at the Git repository holding the Jenkinsfile, with a read-only access credential. Then start a build. The console log shows the agent created for the occasion:

Agent default-3kfr0 is provisioned from template default
Running on default-3kfr0 in /home/jenkins/agent/workspace/premier-pipeline
[Pipeline] { (build)
[Pipeline] echo
First stage
[Pipeline] { (test)
[Pipeline] echo
Second stage
Finished: SUCCESS

During the build, a default-… pod appears in the jenkins namespace; a few seconds after the end, it has disappeared and only jenkins-0 remains. The build ran on an ephemeral agent and nothing persists from one run to the next. With a controller that keeps its executors, the same line would show Running on Jenkins, that is, on the controller itself.

Securing your Jenkins

Jenkins is a self-hosted server: its security depends entirely on how you operate it. Four rules cover the essentials. No build on the controller, as above. Few plugins, pinned and updated as the project publishes security advisories. A configuration described as code, with the configuration-as-code plugin, so that a Jenkins can be rebuilt identically instead of being tuned by hand.

The fourth rule concerns updates: the chart, the controller image and the plugins evolve fast, and a Jenkins nobody dares update any more becomes the untouchable pipeline described in the lesson Why CI/CD pipelines fail. Plan upgrades as a regular task, tested on a disposable cluster before production.

Key points

  • The controller orchestrates, the agents execute; a pipeline is described in a declarative Jenkinsfile, versioned with the code.
  • The official Helm chart is installed while pinning its version (--version 5.9.65), which sets the jenkins/jenkins:2.568.3-jdk21 image.
  • numExecutors: 0 forbids any build on the controller: each build goes to an ephemeral pod destroyed at the end.
  • Plugins are pinned in name:version format, otherwise two installations diverge.
  • The initial password is read from the jenkins Secret and is replaced as soon as possible by company authentication.
  • Minimal plugins, configuration as code and regular updates make up most of a Jenkins' security.

Knowledge check

Check that the essentials of this lesson are in place. The questions only cover what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn