Containerisierung: Docker und OCI
Containerisierung: Docker und OCI
1) Grundbegriffe und OCI-Standards
OCI Image Spec ist ein Bildformat (Manifest, config, layers, index for multi-arch).
OCI Runtime Spec - wie man einen Container startet (bundle, 'config. json`); Realisierung: runc sowie gVisor, Kata Containers.
OCI Distribution Spec - Interaktion mit Registern (Push/Pull, Autorisierung).
Docker = UX und das Ökosystem um OCI: Dockerfile/BuildKit/CLI/Compose/Hub. In Kubernetes wurde die Docker Engine durch containerd/CRI-O ersetzt, aber das Image-Format ist das gleiche.
2) Bilder: Ebenen, Tags, Metadaten
Образ = слои (layered filesystem) + config (entrypoint/cmd/env/labels) + manifest.
Tags: verwenden Sie nicht': neueste' in der Produktion; pinning': 1. 21. 3', git-SHA oder Datum + SHA.
LABEL: Besitzer, Kontakt, vcs-url, org. opencontainers. (title, description, revision, source).
Multi-Arch: Manifest-Index gibt die richtige Option für 'amd64/arm64'.
3) Montage: Dockerfile, BuildKit, Multi-Stage
3. 1 Grundsätze
Minimieren Sie Schichten, fixieren Sie Versionen, säubern Sie die Caches von Paketmanagern.
Kopieren Sie zuerst manifest/lock-Dateien, dann 'RUN install deps' - verbessert den Cache.
.dockerignore ist obligatorisch (beseitigen Sie' .git', Artefakte, Geheimnisse).
Proben distroless/alpine/minimale Basen werden bevorzugt.
3. 2 BuildKit-Chips
Parallele Bilder, Geheimnisse im Build ('--secret'), Cash Mounts, Buildx für Multi-Arch.
Beispiel für einen Cache Mount:dockerfile syntax=docker/dockerfile:1. 6
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements. txt
3. 3 Multi-Stage Beispiele
Go (statisch verlinkt, distroless):dockerfile syntax=docker/dockerfile:1. 6
FROM golang:1. 23 AS build
WORKDIR /src
COPY go. mod go. sum./
RUN go mod download
COPY..
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o /app
FROM gcr. io/distroless/static:nonroot
USER 65532:65532
COPY --from=build /app /app
ENTRYPOINT ["/app"]
Node. js (prod-layer ohne dev-deps):
dockerfile syntax=docker/dockerfile:1. 6
FROM node:22-alpine AS deps
WORKDIR /app
COPY package. json./
RUN npm ci --omit=dev
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules./node_modules
COPY..
RUN npm run build
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules./node_modules
COPY --from=build /app/dist./dist
USER node
CMD ["node","dist/server. js"]
Python (wheel-кеш, non-root):
dockerfile syntax=docker/dockerfile:1. 6
FROM python:3. 12-slim AS base
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
WORKDIR /app
FROM base AS deps
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade pip
COPY requirements. txt.
RUN --mount=type=cache,target=/root/.cache/pip pip wheel --wheel-dir=/wheels -r requirements. txt
FROM base
COPY --from=deps /wheels /wheels
RUN pip install --no-index --find-links=/wheels -r /app/requirements. txt && rm -rf /wheels
COPY..
USER 1000:1000
CMD ["python","-m","app"]
Java (JLink/Layered Spring):
dockerfile syntax=docker/dockerfile:1. 6
FROM maven:3. 9-eclipse-temurin-21 AS build
WORKDIR /src
COPY pom. xml./
RUN mvn -q -e -DskipTests dependency:go-offline
COPY..
RUN mvn -q -DskipTests package
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=build /src/target/app. jar /app/app. jar
ENTRYPOINT ["java","-XX:+UseContainerSupport","-jar","/app/app. jar"]
4) Minimale Bilder, PID 1 und Signale
Distroless - weniger Angriffsfläche, kein Shell/Paketmanager.
PID 1 muss die Signale korrekt proxy, sonst „Zombie-Prozesse“. Verwenden Sie' ENTRYPOINT 'in exec-Form und tini/embedded init:dockerfile
ENTRYPOINT ["tini","--","/app"]
'HEALTHCHECK' intelligent einstellen (Frequenz/Timeout, keine unnötige Belastung).
5) Containersicherheit
5. 1 Politik und Hardening
Non-root (USER), rootless Docker/containers.
Kapazitäten: Überschüssige entfernen ('--cap-drop = ALL --cap-add = NET _ BIND _ SERVICE' usw.).
seccomp/AppArmor/SELinux: Aktivieren Sie Standard- oder strenge Profile.
Read-only FS + `tmpfs` для `/tmp`, no-new-privileges.
Geheimnisse: nicht in Bildern; Verwenden Sie den K8s/vault/docker Secrets Manager.
5. 2 Supply chain
SBOM (CycloneDX/SPDX) und Scannen (Trivy/Grype).
Signatur (cosign, sigstore) und Richtlinie bei pull (verify).
Update-Proben: Die Basis-Images mit CVE-Patches werden regelmäßig neu zusammengesetzt.
6) Speicher und Dateitreiber
Standardmäßig overlay2 (schnell und stabil). In rootless Umgebungen oft fuse-overlayfs.
volumes für Daten und Caches, bind-mount für Entwicklung.
Schreiben Sie nicht in '/' - verwenden Sie den Datenpfad ('/data'), trennen Sie den Zustand vom Bild.
7) Netzwerk und DNS
Netzwerk-Docker: Bridge (Standard), Host (Minimum Overhead, Port-Konflikte), none, macvlan/ipvlan (L2/L3 Integration).
DNS-Resolver Docker nimmt vom Host/daemon. json; für prod lokale Cache-Resolver konfigurieren.
In K8s wird das Netzwerk von CNI (Calico/Cilium/Flannel) betrieben. Für sidecar/mesh - Interceptions (iptables).
8) Ressourcen und QoS (cgroups v2)
Einschränkungen: „--cpus“, „--memory“, „--pids-limit“, „--cpuset-cpus“.
Stellen Sie Requests/Limits (in K8s) ein → beeinflussen Sie Planung und QoS.
Überwachen Sie OOMKilled, throttling, latency spikes aufgrund von GC/IO.
bash docker run --cpus=1. 5 --memory=512m --pids-limit=256 --read-only --tmpfs /tmp:rw,size=64m...
9) Protokolle und Beobachtbarkeit
Protokolltreiber: 'json-file' (mit Rotation), 'journald', 'gelf', 'awslogs', 'syslog'.
Konfigurieren Sie die Rotation:json
{ "log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"5"} }
Metriken: Docker Engine API, cAdvisor, Node-Exporteure; Tracing über einen Agenten in einem Container oder Sidecar.
10) Register und Authentifizierung
Private Register: ECR/GCR/ACR/Harbor/GitHub Container Registry.
Rate-limits Docker Hub; Verwenden Sie Spiegel/Caches (Registry-Cache).
Richtlinie retention/immutable tags, Replikation zwischen Regionen.
'docker login' nicht in Skripten speichern; Verwenden Sie CI-Geheimnisse und OIDC-Föderation.
11) docker-compose vs orchestrators
Compose - Lokale Entwicklungs-/Integrationsstände.
Прод: Kubernetes (Deployment/StatefulSet/DaemonSet, Ingress, Secrets, PVC) с containerd/CRI-O; Sicherheits- und Rollout-Strategien.
Swarm ist veraltet für große Verkäufe, geeignet für einfache Cluster.
yaml version: "3. 9"
services:
api:
build:.
ports: ["8080:8080"]
environment: ["DB_URL=postgres://pg/DB"]
depends_on: ["pg"]
pg:
image: postgres:16-alpine volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: {} }
12) Healthcheck, Start/Stopp, graceful shutdown
Verwenden Sie' HEALTHCHECK 'mit Timeouts und Einschränkungen für' retries'.
Richtig graceful: Fangen Sie SIGTERM, beenden Sie eingehende, schließen Sie Verbindungen, dann verlassen Sie.
В K8s: `preStop` hook + `terminationGracePeriodSeconds`, readiness перед liveness.
13) Best Practices nach Sprachen/Stacks (Zusammenfassung)
Knoten: 'npm ci', 'NODE _ ENV = Produktion', dev-deps in der Laufzeit ausschalten, '--heapsnapshot' aus, 'uWS/GZip' hinter dem L7-Proxy.
Python: Räder, 'gunicorn --graceful-timeout', 'GTHREADS '/' UVICorn' über CPU, speichern venv nicht unnötig innerhalb einer gemeinsamen Schicht.
Go: CGO off (wenn möglich), '-ldflags =' -s -w', distroless/static, 'GOMAXPROCS' von cgroups.
Java: Layer-JAR, '-XX: MaxRAMPercentage', CDS/Layered JAR für den Cache.
14) Supply Chain und Image-Politik
Generit SBOM auf CI, speichern Sie neben dem Artefakt.
Scannen Sie die Bilder auf jedem Fluß; Tor zu kritischen CVEs.
Signieren Sie die Bilder (cosign), aktivieren Sie den Policy Controller (K8s Kyverno/Conftest/Gatekeeper).
Trennen Sie Build und Run-Konto/Netzwerk; Zwischenspeichern von Abhängigkeiten in der privaten Registrierung.
15) Anti-Muster
„: neueste“ in der Produktion; Keine unbeweglichen Tags.
Montage "innerhalb des Prod-Hosts' ohne Isolierung; Speichern von Geheimnissen in Dockerfile.
Läuft unter root, '--privileged', breite Kapazitäten.
Dicke Bilder (> 1-2 GB), keine. dockerignore.
Die init-Logik in ENTRYPOINT über die Shell-Form → Signalprobleme.
Schreiben Sie persistente Daten in eine Containerebene anstelle eines Volumens.
Healthcheck macht teure Anfragen an die Prod-DB.
16) Implementierung Checkliste (0-45 Tage)
0-10 Tage
Standardisieren Sie Dockerfile (multi-stage, .dockerignore, LABEL, pinned base).
Aktivieren Sie BuildKit/buildx, Cachemounts für Paketmanager.
Gehen Sie auf non-root und 'seccomp '/AppArmor/SELinux Standardprofile.
11-25 Tage
Laufzeitbilder minimieren (alpine/distroless), mit Protokollen aufräumen (Rotation).
Konfigurieren Sie Ressourcenlimits, healthchecks, korrekte PID 1/tini.
Heben Sie die private Registrierung/den Cache an, schließen Sie den CVE-Scanner und die SBOM-Generation an.
26-45 Tage
Geben Sie die Bildsignatur und die Zulassungsrichtlinie in den Cluster ein.
Organisieren Sie Multi-Arch (amd64/arm64) für die gewünschten Dienste.
Dokumentieren Sie das Build/Release-Runbook, den Bericht zu Abmessungen/Schwachstellen/Build-Zeiten.
17) Reifegradkennzahlen
Immutable Tags und reproduzierbare Builds für ≥ 95% der Dienste.
Die durchschnittliche Laufzeitbildgröße beträgt <200-300 MB (pro Stapel).
100% der Prod-Container sind Non-Root, mit eingeschränkten Kapazitäten und Read-Only FS.
SBOM und CVE-Scan für jeden Push; Kritische CVEs werden → blockiert.
Signieren von Bildern und Policy-Enforcement in Umgebungen.
Kaltstartzeit des Containers ≤ Ziel-SLO (z.B. 2-5 sec), korrekter graceful Shutdown.
18) Schlussfolgerung
Containerisierung im Erwachsenenalter sind OCI-Standards + Montagedisziplin + Standardsicherheit + Beobachtbarkeit und Lieferpolitik. Verwenden Sie Multi-Stage und BuildKit, minimieren Sie Laufzeitabbilder, führen Sie Non-Root unter strengen Profilen aus, erfassen Sie Tags, scannen und signieren Sie, behalten Sie Protokolle/Ressourcen/Netzwerk unter Kontrolle. So werden Container zu einem vorhersehbaren und überschaubaren Rückgrat Ihrer Plattform - von der Entwicklung bis zur Produktion.