Automation CI/CD DevOps

Podman Jenkins Agent

Today, I’ll show Podman Jenkins agent assuming Jenkins runs on Kubernetes. We’ll see Podman agent’s Dockerfile and CI/CD pipeline using it.


We have already seen numerous demos of Jenkins running on Kubernetes which I installed using helm. We saw how cool Jenkins on Kubernetes is, because Jenkins and its agents run as Kubernetes pods thanks to Jenkins Kubernetes plugin. Agents are dynamically provisioned for each build and pipeline’s code runs inside them.

We also saw Jenkins Docker in Docker Agent which allows running docker commands inside it as part of CI/CD pipelines. Now it’s time to see Jenkins Podman Agent which will act as deamonless alternative of Jenkins Docker in Docker Agent.

Why Podman?

In short, Podman is a deamonless container engine which has an identical CLI to docker client. (docker build = podman build). We saw that using Jenkins Docker in Docker Agent introduces the overhead of running docker daemon inside container for each build. In addition to performance impact, it introduces challenges to docker daemon caching. So, why not go daemonless, altogether?

Podman Jenkins Agent Docker Image

While there’s an official Jenkins Docker client agent image, there’s no official Jenkins Podman agent. No worries, its Dockerfile is rather short, while not being straightforward. First, we’ll use Alpine version of jenkins/inbound-agent as a base image. As the base image is Alpine, we’ll use its docs for installing podman.

FROM jenkins/inbound-agent:alpine
USER root

RUN apk add --no-cache --update podman  fuse-overlayfs

RUN sed -i 's/#mount_program/mount_program/' /etc/containers/storage.conf

RUN echo jenkins:100000:65536 >/etc/subuid
RUN echo jenkins:100000:65536 >/etc/subgid
USER jenkins

We’ll not go into the details of the commands now. Maybe, in the future.

Let’s build the image out of the Dockerfile and run bash shell inside it. Note --privileged flag we used when we ran docker daemon inside docker as well.

docker build -t podman-agent .
docker run --privileged -it podman-agent:latest bash
# inside podman agent container
1f20100c25e8:~$ podman run --rm hello-world
Hello from Docker!

Let’s now push the image to Dockerhub, because we’ll need it while running builds.

# tag the image
$ docker tag podman-agent:latest [docker_hub_id]/podman-agent:latest 
# push the image, you'll need Dockerhub or other container registry account for pushing the image
$ docker push [docker_hub_id]/podman-agent:latest

Podman Jenkins Agent Demo

Let’s put Podman Jenkins agent into action and run some Jenkins pipeline using it.

Demo Prerequisites

I’ll use Linode’s managed Kubernetes cluster for the demo. Check out how easy it is to create Kubernetes Cluster on Linode. Linode is a cloud service provider recently purchased by Akamai. With this purchase, Akamai became a competitor in the cloud providers market. You can repeat this demo on your own Linode account. Create one and get 100$ credit using this link.

In addition to Kubernetes cluster, you’ll need kubectl and helm installed on your local machine. Moreover, you’ll need Dockerhub or other container registry account for pushing docker image I build during the demo.

Use Podman Jenkins Agent agent

We’ll install Jenkins on Kubernetes using helm. In order to configure Jenkins to use Podman agent, we’ll use its chart’s values.yaml.

Let’s download official Jenkins helm chart’s values.yaml

wget -4

Next, put reference to Podman agent under key additionalAgents in values.yaml:

    podName: podman
    image: jenkins
    customJenkinsLabels: podman
    tag: "latest"
    privileged: true
    alwaysPullImage: true

Install Jenkins on Kubernetes

helm repo add jenkinsci
helm repo update
helm install jenkins -n jenkins --create-namespace jenkinsci/jenkins -f values.yaml

Wait till all resources are running, healthy and ready. Next, access Jenkins UI in the browser using its LoadBalancer service external ip address and port 8080.

Find admin password using below command:

kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo

If you navigate to Jenkins /manage/configureClouds/ endpoint you’ll notice that Jenkins is configured to use podman agent.

This screen is enabled due to Jenkins Kubernetes plugin which comes by default in Jenkins community helm chart.

Run sample Jenkins job using Podman Jenkins Agent

Now, let’s create a sample Jenkins pipeline which will use our Podman Jenkins agent. We’ll use it to build image of dind Jenkins agent we used in Jenkins Docker in Docker Agent demo.

Use Jenkinsfile-Podman.groovy as a script path and main branch as the branch to build.

Jenkinsfile-Podman.groovy is straightforward:

pipeline {
    agent  {
        label 'podman'

    stages {
        stage("build image") {
            steps {
                script {
                    sh "podman build -t dind-client-jenkins-agent ."

Note the agent’s label podman. It’s the same label we have assigned to podman agent in customJenkinsLabels field in values.yaml. Hence, Kubernetes plugin will use Podman agent image while provisioning Kubernetes pods for the builds.

Let’s run the pipeline in Jenkins UI and see that it successfully completes.

So what happened behind the scenes?

kubectl get pods while the pipeline is running in order to see that Jenkins provisioned podman agent on-demand just for the duration of the pipeline. podman build command ran inside it.

If you want to see the actual Kubernetes deployment manifests used to provision the agent, inspect the job’s Console output. You’ll see that the image we built and pushed earlier was used in the manifests.


That’s it about Podman Jenkins Agent. As always, feel free to share.

Find out recommended Jenkins books on Amazon.

Find out recommended Jenkins courses on Pluralsight:

Sign up using this link to get exclusive discounts like 50% off your first month or 15% off an annual subscription)