What an Image Build Pipeline Is For
Summary
- An image build pipeline is the automated path that turns a commit into a scanned, signed, and cached container image published to a registry.
- Insight: the deployable artifact is the immutable image plus its digest, not the branch or the tag - the pipeline exists to make that artifact trustworthy and reproducible.
- Key Concepts: BuildKit (Docker Engine 29.6.1 default backend), content-addressable digests, layer cache, SBOM and provenance attestations, registry as source of truth.
- When to Use: any service that ships as a container - which on Kubernetes 1.36.2 means every workload, since containerd runs pods from registry images.
- Limitations/Trade-offs: pipelines add latency and infrastructure cost; over-gating slows delivery, under-gating ships vulnerabilities.
- Related Topics: CI triggers, buildx and multi-arch, remote cache, SLSA provenance.
Foundations
A container image is not built by Kubernetes. It is built in CI, pushed to a registry, and pulled by containerd on each node when a pod is scheduled.
That separation is the whole point. Build once, promote the same digest through environments, and never rebuild for production.
The pipeline is the machine that produces that artifact on every change. Its job is to make images that are reproducible, small, scanned, and signed - without a human running docker build on a laptop.
Think of it as a pure function. Source plus base images plus build args go in; a digest-addressed image comes out.
The digest is a SHA-256 hash of the image manifest. myapp@sha256:abcd... always refers to identical bytes, while myapp:latest can point anywhere over time.
Digests are why the pipeline matters for security and rollback. You deploy a digest, you know exactly what runs, and you can roll back to a prior digest with certainty.
Mechanics & Interactions
A modern pipeline has five stages that run in order: trigger, build, scan, sign, and publish.
Trigger. A push or pull request fires the workflow. Convention is build-and-test on every PR, but push to the registry only from main or a release tag.
Build. BuildKit executes the Dockerfile as a directed acyclic graph of stages. It parallelizes independent stages, skips unchanged layers using the cache, and can target multiple architectures.
BuildKit is content-addressable end to end. Each layer is keyed by its inputs, so an unchanged COPY package.json step restores from cache instead of reinstalling dependencies.
Scan. A scanner such as Trivy or Grype inspects the built image for known CVEs in OS packages and language dependencies. The pipeline generates an SBOM (software bill of materials) describing every component.
Sign. Cosign signs the image digest, producing a signature stored alongside the image in the registry. BuildKit can also attach provenance and SBOM attestations directly.
Publish. The signed image is pushed by digest. Downstream, an admission controller or GitOps step can verify the signature before the image is allowed to run.
These stages interact through the registry. The registry is not just storage - it holds the image, its attestations, its signatures, and the shared build cache.
The build cache is itself an interaction point. Registry-backed cache lets ephemeral CI runners share layers, so a cold runner still builds fast.
Advanced Considerations & Applications
Reproducibility is the hardest property to achieve and the most valuable. Pin base images by digest, not by floating tags, so FROM node:22 cannot silently change under you.
Pin package versions too. An unpinned apt-get install makes the same Dockerfile produce different images on different days.
Cache strategy is where pipelines win or lose on speed. Order Dockerfile instructions from least to most frequently changing: base, then dependencies, then application source.
For monorepos, registry-backed remote cache with mode=max exports intermediate layers, so a change in one service does not force rebuilding the others from scratch.
Multi-arch matters because clusters mix linux/amd64 and linux/arm64 nodes (Graviton, Ampere). buildx builds a manifest list so containerd pulls the right variant automatically.
Native runners beat emulation. QEMU works for arm64 on amd64 hosts but is slow for compilation-heavy builds; prefer per-arch native runners and merge into one manifest.
Supply-chain hardening is increasingly non-negotiable. SLSA provenance and cosign signatures answer the compliance question "prove this image came from this commit through this pipeline."
On the cluster side, enforce it. A Kyverno or admission policy that rejects unsigned images turns provenance from a document into a gate.
Cost and latency are real constraints. Every gate adds minutes; put fast checks (lint, unit) before slow ones (integration, scan) and fail fast.
Common Misconceptions
"Kubernetes builds my images." It does not. Kubernetes schedules pods and containerd pulls prebuilt images from a registry - dockershim was removed, so Docker Engine is never the in-cluster runtime.
"latest is fine for production." A floating tag defeats reproducibility and rollback. Deploy by digest; use tags only as human-readable aliases.
"Scanning at build time is enough." New CVEs are disclosed after you build. You also need periodic re-scans of already-published images.
"Signing proves the code is safe." Signing proves origin and integrity, not absence of bugs or vulnerabilities. It answers "who built this," not "is this good."
"A faster build is always cheaper." Aggressive parallelism and large runners cut wall-clock time but raise cost. Optimize the critical path, not every step.
FAQs
Do I need a pipeline for a small project? Yes, even a minimal one. A single workflow that builds on PR and pushes a digest on merge prevents "works on my laptop" images.
Where does the image actually run the build? On a CI runner (GitHub Actions, GitLab, etc.) using BuildKit. The runner is ephemeral, which is why remote cache matters.
Should CI push on pull requests? Generally no. Build and test on PRs to validate; push to the registry only from protected branches or tags to keep the registry clean.
What is an SBOM and why generate one? It is a machine-readable inventory of everything in the image. It powers vulnerability triage and compliance and can be attached as an attestation.
How do digests help rollback? A digest is immutable, so redeploying a previous digest restores exact prior bytes. There is no ambiguity about what a tag pointed to last week.
Is Docker Engine required in the cluster? No. Use Docker or buildx to build in CI; containerd via CRI runs the pods. Keep the two roles distinct.
Related
- Image CI Basics
- GitHub Actions & buildx
- Remote Cache
- Provenance & SLSA
- Build Pipeline Best Practices
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).