<p>I wrote about <a href="https://www.rokpoto.com/jenkins-docker-in-docker-agent/" rel="nofollow noreferrer">Jenkins Docker in Docker Agent</a> which you may find useful.</p>
<p>The article answers your questions in detail.</p>
<p>I'll answer them shortly here as well:</p>
<blockquote>
<p>Why having it running as two containers?</p>
</blockquote>
<p>The first one is the container with Docker client. And it’s basically Jenkins agent, because it extends jenkins/jnlp-agent-docker base image. The second one is the container with Docker daemon inside.</p>
<blockquote>
<p>I install from the official Helm chart. I could not find a good way to add another container there yet, without overwriting the whole pod template.</p>
</blockquote>
<p>You need to put a reference to docker in docker agent in <code>additionalAgents</code> key in helm chart <code>values.yaml</code>. See the example of <a href="https://www.rokpoto.com/jenkins-docker-in-docker-agent/#use-docker-in-docker-agent" rel="nofollow noreferrer">Docker in Docker agent</a> configuration.</p>

CC BY-SA 4.0
2022-11-14T20:04:29.643Z
2022-11-14T20:04:29.643Z
rokpoto.com
<p>I'm looking for a way to run a Docker-in-Docker (dind) container alongside my Jenkins agent nodes using the Jenkins Kubernetes Plugin configured by Jenkins Configuration-as-Code (JCasC).</p>
<p>I'm currently running a plain agent node, that has all my tools installed. Including the Docker client. But no server/daemon running. My idea was now to add another container, that is running the Docker daemon. Both containers share the same working directory, so they operate on the same data.</p>
<p>Why having it running as two containers? The Docker daemon needs privileged access. And I want to restrict it as much as possible.</p>
<p>First problem that I encountered was, that Jenkins is not <em>killing the pod</em> when its finished building, but just ends the agent process. Now with another container running, the pod stays alive. I <em>fixed</em> this by writing a file to another shared volume when the agent pod stops, which in turn is read by the dind pod and exits when the file is present.</p>
<p>Here's an excerpt from my current Pod config:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: &quot;v1&quot;
kind: &quot;Pod&quot;
spec:
  serviceAccountName: jenkins-agent
  containers:
  - image: &quot;jenkins-jnlp-image&quot;
    command: [ &quot;/bin/sh&quot;, &quot;-c&quot; ]
    args:
    - |
      trap 'touch /usr/share/pod/done' EXIT
      /entrypoint.sh
    name: &quot;jnlp&quot;
    env:
    - name: DOCKER_HOST
      value: tcp://localhost:2375
    securityContext:
      privileged: false
    tty: true
    volumeMounts:
    - mountPath: &quot;/home/jenkins/agent&quot;
      name: &quot;workspace-volume&quot;
      readOnly: false
    - mountPath: /usr/share/pod
      name: tmp-pod
    workingDir: &quot;/home/jenkins/agent&quot;
  - image: &quot;dind-image&quot;
    name: &quot;dind&quot;
    command: [ &quot;/bin/sh&quot;, &quot;-c&quot; ]
    args:
      - |
        dockerd-entrypoint.sh &amp;
        while ! test -f /usr/share/pod/done; do
        echo 'Waiting for the jnlp to finish...'
        sleep 5
        done
        echo &quot;Agent pod finished, exiting&quot;
        exit 0
    securityContext:
      privileged: true
    tty: false
    volumeMounts:
    - mountPath: &quot;/home/jenkins/agent&quot;
      name: &quot;workspace-volume&quot;
      readOnly: false
    - mountPath: /usr/share/pod
      name: tmp-pod
    workingDir: &quot;/home/jenkins/agent&quot;
  volumes:
    - emptyDir:
        medium: &quot;&quot;
      name: &quot;workspace-volume&quot;
    - emptyDir: {}
      name: tmp-pod
</code></pre>
<p>Is this the deigned way of doing this? Is there any better?</p>
<p>Bonus question: I install from the <a href="https://github.com/jenkinsci/helm-charts/tree/main/charts/jenkins" rel="nofollow noreferrer">official Helm chart</a>. I could not find a good way to add another container there yet, without overwriting the whole pod template. Does anyone know of a way? If not I would probably create a PR to add that as a feature.</p>
<p>Thanks in advance!</p>

<kubernetes><jenkins><kubernetes-helm><docker-in-docker>
Run docker-in-docker container alongside Jenkins agent
Max N.
# Run docker-in-docker container alongside Jenkins agent

(Asked by: username_0 on 2022-08-30)

I'm looking for a way to run a Docker-in-Docker (dind) container alongside my Jenkins agent nodes using the Jenkins Kubernetes Plugin configured by Jenkins Configuration-as-Code (JCasC).
I'm currently running a plain agent node, that has all my tools installed. Including the Docker client. But no server/daemon running. My idea was now to add another container, that is running the Docker daemon. Both containers share the same working directory, so they operate on the same data.
Why having it running as two containers? The Docker daemon needs privileged access. And I want to restrict it as much as possible.
First problem that I encountered was, that Jenkins is not killing the pod when its finished building, but just ends the agent process. Now with another container running, the pod stays alive. I fixed this by writing a file to another shared volume when the agent pod stops, which in turn is read by the dind pod and exits when the file is present.
Here's an excerpt from my current Pod config:
apiVersion: "v1"
kind: "Pod"
spec:
  serviceAccountName: jenkins-agent
  containers:
  - image: "jenkins-jnlp-image"
    command: [ "/bin/sh", "-c" ]
    args:
    - |
      trap 'touch /usr/share/pod/done' EXIT
      /entrypoint.sh
    name: "jnlp"
    env:
    - name: DOCKER_HOST
      value: tcp://localhost:2375
    securityContext:
      privileged: false
    tty: true
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"
      readOnly: false
    - mountPath: /usr/share/pod
      name: tmp-pod
    workingDir: "/home/jenkins/agent"
  - image: "dind-image"
    name: "dind"
    command: [ "/bin/sh", "-c" ]
    args:
      - |
        dockerd-entrypoint.sh &
        while ! test -f /usr/share/pod/done; do
        echo 'Waiting for the jnlp to finish...'
        sleep 5
        done
        echo "Agent pod finished, exiting"
        exit 0
    securityContext:
      privileged: true
    tty: false
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"
      readOnly: false
    - mountPath: /usr/share/pod
      name: tmp-pod
    workingDir: "/home/jenkins/agent"
  volumes:
    - emptyDir:
        medium: ""
      name: "workspace-volume"
    - emptyDir: {}
      name: tmp-pod

Is this the deigned way of doing this? Is there any better?
Bonus question: I install from the official Helm chart. I could not find a good way to add another container there yet, without overwriting the whole pod template. Does anyone know of a way? If not I would probably create a PR to add that as a feature.
Thanks in advance!

**Tags:** kubernetes, jenkins, kubernetes-helm, docker-in-docker


---

## 1 answers

### Answer by username_1 on 2022-11-14. Score: 1

I wrote about [Jenkins Docker in Docker Agent](https://www.username_1/jenkins-docker-in-docker-agent/) which you may find useful.

The article answers your questions in detail.

I'll answer them shortly here as well:

> Why having it running as two containers?

The first one is the container with Docker client. And it’s basically Jenkins agent, because it extends jenkins/jnlp-agent-docker base image. The second one is the container with Docker daemon inside.

> I install from the official Helm chart. I could not find a good way to add another container there yet, without overwriting the whole pod template.

You need to put a reference to docker in docker agent in `additionalAgents` key in helm chart `values.yaml`. See the example of [Docker in Docker agent](https://www.username_1/jenkins-docker-in-docker-agent/#use-docker-in-docker-agent) configuration.


---

