Jenkins agents running as Kubernetes pods are ephemeral, on-demand compute resources that spin up and down as needed to execute build jobs, dramatically increasing scalability and efficiency.
Let’s see this in action. Imagine a Jenkinsfile that needs to build a Docker image.
pipeline {
agent {
kubernetes {
label 'docker-build'
yaml """
apiVersion: v1
kind: Pod
metadata:
name: jenkins-agent-docker
spec:
containers:
- name: build
image: docker:latest
command: ['sleep']
args: ['infinity']
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
"""
}
}
stages {
stage('Build Docker Image') {
steps {
container('build') {
sh 'docker build -t my-app:latest .'
}
}
}
}
}
When this pipeline starts, Jenkins’ Kubernetes plugin communicates with the Kubernetes API server. It requests a pod matching the label 'docker-build' and uses the provided yaml to define its structure. The docker:latest image is pulled, and the container starts, sleeping indefinitely. The crucial part here is the volumeMounts section, which maps the host’s Docker socket (/var/run/docker.sock) into the pod. This allows the container running inside the pod to communicate with the Docker daemon on the Kubernetes node, enabling it to build Docker images.
Once the pod is running, Jenkins schedules the Build Docker Image stage. It targets the container named build within the pod. The sh 'docker build -t my-app:latest .' command is executed inside this container. Because the Docker socket is mounted, the docker build command successfully interacts with the host’s Docker daemon, building the my-app:latest image. After the build stage completes, Jenkins can then terminate the pod, freeing up resources.
The problem this solves is the traditional bottleneck of fixed build agent infrastructure. With static agents, you either over-provision and waste resources, or under-provision and face long build queues. Kubernetes agents provide elastic scalability. You define the agent’s requirements in the agent block (e.g., specific container images, environment variables, volumes), and Kubernetes handles the provisioning and de-provisioning.
Internally, the Jenkins Kubernetes plugin acts as a controller. It watches for build jobs that require Kubernetes agents. When a job starts, it translates the agent { kubernetes { ... } } block into a Kubernetes Pod specification. This specification is then submitted to the Kubernetes API. The plugin also monitors the status of these pods. When a pod becomes ready, Jenkins connects to it and executes the build steps. Upon job completion or failure, the plugin can be configured to clean up (delete) the pod, ensuring resources are released.
The yaml block within the kubernetes agent is powerful. It allows you to define any valid Kubernetes Pod spec. This means you can specify multiple containers, sidecars for logging or artifact archiving, specific resource requests/limits (resources: { requests: { cpu: "500m", memory: "1Gi" } }), persistent volumes, and even custom service accounts for accessing other Kubernetes resources. This flexibility allows you to tailor your build environments precisely to the needs of your jobs, from simple shell scripts to complex microservice builds requiring specialized tools.
A common pattern is to use a "workflow" container that orchestrates other containers. For instance, you might have a main build container and a docker sidecar, each with their own configurations and tools, all running within the same pod and sharing network namespaces.
The most surprising thing about this setup is how seamlessly it integrates with existing Docker workflows. You’re not restricted to building within the agent pod; you can use the agent pod to control the Docker daemon on the node it’s running on, effectively turning your Kubernetes nodes into dynamic build farms. This allows you to leverage the full power of Docker, including building multi-stage Dockerfiles or even orchestrating Docker Compose locally on the node, all managed by Jenkins.
The next step is to explore advanced configurations like using Jenkins Kubernetes plugin’s built-in declarative templates or integrating with GitOps workflows to manage your agent definitions.