Konteneryzacja: Docker i OCI
Konteneryzacja: Docker i OCI
1) Podstawowe koncepcje i standardy OCI
OCI Image Spec - format obrazu (manifest, konfiguracja, warstwy, indeks dla wielu łuków).
OCI Runtime Spec - jak uruchomić kontener (pakiet, 'config. json "); implementacja: runc, a także gVisor, Kata Containers.
OCI Distribution Spec - interakcja z rejestrami (push/pull, autoryzacja).
Docker = UX i ekosystem wokół OCI: Dockerfile/KeyKit/CLI/Compose/Hub. W Kubernetes, Docker Engine jest zastąpiony przez kontener/CRI-O, ale format obrazu jest taki sam.
2) Wygląd: warstwy, tagi, metadane
Овра, = Слой (warstwowy system plików) + config (entrypoint/cmd//Labels) + manifest.
Tagi: nie używać ': najnowsze' w prod; szpilki ": 1. 21. 3 ', git-SHA lub data + SHA.
ETYKIETA: właściciel, kontakt, vcs-url, org. środki odkrywkowe. (tytuł, opis, zmiana, źródło).
Multi-arch: Manifest indeksu daje właściwą opcję dla 'amd64/arm64'.
3) Budowa: Dockerfile, Kit, wielostopniowy
3. 1 Zasady
Zminimalizować warstwy, naprawić wersje, czyste bufory menedżera pakietów.
Najpierw skopiuj pliki manifestu/blokady, a następnie 'RUN install deps' - poprawia pamięć podręczną.
.dockerignore jest wymagane (z wyłączeniem '.git', artefaktów, tajemnic).
Preferowane są przykłady podstaw bezwzględnych/alpejskich/minimalnych.
3. 2 Żetony do zestawu
Równoległe buduje, sekrety w zespole ('-secret'), uchwyty pamięci podręcznej, buildx dla multi-arch.
Przykład uchwytu pamięci podręcznej:dockerfile syntax=docker/dockerfile:1. 6
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements. txt
3. 3 Przykłady wielostopniowe
Go (statycznie połączony, bezzasadny):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"]
Węzeł. js (prod-warstwa bez 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 (koło-ке, bez korzenia):
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) Minimalne obrazy, PID 1 i sygnały
Bezolbrzymia - mniejsza powierzchnia ataku, brak powłoki/menedżera pakietów.
PID 1 musi prawidłowo sygnały proxy, inaczej "procesy zombie. "Używać 'ENTRYPOINT' w postaci exec i tini/init init:dockerfile
ENTRYPOINT ["tini","--","/app"]
„HEALTHCHECK” jest rozsądne (częstotliwość/czas, bez zbędnego obciążenia).
5) Bezpieczeństwo kontenera
5. 1 Polityka i utwardzanie
Non-root (USER), bez korzeni Docker/pojemniki.
Możliwości: usuń zbędne ('--cap-drop = ALL --cap-add = NET _ BIND _ SERVICE' itp.).
seccomp/AppArmor/SELinux: Włącz domyślne lub ścisłe profile.
Tylko do odczytu FS + 'tmpfs' дла '/tmp ', bez-new-privileges.
Sekrety: nie w obrazach; montaż od kierownika sekretów K8s/vault/docker.
5. 2 Łańcuch dostaw
SBOM (CycloneDX/SPDX) i skanowanie (Trivy/Grype).
Podpis (cosign, sigstore) i zasady ciągnięcia (sprawdź).
Próby do aktualizacji: obrazy bazowe z łatami CVE są regularnie przebudowywane.
6) Sterowniki pamięci i plików
Domyślnie jest overlay2 (szybki i stabilny). W środowiskach bez korzeni, często bezpieczniki overlayfs.
woluminy danych i pamięci podręcznej, mocowanie wiązane do rozwoju.
Nie zapisuj do '/' - użyj ścieżki danych ('/data '), oddzielając stan od obrazu.
7) Sieć i system DNS
Sieci Docker: most (domyślny), host (minimalny napowietrzny, konflikty portowe), brak, macvlan/ipvlan (integracja L2/L3).
Rozdzielacz DNS Docker pobiera/demon z hosta. json; dla prod, skonfigurować lokalną pamięć podręczną rozdzielacza.
W K8s sieć jest zarządzana przez CNI (Calico/Cilium/Flannel). Dla siatki/siatki - przechwytywania (iptables).
8) Zasoby i QoS (grupy kapitałowe v2)
Ograniczenia: '--cpus', '--memory', '--pids-limit', '--cpuset-cpus'.
Ustaw żądania/limity (w K8s) → wpływa na harmonogram i QoS.
Monitor OOMKilled, throttling, latency kolce ze względu na GC/IO.
bash docker run --cpus=1. 5 --memory=512m --pids-limit=256 --read-only --tmpfs /tmp:rw,size=64m...
9) Dzienniki i obserwowalność
Sterowniki dziennika: 'json-file' (z rotacją), 'journal', 'gelf', 'awslogs',' syslog '.
Skonfiguruj obrót:json
{ "log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"5"} }
Metryki: Docker Engine API, cAdvisor, eksporterzy węzłów; śledzenie przez agenta w pojemniku lub bocznym ekranie.
10) Rejestry i uwierzytelnianie
Prywatne rejestry: ECR/GCR/ACR/Harbor/GitHub Container Registry.
Wartości graniczne Docker Hub; używać luster/pamięci podręcznej (registry-cache).
Polityka zatrzymywania/niezmiennego znakowania, powielanie między regionami.
„login docker” nie jest przechowywany w skryptach; używać tajemnic CI i federacji OIDC.
11) docker-compose vs orkiestratorzy
Kompozyt - lokalne stoiska rozwoju/integracji.
Мро, „: Kubernetes” (rozmieszczenie/Stat Set/DaemonSet, Ingress, Secrets, PVC) polityki bezpieczeństwa i strategii wdrażania.
Rój jest przestarzały do dużych sprzedaży, nadaje się do prostych klastrów.
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) Health check, start/stop, graceful shutdown
Użyj 'HEALTHCHECK' z ograniczeniami czasowymi i 'retries'.
Poprawna graceful: złapać SIGTERM, zakończyć przychodząc, zamknąć połączenia, a następnie wyjść.
Zdjêcie : 'preStop' hook + 'termοGrace Seconds', gotowoœæ мере,
13) Najlepsze praktyki według języka/stosu (streszczenie)
Węzeł: 'npm ci', 'NODE _ NA = produkcja', wyłączyć dev-deps w czasie trwania, '-heapsnapshot' off, 'uWS/GZip' za serwerem proxy L7.
Python: koła, 'gunicorn --graceful-timeout', 'GTHREADS '/' UVICorn' przez CPU, nie przechowywać niepotrzebnie venv wewnątrz wspólnej warstwy.
Go: CGO off (jeśli to możliwe), '-ldflags =' -s -w '', distroless/static, 'GOMAXPROCS' przez cgroups.
Java: warstwowy JAR, '-XX: MaxRAMPercentage', CDS/Layered JAR do pamięci podręcznej.
14) Łańcuch dostaw i polityka wizerunkowa
Generuj SBOM na CI, zapisz obok artefaktu.
Skanowanie obrazów na każdym pudle; brama do krytycznych CSU.
Zaloguj obrazy (cosign), włącz kontroler zasad (w K8s - Kyverno/Conftest/Gatekeeper).
Oddzielne rachunki budowania i uruchamiania/sieci; Zależność od pamięci podręcznej w rejestrze prywatnym.
15) Anty-wzory
„: najnowsze” w prod; brak niezmiennych znaczników.
Montaż „wewnątrz hosta produkcji” bez izolacji; przechowywanie tajemnic w Dockerfile.
Działa jako korzeń, '--privileged', szerokie możliwości.
Grube obrazy (> 1-2 GB), brak. dockerignore.
Logika init w ENTRYPOINT poprzez formę powłoki → problemy z sygnałem.
Zapisz trwałe dane do warstwy pojemnika zamiast objętości.
Healthcheck, co sprawia, że drogie wnioski do prod-DB.
16) Lista kontrolna wdrażania (0-45 dni)
0-10 dni
Standaryzacja Dockerfile (multi-stage, .dockerignore, LABEL, pinned base).
Dodaj Zestaw/buildx, uchwyty pamięci podręcznej dla menedżerów pakietów.
Przełącz na profile domyślne non-root i 'seccomp '/AppArmor/SELinux.
11-25 dni
Zminimalizuj obrazy runtime (alpejskie/bezlitosne), uporządkuj rzeczy za pomocą dzienników (obrót).
Ustaw limity zasobów, sprawdzanie zdrowia, poprawne PID 1/tini.
Podnieś prywatny rejestr/pamięć podręczną, podłącz skaner CVE i generację SBOM.
26-45 dni
Wprowadź podpis obrazu i zasady przyjmowania klastra.
Zorganizuj multi-arch (amd64/arm64) dla wymaganych usług.
Zbuduj/uwolnij dokument, zbuduj rozmiar/lukę/raport czasu.
17) Wskaźniki zapadalności
Niezmienne znaczniki i zespoły odtwarzalne dla ≥ 95% usług.
Średni rozmiar obrazu runtime wynosi <200-300 MB (ułożony).
100% kontenerów prod jest bez korzenia, z ograniczonymi możliwościami i tylko do odczytu FS.
Skan SBOM i CVE na naciśnięcie; krytyczne CZ są → zablokowane.
Podpisywanie i egzekwowanie polityki wizerunkowej w środowisku.
Czas rozruchu chłodni kontenera ≤ docelowe SLO (np. 2-5 sekund), poprawne wdzięczne zamknięcie.
18) Wniosek
Konteneryzacja dla dorosłych to standardy OCI + dyscyplina budowania + domyślne bezpieczeństwo + zasady obserwacji i dostawy. Użyj wielostopniowego zestawu, zminimalizuj obrazy runtime, uruchom non-root pod ścisłymi profilami, naprawić znaczniki, skanować i podpisać, przechowywać dzienniki/zasoby/sieć pod kontrolą. Tak więc kontenery staną się przewidywalnym i zarządzalnym fundamentem Twojej platformy - od rozwoju po produkcję.