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 imagescgr.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#
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)#
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 — github.com/GoogleContainerTools/distroless
- Chainguard Images — chainguard.dev/chainguard-images
- Wolfi (Chainguard distro) — github.com/wolfi-dev
- Cosign — github.com/sigstore/cosign
Dockerfile-Best-Practices.mdMulti-Stage-Builds.mdImage-Signing-Cosign.md08-Security/Container-Image-Scanning.md08-Security/Kubernetes-Hardening.md
"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."