How to Build Docker‑less Container Images with Kaniko in CI/CD Pipelines
This guide explains how Kaniko enables container image builds without a Docker daemon, covering its architecture, step‑by‑step usage on Kubernetes—including secret creation, Dockerfile preparation, pod deployment, log verification—and outlines its current limitations.
When building a CI/CD pipeline you may need to create a container image on a node that cannot install Docker or lacks permission to start the Docker daemon. Google’s open‑source tool Kaniko solves this by building images entirely without Docker, requiring no root privileges or daemon process, and works on platforms such as GitLab CI, Jenkins, Tekton, and Argo Workflows.
Kaniko Introduction
Kaniko builds container images from a Dockerfile inside a container or Kubernetes cluster. It does not depend on the Docker daemon and executes each Dockerfile command in user space, making it suitable for environments where running Docker is unsafe or impractical, such as standard Kubernetes clusters.
How It Works
The Kaniko executor image extracts the base image filesystem (the FROM image), runs each Dockerfile command, snapshots the filesystem after each step, and appends a new layer to the base image, updating the image metadata.
Kaniko Usage
1. Configure Harbor credentials
<code>$ kubectl create secret docker-registry harbor-user-secret --docker-server=https://core.jiaxzeng.com --docker-username=admin --docker-password=pwd
secret/harbor-user-secret created</code>2. Prepare the Dockerfile
<code>$ pwd
/tmp/kaniko/simple
$ ls
Dockerfile go.mod main.go README.md
$ cat Dockerfile
FROM core.jiaxzeng.com/library/golang:1.23.8-alpine AS builder
COPY . .
RUN go env -w GO111MODULE=on && \
go build -o /tmp/simple .
FROM scratch
COPY --from=builder /tmp/simple /simple
CMD ["/simple"]</code>3. Deploy the Kaniko pod
<code>cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
image: core.jiaxzeng.com/library/kaniko-executor:latest
args:
- --dockerfile=/workspace/Dockerfile
- --context=/workspace/
- --skip-tls-verify
- --destination=core.jiaxzeng.com/library/test:v1.0
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker
- name: dockerfile-storage
mountPath: /workspace
restartPolicy: Never
nodeSelector:
kubernetes.io/hostname: "k8s-node04"
volumes:
- name: kaniko-secret
secret:
secretName: harbor-user-secret
items:
- key: .dockerconfigjson
path: config.json
- name: dockerfile-storage
hostPath:
path: /tmp/kaniko/simple
type: DirectoryOrCreate
EOF</code>4. Verify the build
Check the Kaniko logs:
<code>$ kubectl logs -f kaniko
INFO[0001] Resolved base name core.jiaxzeng.com/library/golang:1.23.8-alpine to builder
... (log output truncated for brevity) ...
INFO[0045] Pushed core.jiaxzeng.com/library/test@sha256:0d72a170294cbb855df3139206d9f81e5e314f69122eb760dd05ad5734ffa19a</code>Then confirm the image appears in Harbor:
Limitations
Kaniko does not support building Windows containers.
It cannot run inside any Docker image other than the official Kaniko executor image due to implementation details.
It cannot use chroot or bind‑mount because it must run without privileged access, unpacking directly into its own root filesystem.
Kaniko does not support the v1 registry API (the v1 API is deprecated).
Conclusion
Kaniko’s emergence means we can finally eliminate the dependency on the Docker daemon, safely and efficiently building container images in any environment. In CI/CD scenarios it not only improves build security but also enhances deployment flexibility and portability.
Linux Ops Smart Journey
The operations journey never stops—pursuing excellence endlessly.
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.