Ana içeriğe geç

Distroless & Chainguard — 0-CVE Image Stratejisi#

"Ubuntu base = 100+ CVE, daily. Alpine = ~30 CVE. Distroless = ~5 CVE. Chainguard = near-zero CVE, daily rebuild. 'Hangi base?' sorusunun cevabı 2026'da çoktan değişti."

Bu rehber distroless ve Chainguard image'larını, niye 2026 standardı olduklarını, migration stratejisini, ve trade-off'ları anlatır.


📊 Base Image Karşılaştırması#

Base Boyut CVE (tipik) Shell? Package manager? Use case
ubuntu:22.04 78 MB 100+ ✅ bash apt Dev / debug
debian:12-slim 80 MB 50+ ✅ bash apt Dev
alpine:3.19 7 MB ~30 ✅ ash apk Lightweight
gcr.io/distroless/static-debian12 2 MB ~5 Go static
gcr.io/distroless/cc-debian12 20 MB ~10 C/C++/Rust
gcr.io/distroless/python3-debian12 50 MB ~10 Python
gcr.io/distroless/nodejs22-debian12 75 MB ~10 Node
cgr.dev/chainguard/static 2 MB ~0 Go static
cgr.dev/chainguard/python 40 MB ~0 Python
cgr.dev/chainguard/node 70 MB ~0 Node
scratch 0 MB 0 Static binary only

🔑 Chainguard < Distroless < Alpine < Debian/Ubuntu (CVE açısından).


🎯 Distroless Nedir?#

Distroless: Google'ın projesi, sadece uygulama runtime dependencies içerir. Shell, package manager, debugger yok.

İçinde ne var?#

  • Runtime libraries (libc, ssl)
  • CA certificates
  • /etc/passwd (nonroot user)
  • timezone data
  • (bazılarında) Java JRE / Python interpreter / Node runtime

İçinde ne yok?#

  • Shell (bash, sh)
  • apt, apk, rpm, npm
  • curl, wget, vim
  • find, grep, ls

🔑 Saldırgan compromise etse bile içeride komut çalıştıramaz → exfiltration zor.

Variants#

Image İçindekiler
distroless/static CA + nonroot user (Go static binary için)
distroless/base static + glibc + libssl (CGo binaries)
distroless/cc base + libgcc (C/C++/Rust)
distroless/python3 cc + Python runtime
distroless/nodejs22 cc + Node 22
distroless/java21 base + JRE 21

Tags#

  • :latest (mutable, kullanma)
  • :debug (busybox shell — sadece debug için)
  • :nonroot (UID 65532, önerilen)
  • :debug-nonroot (kombine)
  • @sha256:... (digest pin, en güvenli)

🦅 Chainguard Images#

Chainguard: 2022'de kurulan startup. Wolfi (mini distro) üzerine kurulu. Daily rebuild + near-zero CVE taahhüdü.

Avantajlar#

  • 0 CVE hedefi (most images)
  • Daily rebuild — yeni CVE açıklandığında image güncel
  • SBOM + signature her image'a attached
  • glibc-tabanlı (musl değil — Alpine sorunlarını engeller)
  • FIPS 140-3 versions available
  • Reproducible builds

Free vs Paid#

  • cgr.dev/chainguard/<IMAGE>:latest → free, public images
  • cgr.dev/chainguard-private/<IMAGE> → paid, daily-rebuild older versions

Örnek#

# Free, latest
FROM cgr.dev/chainguard/python:latest

# Paid (daily rebuild + version-pinned)
FROM cgr.dev/chainguard-private/python:3.12.7

🚀 Migration: Ubuntu → Distroless#

Adım 1: Multi-stage build'e geç#

# Eski (tek-stage Ubuntu)
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y python3
COPY . /app
CMD ["python3", "/app/main.py"]

# Yeni (multi-stage)
FROM python:3.12-slim AS builder
RUN python -m venv /opt/venv
COPY requirements.txt .
RUN /opt/venv/bin/pip install -r requirements.txt

FROM gcr.io/distroless/python3-debian12:nonroot
COPY --from=builder /opt/venv /opt/venv
COPY . /app
WORKDIR /app
ENV PATH="/opt/venv/bin:$PATH"
USER nonroot
CMD ["python", "main.py"]

Adım 2: Build araçları builder'da kalsın#

# ❌ Distroless'ta apt yok
RUN apt-get install -y curl   # FAIL

# ✅ Builder'da yap
FROM debian:12-slim AS builder
RUN apt-get install -y curl ca-certificates
COPY ... ...

FROM gcr.io/distroless/cc-debian12:nonroot
COPY --from=builder /usr/bin/curl /usr/bin/curl

Adım 3: Shell'siz debugging#

# Production image'da shell yok
docker exec -it <CONTAINER> sh   # FAIL

# Debug için ephemeral container
kubectl debug -it <POD> --image=nicolaka/netshoot --target=<CONTAINER>

# veya distroless:debug image kullan (sadece debug için)
FROM gcr.io/distroless/python3-debian12:debug-nonroot

🔧 Build vs Runtime Image#

Build: tam SDK#

FROM golang:1.23 AS builder
# tüm araçlar var
RUN go build ...

Runtime: minimal#

FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /myapp /myapp
USER nonroot
ENTRYPOINT ["/myapp"]

🔑 Build araçlarının runtime'da hiçbir işi yok. Multi-stage zorunlu.


🛡️ Production Security Hardening#

1. UID 65532 (nonroot)#

USER nonroot   # veya 65532

2. Read-only filesystem#

# K8s deployment
securityContext:
  readOnlyRootFilesystem: true
volumeMounts:
  - name: tmp
    mountPath: /tmp
volumes:
  - name: tmp
    emptyDir: {}

3. Drop all capabilities#

securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: [ALL]
  seccompProfile:
    type: RuntimeDefault

4. Cosign sign + Kyverno verify#

Bkz Image-Signing-Cosign.md ve 08-Security/Policy-as-Code-OPA-Kyverno.md.


🚫 Anti-Pattern Tablosu#

Anti-pattern Niye kötü Doğru
FROM ubuntu:latest runtime 100+ CVE + 78 MB distroless / chainguard
Shell production'da Compromise interactive Shell-free runtime
RUN apt-get install runtime image'da Dev tool runtime'da Builder'da yap, COPY runtime'a
:latest distroless tag Mutable Digest pin
Distroless + USER root Default UID kullanım :nonroot veya USER 65532
Alpine + glibc app musl uyumsuzlukları distroless (glibc)
Chainguard latest free + production Major version skip riski Pinned + paid
Debugging için prod image'a SSH Saldırgan vektörü kubectl debug --image=netshoot
Build cache yok Her build full rebuild BuildKit cache mount
SBOM yok Supply chain bilinmez --sbom=true

📋 Distroless Adoption Checklist#

[ ] Tüm prod image multi-stage
[ ] Runtime: distroless veya chainguard
[ ] USER nonroot
[ ] Digest pin (`@sha256:...`)
[ ] readOnlyRootFilesystem: true (K8s)
[ ] Drop ALL capabilities
[ ] BuildKit cache mount
[ ] cosign sign + verify (Kyverno)
[ ] SBOM attached (`--sbom=true`)
[ ] Trivy scan: 0 CRITICAL/HIGH (fix-available)
[ ] Image size dashboard (CI'da)
[ ] Multi-arch build (`buildx`)
[ ] Debug için `:debug` variant veya ephemeral container
[ ] Quarterly: base image upgrade (yeni distro version)

📚 Referanslar#


"Distroless 'extreme' değil — 2026 production standardı. Ubuntu base ile prod'a image push'layan ekip, CVE backlog dağı ile uğraşırken; Chainguard ile push'layan ekip near-zero CVE rapor verir."