Cloud Native 12 min read

Container Image Build Tools for Containerd: Docker, DinD, DaemonSet, Kaniko, and Jib

This article introduces the main container image building methods for environments using containerd, covering Docker‑outside‑Docker, DinD sidecars, DaemonSet deployment, and daemon‑less tools such as Kaniko and Jib, with detailed YAML examples and usage notes.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Container Image Build Tools for Containerd: Docker, DinD, DaemonSet, Kaniko, and Jib

Using Docker for Image Build Service

In Kubernetes clusters, CI/CD pipelines may use Docker to build images by mounting the host Docker UNIX socket (/var/run/docker.sock) into Pods via hostPath, implementing the “Docker outside of Docker” (DooD) approach, which is simpler and more resource‑efficient than Docker‑in‑Docker but has limitations such as incompatibility with containerd runtimes, potential image overwrites, daemon configuration impacts, and security concerns in multi‑tenant scenarios.

Using DinD as a Pod Sidecar

Deploy a sidecar container named dind alongside the build container, sharing an emptyDir volume for /var/run . The build container accesses Docker via the mounted UNIX socket, enabling image builds without altering the host daemon.

apiVersion: v1
kind: Pod
metadata:
  name: clean-ci
spec:
  containers:
  - name: dind
    image: 'docker:stable-dind'
    command:
    - dockerd
    - --host=unix:///var/run/docker.sock
    - --host=tcp://0.0.0.0:8000
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /var/run
      name: cache-dir
  - name: clean-ci
    image: 'docker:stable'
    command: ["/bin/sh"]
    args: ["-c", "docker info >/dev/null 2>&1; while [ $? -ne 0 ]; do sleep 3; docker info >/dev/null 2>&1; done; docker pull library/busybox:latest; docker save -o busybox-latest.tar library/busybox:latest; docker rmi library/busybox:latest; while true; do sleep 86400; done"]
    volumeMounts:
    - mountPath: /var/run
      name: cache-dir
  volumes:
  - name: cache-dir
    emptyDir: {}

Deploying Docker via DaemonSet

A DaemonSet can run a Docker daemon on every node, exposing the same UNIX socket through a hostPath volume, allowing build Pods to use Docker identically to the sidecar method.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: docker-ci
spec:
  selector:
    matchLabels:
      app: docker-ci
  template:
    metadata:
      labels:
        app: docker-ci
    spec:
      containers:
      - name: docker-ci
        image: 'docker:stable-dind'
        command:
        - dockerd
        - --host=unix:///var/run/docker.sock
        - --host=tcp://0.0.0.0:8000
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /var/run
          name: host
      volumes:
      - name: host
        hostPath:
          path: /var/run

Kaniko

Kaniko builds container images from a Dockerfile inside a container or Kubernetes pod without requiring a Docker daemon or privileged mode. It processes the Dockerfile line‑by‑line, creating snapshots for each layer and pushing the final image to a registry.

Example Dockerfile:

FROM alpine:latest
RUN apk add busybox-extras curl
CMD ["echo","Hello Kaniko"]

Kaniko Pod specification:

apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args: ["--dockerfile=/workspace/Dockerfile","--context=/workspace/","--destination=cnych/kaniko-test:v0.0.1"]
    volumeMounts:
    - name: kaniko-secret
      mountPath: /kaniko/.docker
    - name: dockerfile
      mountPath: /workspace/Dockerfile
      subPath: Dockerfile
  volumes:
  - name: dockerfile
    configMap:
      name: dockerfile
  - name: kaniko-secret
    projected:
      sources:
      - secret:
          name: regcred
          items:
          - key: .dockerconfigjson
            path: config.json

The secret provides Docker registry credentials in config.json as a base64‑encoded username:password string.

Jib

Jib is a Google‑open‑source tool for building Java container images without a Dockerfile or daemon, integrating with Maven or Gradle. It leverages Docker layer caching for fast, incremental builds and produces reproducible images.

Gradle configuration example:

buildscript{
    ...
    dependencies {
        ...
        classpath "gradle.plugin.com.google.cloud.tools:jib-gradle-plugin:1.1.2"
    }
}
apply plugin: 'com.google.cloud.tools.jib'

jib{
    from{
        image = 'harbor.k8s.local/library/base:1.0'
        auth{
            username = '********'
            password = '********'
        }
    }
    to{
        image = 'harbor.k8s.local/library/xxapp:1.0'
        auth{
            username = '********'
            password = '********'
        }
    }
    container{
        jvmFlags = ['-Djava.security.egd=file:/dev/./urandom']
        ports = ['8080']
        useCurrentTimestamp = false
        workingDirectory = "/app"
    }
}

Build the image with gradle jib or push to a local Docker daemon with gradle jibDockerBuild . Combined with BuildKit, Buildah, or Podman, these tools enable daemon‑less image builds fully integrated with Kubernetes.

DockerKubernetescontainerdJibkanikoImage Building
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.