'Docker in Docker configuration

I am having Jenkins running in K8s and now i am trying to run: docker build as one of the step in Jenkins build. Since Jenkins is running inside Docker, i came to the solution to use Docker in Docker from this post: https://medium.com/hootsuite-engineering/building-docker-images-inside-kubernetes-42c6af855f25

However, after I modified the deployment yaml file, it still does not work.

There are 2 containers running: Jenkins (Jenkins image) and dind (docker in docker image). I could run the docker command inside dind container but i can not run docker command in Jenkins or pod.

Here is the yaml file:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "9"
    field.cattle.io/publicEndpoints: '[{"addresses":["10.0.0.111"],"port":80,"protocol":"HTTP","serviceName":"jenkins-with-did:jenkins-with-did","ingressName":"jenkins-with-did:jenkins-with-did","hostname":"jenkins.dtl.miproad.ad","allNodes":true}]'
  creationTimestamp: "2020-04-30T06:38:40Z"
  generation: 11
  labels:
    app.kubernetes.io/component: jenkins-master
    app.kubernetes.io/instance: jenkins-with-did
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: jenkins
    helm.sh/chart: jenkins-1.18.0
    io.cattle.field/appId: jenkins-with-did
  name: jenkins-with-did
  namespace: jenkins-with-did
  resourceVersion: "29233038"
  selfLink: /apis/apps/v1/namespaces/jenkins-with-did/deployments/jenkins-with-did
  uid: 6439c48d-c4ce-418c-8553-d06fee13c7d1
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/component: jenkins-master
      app.kubernetes.io/instance: jenkins-with-did
  strategy:
    type: Recreate
  template:
    metadata:
      annotations:
        cattle.io/timestamp: "2020-04-30T18:15:50Z"
        checksum/config: fda7089fede91f066c406bbba5e2a1d59f71183eebe9bca3fe7de19d13504058
        field.cattle.io/ports: '[[{"containerPort":8080,"dnsName":"jenkins-with-did","hostPort":0,"kind":"ClusterIP","name":"http","protocol":"TCP","sourcePort":0},{"containerPort":50000,"dnsName":"jenkins-with-did","hostPort":0,"kind":"ClusterIP","name":"slavelistener","protocol":"TCP","sourcePort":0}]]'
      creationTimestamp: null
      labels:
        app.kubernetes.io/component: jenkins-master
        app.kubernetes.io/instance: jenkins-with-did
        app.kubernetes.io/managed-by: Tiller
        app.kubernetes.io/name: jenkins
        helm.sh/chart: jenkins-1.18.0
    spec:
      containers:
      - args:
        - --argumentsRealm.passwd.$(ADMIN_USER)=$(ADMIN_PASSWORD)
        - --argumentsRealm.roles.$(ADMIN_USER)=admin
        - --httpPort=8080
        env:
        - name: JAVA_OPTS
        - name: JENKINS_OPTS
        - name: JENKINS_SLAVE_AGENT_PORT
          value: "50000"
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              key: jenkins-admin-password
              name: jenkins-with-did
              optional: false
        - name: ADMIN_USER
          valueFrom:
            secretKeyRef:
              key: jenkins-admin-user
              name: jenkins-with-did
              optional: false
        image: jenkins/jenkins:lts
        imagePullPolicy: Always
        livenessProbe:
          failureThreshold: 5
          httpGet:
            path: /login
            port: http
            scheme: HTTP
          initialDelaySeconds: 90
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
          env:
            - name: DOCKER_HOST
              value: tcp://localhost:2375
        name: jenkins
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        - containerPort: 50000
          name: slavelistener
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /login
            port: http
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        resources:
          limits:
            cpu: "2"
            memory: 4Gi
          requests:
            cpu: 50m
            memory: 256Mi
        securityContext:
          capabilities: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /tmp
          name: tmp
        - mountPath: /var/jenkins_home
          name: jenkins-home
        - mountPath: /var/jenkins_config
          name: jenkins-config
          readOnly: true
        - mountPath: /usr/share/jenkins/ref/secrets/
          name: secrets-dir
        - mountPath: /usr/share/jenkins/ref/plugins/
          name: plugin-dir
      - image: docker:18.05-dind
        imagePullPolicy: IfNotPresent
        name: dind
        resources: {}
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/lib/docker
          name: dind-storage
      dnsPolicy: ClusterFirst
      initContainers:
      - command:
        - sh
        - /var/jenkins_config/apply_config.sh
        env:
        - name: ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              key: jenkins-admin-password
              name: jenkins-with-did
              optional: false
        - name: ADMIN_USER
          valueFrom:
            secretKeyRef:
              key: jenkins-admin-user
              name: jenkins-with-did
              optional: false
        image: jenkins/jenkins:lts
        imagePullPolicy: Always
        name: copy-default-config
        resources:
          limits:
            cpu: "2"
            memory: 4Gi
          requests:
            cpu: 50m
            memory: 256Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/lib/docker
          name: dind-storage
        - mountPath: /tmp
          name: tmp
        - mountPath: /var/jenkins_home
          name: jenkins-home
        - mountPath: /var/jenkins_config
          name: jenkins-config
        - mountPath: /usr/share/jenkins/ref/secrets/
          name: secrets-dir
        - mountPath: /var/jenkins_plugins
          name: plugin-dir
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        runAsUser: 0
      serviceAccount: jenkins-with-did
      serviceAccountName: jenkins-with-did
      terminationGracePeriodSeconds: 30
      volumes:
      - emptyDir: {}
        name: dind-storage
      - emptyDir: {}
        name: plugins
      - emptyDir: {}
        name: tmp
      - configMap:
          defaultMode: 420
          name: jenkins-with-did
        name: jenkins-config
      - emptyDir: {}
        name: secrets-dir
      - emptyDir: {}
        name: plugin-dir
      - name: jenkins-home
        persistentVolumeClaim:
          claimName: jenkins-with-did
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2020-04-30T18:20:47Z"
    lastUpdateTime: "2020-04-30T18:20:47Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2020-04-30T06:38:40Z"
    lastUpdateTime: "2020-04-30T18:20:47Z"
    message: ReplicaSet "jenkins-with-did-5db85986b6" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 11
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

Thank you so much in advance!



Solution 1:[1]

Your idea is a valid approach.

The regular jenkins image does not provide the docker cli - therefore using docker does not work out of the box. You can either build your own jenkins image which provides the docker command or you can use a prebuilt jenkins image including the docker cli, for example: https://hub.docker.com/r/trion/jenkins-docker-client

Solution 2:[2]

You can do a hostpath volumes and mount /usr/bin/docker, /lib64 and /usr/lib64 from the node to your pod. This would need securityContext: -> privileged: true

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thomas
Solution 2 RandomQuests