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

  1. Install the Kubernetes plugin from Manage Jenkins and Plugins.
  2. Open Manage Jenkins, then Clouds, and add a new Kubernetes cloud.
  3. Enter the cluster API address, or leave it blank when Jenkins already runs inside the cluster.
  4. Add a credential that grants access to create pods.
  5. Set the Jenkins URL that pods use to reach the controller.
  6. 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

BenefitMeaning
Clean buildsEvery build gets a new pod, so leftovers never affect results
Elastic capacityFifty builds at once create fifty pods, and zero builds create none
Tool freedomEach project picks its own images and versions
Cost controlYou 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-namespace

Read 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

SymptomLikely Cause
Build waits for an agent foreverPod cannot schedule because the cluster lacks free resources
Agent pod starts then disconnectsWrong Jenkins URL or blocked network path to the controller
ImagePullBackOff statusImage name typo or missing registry credentials
Builds feel slowEmpty 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.