Contenitore Docker e OCI
Contenitore Docker e OCI
1) Nozioni di base e standard OCI
OCI Immagine Spec è un formato di immagini (manifesto, config, livelli, index per multi-arch).
OCI Runtime Spec - Come avviare un contenitore ('bundle,' config. json`); L'implementazione è runc e gVisor, Kata Containers.
OCI Distribuzione Spec - Interazione con i registri (push/pull, autorizzazione).
Docker = UX e l'ecosistema intorno a OCI: Dockerfile/BuildKit/CLI/Compose/Hub. In Kubernets Docker Engine è stato sostituito con containerd/CRI-O, ma il formato delle immagini è uguale.
2) Immagini: livelli, tag, metadati
Образ = слои (layered filesystem) + config (entrypoint/cmd/env/labels) + manifest.
Tag: non usare «: latest» in vendita; pinning ': 1. 21. 3 ', git-SHA o data + SHA.
LABEL - Proprietario, contatto, URL vcs, org. opencontainers. (title, description, revision, source).
Multi-arch: il manifesto indice dà l'opzione corretta per'amd64/arm64 '.
3) Assemblaggio: dockerfile, BuildKit, multi-stage
3. 1 Principi
Ridurre al minimo i livelli, fissare le versioni, pulire le caselle dei gestori batch.
Prima copia i file manifest/lock, poi "RUN install deps'migliora la cache.
.dockerignore è obbligatorio (escludere «.git», manufatti, segreti).
Sono preferiti i campioni distroless/alpine/basi minime.
3. 2
Bildi paralleli, segreti nell'assieme ('--secret'), cache mount, buildx per multi-arch.
Esempio di cache mount:dockerfile syntax=docker/dockerfile:1. 6
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements. txt
3. 3 esempi Multi-stage
Go (staticamente lineare, 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 (livello prod senza def-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) Immagini minime, PID 1 e segnali
Distroless - Meno superficie di attacco, niente shell/gestore batch.
Il PID 1 deve far scorrere correttamente i segnali, altrimenti i processi zombie. Usa «ENTRYPOINT» nel modulo exec e tini/init incorporato:dockerfile
ENTRYPOINT ["tini","--","/app"]
«HEALTHCHECK» è ragionevole (frequenza/timeout, senza sovraccarico).
5) Sicurezza dei contenitori
5. 1 Regole e hardening
Non-root (USER), rootless Docker/containers.
Capabilities: rimuovi il superfluo ('--cap-drop = ALL --cap-add = NET _ BIND _ SERVICE', ecc.).
seccomp/AppArmor/SELinux: includere profili predefiniti o rigorosi.
Read-only FS + `tmpfs` для `/tmp`, no-new-privileges.
Non nelle immagini; Montare da Gestione segreti (K8s/vault/docker secret).
5. 2 Supply chain
SBOM (CycloneDX/SPDX) e scansione (Trivy/Grype).
Firma (cosign, sigstore) e criterio pull (verify).
Prove di aggiornamento: le immagini di base con patch CVE vengono ripetute regolarmente.
6) Memorizzazione e driver di file
Per impostazione predefinita, overlay2 (veloce e stabile). In ambienti rootless spesso fuse-overlayfs.
volumi per dati e cache, bind-mount per lo sviluppo.
Non scrivere in/- Usa il percorso dati ('/data '), separa lo state dall'immagine.
7) Rete e DNS
Rete docker: bridge (predefinito), host (minimo overhead, conflitti di porte), none, macvlan/ipvlan (L2/L3 integrazione).
Il resolver DNS Docker viene prelevato dall'host/daemon. json; per prod, personalizzare i risvolti di cache locali.
In K8s, la rete gestisce CNI (Calico/Cilium/Flannel). Per sidecar/mesh - intercettazioni (iptable).
8) Risorse e QoS (cgrups v2)
Vincoli: '--cpus',' --memori', '-pids-limit', '-cpuset-cpus'.
Installa i richiesti/limits (in K8s) → influisce sulla pianificazione e la QoS.
Monitora OMKilled, throttling, latency spikes a causa di GC/IO.
bash docker run --cpus=1. 5 --memory=512m --pids-limit=256 --read-only --tmpfs /tmp:rw,size=64m...
9) Loghi e osservabilità
I driver di login sono «json-file», «journald», «gelf», «awslogs», «syslog».
Impostare la rotazione:json
{ "log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"5"} }
Metriche: API Docker Engine, cAdvisor, node-esportatori; traccia tramite agente in un contenitore o sidecar.
10) Registri e autenticazione
Registri privati: ECR/GCR/ACR/Harbor/GitHub Container Registry.
Rate-limits Docker Hub; Usa gli specchi/caselle (registry-cache).
Regola di retentione/immutable tags, replica tra regioni.
«docker login» non memorizzare negli script; Utilizzare i segreti CI e la federazione OIDC.
11) orchestratori docker-compose vs
Compose - design locale/stand di integrazione.
Прод: Kubernetes (Deployment/StatefulSet/DaemonSet, Ingress, Secrets, PVC) с containerd/CRI-O; Politiche di sicurezza e strategie rollout.
Swarm è obsoleto per grandi vendite, adatto per cluster semplici.
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, partenza/stop, graceful shutdown
Usa HEALTHCHECK con timeout e restrizioni retries.
Graceful corretto: cattura SIGTERM, termina in entrata, chiudi le connessioni e poi esci.
В K8s: `preStop` hook + `terminationGracePeriodSeconds`, readiness перед liveness.
13) Best practices per lingue/vetro (riepilogo)
Node: 'npm ci', 'NODE _ ENV = production', 'spegne i devs-deps in runtime,' --heapsnapshot 'off', 'uWS/GZip' dietro il proxy L7.
Python: wheels, 'gunicorn --graceful-timeout', 'GTHREADS'/' UVICorn' secondo CPU, non memorizzare il venv all'interno di un livello condiviso senza necessità.
Go: CGO off (se possibile), '-ldflags =' -s -w ', distroless/static,' GOMAXPROCS ',' ggrups '.
Java: JAR strato, '- XX:MaxRAMPercentage', CDS/Layered JAR per la cache.
14) Supply chain e criteri di immagine
Genetica SBOM su CI, conserva accanto al manufatto.
Scansionare le immagini su ogni cannone; gate su CVE critici.
Firma le immagini (cosign), attiva policy controller (K8s - Kyverno/Conftest/Gatekeeper).
Separare build e run insegne/reti; memorizzare le dipendenze nel registro privato.
15) Anti-pattern
«: latest» in vendita; nessun tag immutabile.
Assemblaggio all'interno del prod-host senza isolamento; conservazione di segreti in Dockerfile.
Avvia sotto root, '--privileged', ampi capabilities.
Immagini spesse (> 1-2 GB), nessuna. dockerignore.
La logica init di ENTRYPOINT attraverso la forma shell ha evidenziato problemi di segnalazione.
Scrivere dati permanenti in un livello contenitore anziché volume.
Healthcheck che esegue costose richieste di prod-database.
16) Assegno foglio di implementazione (0-45 giorni)
0-10 giorni
Standardizza Dockerfile (multi-stage, .dockerignore, LABEL, pinned base).
Abilita il BuildKit/buildx, cache mount per i gestori pacchetti.
Vai ai profili predefiniti non-root e 'seccomp '/'.
11-25 giorni
Minimizza le immagini runtime (alpine/distroless), riordina i fogli (rotazione).
Configura i limiti di risorse, healthchecks, PID corretto 1/tini.
Alzare il registro/cash privato, collegare lo scanner CVE e la generazione SBOM.
26-45 giorni
Immettere la firma dell'aspetto e il criterio di tolleranza nel cluster.
Organizza multi-arch (amd64/arm64) per i servizi appropriati.
Documentare il runbook dell'assieme/rilascio, il report quote/vulnerabilità/tempo di assemblaggio.
17) Metriche di maturità
Tag immutabili e assemblaggi riproducibili per il 95% dei servizi.
Dimensioni medie dell'immagine runtime <200-300 MB (in vetro).
100% dei contenitori prod - no-root, con capabilities limitate e read-only FS.
SBOM e scansione CVE per ogni push; i CVE critici vengono bloccati.
Firma immagini e policy-enforcement negli ambienti.
Ora di partenza fredda del contenitore di destinazione SLO (ad esempio, 2-5 secondi), corretta graceful shutdown.
18) Conclusione
Container per adulti - standard OCI + disciplina di assemblaggio + sicurezza predefinita + osservabilità e regole di spedizione. Usate multi-stage e BuildKit, minimizzate le immagini runtime, eseguite non-root sotto profili rigorosi, fissate i tag, scansionate e firmate, tenete i fogli/risorse/rete sotto controllo. In questo modo i contenitori saranno la base prevedibile e gestibile della vostra piattaforma, dal progettista alla produzione.