Jenkins on Kubernetes
Fixed build servers sit idle at night and choke during busy mornings. Kubernetes solves both problems. Jenkins can create a fresh build machine for every job, use it for a few minutes, and delete it. Capacity grows and shrinks with demand, and every build starts from a clean slate.
The Layman's View
Compare a permanent office with a coworking space. A permanent office costs money all month, even when half the desks stay empty. A coworking space gives you a desk when you arrive and takes it back when you leave. Kubernetes agents work like coworking desks: Jenkins books one per build and releases it afterwards.
How It Works
+-------------------+ 1. build starts
| Jenkins |------------------------+
| Controller | |
+-------------------+ v
^ +--------------------+
| | Kubernetes API |
| 3. agent connects +--------------------+
| |
| 2. creates a pod |
| v
| +--------------------+
+--------------------------| Agent Pod |
| jnlp + tool |
| containers |
+--------------------+
|
4. build finishes,
pod is deleted
A pod is the smallest unit in Kubernetes. It holds one or more containers that share a network and storage. The agent pod includes a connector container, which links to Jenkins, plus any tool containers that your build needs.
Setting Up the Connection
- Install the Kubernetes plugin from Manage Jenkins and Plugins.
- Open Manage Jenkins, then Clouds, and add a new Kubernetes cloud.
- Enter the cluster API address, or leave it blank when Jenkins already runs inside the cluster.
- Add a credential that grants access to create pods.
- Set the Jenkins URL that pods use to reach the controller.
- Press Test Connection and confirm a success message.
Defining Agents in a Pipeline
The simplest approach describes the pod directly in the Jenkinsfile using YAML.
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.9-eclipse-temurin-17
command: ['sleep']
args: ['99d']
- name: node
image: node:20
command: ['sleep']
args: ['99d']
'''
}
}
stages {
stage('Java Build') {
steps {
container('maven') {
sh 'mvn -B package'
}
}
}
stage('Frontend Build') {
steps {
container('node') {
sh 'npm ci && npm run build'
}
}
}
}
}Each container brings its own tools. The pipeline needs no Maven or Node installation on any server. The container step selects where each command runs.
Benefits in Plain Words
| Benefit | Meaning |
|---|---|
| Clean builds | Every build gets a new pod, so leftovers never affect results |
| Elastic capacity | Fifty builds at once create fifty pods, and zero builds create none |
| Tool freedom | Each project picks its own images and versions |
| Cost control | You pay for compute only while builds run |
Resource Requests and Limits
Pods compete for CPU and memory. Declare what each container needs so Kubernetes places the pod on a suitable node.
- name: maven
image: maven:3.9-eclipse-temurin-17
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "3Gi"Requests reserve capacity. Limits cap usage, which protects other workloads from a runaway build.
Caching Dependencies
Fresh pods start with empty caches, so each build downloads libraries again. Mount a persistent volume claim at the cache folder, such as /root/.m2, to share downloads across builds. Many teams run a local mirror of Maven Central inside the cluster for the same reason.
Running Jenkins Itself on Kubernetes
The official Helm chart installs the Jenkins controller in a cluster with one command. Store the Jenkins home folder on a persistent volume, so job history and settings survive pod restarts.
helm repo add jenkins https://charts.jenkins.io
helm repo update
helm install jenkins jenkins/jenkins --namespace ci --create-namespaceRead the chart notes after installation for the admin password command and the service address.
Security Practices
- Create a dedicated namespace for build pods.
- Give the Jenkins service account only the rights it needs, such as creating and deleting pods in that namespace.
- Avoid privileged containers unless a build truly requires them.
- Pull images from a trusted registry and pin versions.
- Store secrets in Kubernetes secrets or Jenkins credentials, never in the YAML.
Troubleshooting
| Symptom | Likely Cause |
|---|---|
| Build waits for an agent forever | Pod cannot schedule because the cluster lacks free resources |
| Agent pod starts then disconnects | Wrong Jenkins URL or blocked network path to the controller |
| ImagePullBackOff status | Image name typo or missing registry credentials |
| Builds feel slow | Empty caches or small resource requests |
Run kubectl get pods and kubectl describe pod during a build to watch agents appear and vanish. That live view makes the model easy to grasp.
