Kubernetes Image Security

Every container starts from an image, and every image carries code written by someone else: a base operating system, language libraries, and application files. A weakness in any layer becomes a weakness in the cluster. Image security protects the cluster before a single pod starts.

The Food Supply Analogy

A restaurant protects customers by checking ingredients at delivery, storing them in clean containers, and labeling them with dates. Image security follows the same plan. Teams choose trusted suppliers, inspect each delivery, and keep records of what went into every dish.

The Image Journey

 Source code ──▶ Build ──▶ Scan ──▶ Sign ──▶ Registry ──▶ Cluster
      │            │         │        │          │            │
   review       minimal   find CVEs  prove     private      verify
   code         base                origin     access       before run

Every stage offers a chance to stop a threat. A weak stage lets threats flow downstream.

Choose Small Base Images

A smaller image contains fewer packages, so it holds fewer vulnerabilities and gives attackers fewer tools.

Base image typeTypical sizeAttack surface
Full operating system imageHundreds of MBLarge
Slim variantsTens of MBMedium
Alpine-basedUnder 10 MBSmall
Distroless or scratchA few MBVery small, no shell

Multi-stage builds keep compilers and build tools out of the final image.

FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o app

FROM gcr.io/distroless/static
COPY --from=build /src/app /app
USER 65532:65532
ENTRYPOINT ["/app"]

Pin Exact Versions

The tag latest points to a different image every time the publisher pushes an update. A pod restart may pull code nobody tested. Use specific version tags. Digests go one step further because they identify the exact bytes of an image.

image: nginx:1.27.2
image: nginx@sha256:3f1b0c...  # digest, truncated here

Scan for Vulnerabilities

Scanners compare image contents against databases of known flaws (CVEs). Trivy, Grype, and registry-built scanners all fit into a CI pipeline.

trivy image --severity HIGH,CRITICAL myrepo/orders:1.0

Fail the build when critical findings appear. Scan stored images on a schedule, because new CVEs surface after an image ships.

Use Private Registries

Public registries host millions of images with uneven quality. Mirror trusted images into a private registry and let the cluster pull only from it. A pod fetches private images with credentials stored in an image pull secret.

kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=builder \
  --docker-password='REPLACE_ME' \
  -n shop
spec:
  imagePullSecrets:
  - name: regcred
  containers:
  - name: orders
    image: registry.example.com/shop/orders:1.0

Control Pull Behavior

  • IfNotPresent reuses a cached image on the node. This is the default for versioned tags.
  • Always checks the registry on every start. This is the default for latest.
  • Never uses only local images.

Sign and Verify Images

A signature proves that a trusted build system created an image and that nobody changed it after the build. Cosign from the Sigstore project signs images and stores signatures beside them in the registry.

cosign sign registry.example.com/shop/orders:1.0
cosign verify registry.example.com/shop/orders:1.0 \
  --certificate-identity=builder@example.com \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com

Admission policies in the cluster, such as Kyverno or Sigstore policy controller, reject pods whose images lack a valid signature.

Record What Is Inside

A Software Bill of Materials (SBOM) lists every package in an image. When a new vulnerability appears, teams search SBOMs to find affected applications in minutes rather than days. Tools such as Syft generate SBOMs automatically.

Run Containers with Least Privilege

  • Set USER in the Dockerfile to a non-root account.
  • Remove shells and package managers from production images.
  • Use read-only root filesystems at runtime with readOnlyRootFilesystem: true.
  • Never bake passwords, tokens, or private keys into image layers. Layers stay readable after deletion.

Checklist for Every Image

  1. Start from a trusted, minimal base.
  2. Pin versions or digests.
  3. Scan on build and on schedule.
  4. Sign the image and verify at admission.
  5. Store it in a private registry with restricted push rights.
  6. Run it as a non-root user with a read-only filesystem.

Key Points

  • Small images carry fewer vulnerabilities.
  • Version pins and digests make deployments repeatable.
  • Scanning, signing, and SBOMs build a chain of trust from build to cluster.
  • Private registries and pull secrets control who can fetch images.