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.
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/runKaniko
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.jsonThe 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.
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.