集裝箱化:Docker和OCI
集裝箱化: Docker和OCI
1)OCI的基本概念和標準
OCI Image Spec是一種圖像格式(清單,config,層,多拱索引)。
OCI運行時規格-如何運行容器(bundle, 'config.json`);實現:runc以及gVisor,Kata Containers。
OCI Distribution Spec-與註冊表交互(推入/推送、授權)。
Docker=UX和OCI周圍的生態系統:Dockerfile/BuildKit/CLI/Compose/Hub。在Kubernetes中,Docker引擎被containerd/CRI-O取代,但映像格式相同。
2)映像: 圖層,標簽,元數據
Образ = слои (layered filesystem) + config (entrypoint/cmd/env/labels) + manifest.
標簽:不要在銷售中使用「:最新」;pinning':1.21.3',git-SHA或日期+SHA。
LABEL: 所有者,聯系人,vcs-url, org.opencontainers.(title, description, revision, source).
Multi-arch:宣言索引為「amd 64/arm64」提供了正確的選擇。
3)組裝: Dockerfile,BuildKit,多階段
3.1項原則
最大限度地減少層,鎖定版本,清潔批處理管理器的腰包。
首先復制manifest/lock文件,然後「RUN install deps」-改進緩存。
.dockerignore是強制性的(排除'.git',文物,秘密)。
Distroless/alpine/最低基數樣本是首選。
3.2 BuildKit籌碼
並行法案,組件中的秘密(「-secret」),緩存山,用於多拱形的buildx。
緩存山示例:dockerfile syntax=docker/dockerfile:1. 6
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements. txt
3.3多階段示例
Go(靜態斜線,無分布):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(沒有dev-deps的prod層):
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)最小映像,PID 1和信號
Distroless-較小的攻擊面,沒有外殼/數據包管理器。
PID 1必須正確地滾動信號,否則「僵屍過程」。使用執行表格中的「ENTRYPOINT」和tini/init:dockerfile
ENTRYPOINT ["tini","--","/app"]
「HEALTHCHECK」明智地設置(頻率/計時,沒有額外的負載)。
5)集裝箱證券化
5.1政策與強硬
Non-root (USER), rootless Docker/containers.
Capabilities:清理更多('-cap-drop=ALL-cap-add=NET_BIND_SERVICE'等)。
seccomp/AppArmor/SELinux:啟用默認配置文件或嚴格配置文件。
Read-only FS + `tmpfs` для `/tmp`, no-new-privileges.
秘密:不在圖像中;從Secrets Manager (K8s/vault/docker secrets)裝載。
5.2 Supply chain
SBOM(CycloneDX/SPDX)和掃描(Trivy/Grype)。
標題(cosign, sigstore)和策略(已驗證)。
更新排練:定期重新拍攝帶有CVE補丁的基本圖像。
6)存儲和文件驅動程序
默認值為overlay2(快速穩定)。在rootless環境中,通常是fuse-overlayfs。
用於數據和緩存的卷,用於開發的bind卡口。
不要寫入「/」-使用數據路徑(「/data」),將狀態與映像分開。
7)網絡和DNS
網絡的Docker: bridge(默認),host(最小值、端口沖突),none, macvlan/ipvlan (L2/L3集成)。
Docker的DNS 解析器取自主機/daemon。json;為prod配置本地kesh-resolvers。
K8s,該網絡由CNI(Calico/Cilium/Flannel)運營。對於sidecar/mesh,-攔截(iptables)。
8)資源和QoS (cgroups v2)
限制:「-cpus」,「-mmory」,「--pids-limit」,「--cpuset-cpus」。
設置requests/limits (K8s) →影響計劃和QoS。
監視OOMKilled、throttling、latency spikes由於GC/IO。
bash docker run --cpus=1. 5 --memory=512m --pids-limit=256 --read-only --tmpfs /tmp:rw,size=64m...
9)Logi和可觀察性
Logs驅動程序:「json-file」(輪換),「journald」,「gelf」,「awslogs」,「syslog」。
配置輪換:json
{ "log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"5"} }
度量:Docker Engine API,cAdvisor,node出口商;通過容器或sidecar中的代理進行跟蹤。
10)註冊和身份驗證
私人登記冊:ECR/GCR/ACR/Harbor/GitHub集裝箱登記冊。
Rate-limits Docker Hub;使用鏡像/腰果(registry-cache)。
Retention/immutable tags策略,跨區域復制。
「docker login」不存儲在腳本中;使用CI秘密和OIDC聯盟。
11) docker-compose vs管弦樂隊
Compose-本地開發/集成展位。
Прод: Kubernetes (Deployment/StatefulSet/DaemonSet, Ingress, Secrets, PVC) с containerd/CRI-O;安全策略和滾動策略。
Swarm已過時用於大型銷售,適用於簡單的集群。
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,開始/停止,graceful shutdown
使用「HEALTHCHECK」和「retries」的時間限制。
正確的graceful:捕獲SIGTERM,完成輸入,關閉連接,然後退出。
В K8s: `preStop` hook + `terminationGracePeriodSeconds`, readiness перед liveness.
13)語言/堆棧最佳實踐(摘要)
節點:"npm ci","NODE_ENV=生產",在運行時關閉dev-deps,"--heapsnapshot'off,"uWS/GZip"代表L7代理。
Python:wheels,「gunicorn -graceful-timeout」,CPU的「GTHREADS」/「UVICorn」,無需在公共層中存儲venv。
Go:CGO off(如果可以的話),'-ldflags='-s -w',distroless/static,'GOMAXPROCS' by cgroups。
Java:分層JAR,「-XX:MaxRAMPercentage」,CDS/分層 JAR用於緩存。
14)供應鏈和映像策略
在CI上生成SBOM,在人工制品旁邊保存。
掃描每個大炮上的圖像;關鍵的CVE門。
簽名映像(cosign),啟用策略控制器(K8s-Kyverno/Conftest/Gatekeeper)。
共享構建和運行帳戶/網絡;在私有註冊表中緩存依賴項。
15)反模式
「:最新」的銷售;沒有固定標簽。
在沒有隔離的情況下在「prod主機內部」組裝;在Dockerfile中存儲秘密。
在root下運行,「--privileged」,廣泛的機會。
厚圖像(>1-2GB),缺席。dockerignore.
ENTRYPOINT中的init邏輯通過殼形式→信號問題。
將永久數據寫入容器層而不是卷。
Healthcheck對prod-DB提出了昂貴的要求。
16)實施清單(0-45天)
0-10天
標準化Dockerfile(多階段,.dockerignore, LABEL, pinned base)。
啟用BuildKit/buildx(用於軟件包管理器的緩存)。
轉到默認的非根和「seccomp」/AppArmor/SELinux配置文件。
11-25天
最大程度地減少運行時映像(alpine/distroless),重新排列日誌順序(旋轉)。
設置資源限制,健康檢查,正確的PID 1/tini。
提高私有註冊表/kesh,連接CVE掃描儀和SBOM生成。
26-45天
在群集中輸入映像簽名和公差策略。
為所需服務組織多方(amd64/arm64)。
記錄裝配/發行版runbook、大小/漏洞/裝配時間報告。
17)成熟度量
≥ 95%的服務具有固定標簽和可重現組件。
平均運行時映像大小小於200-300 MB(按堆棧)。
100% prod容器是非根容器,其容量有限且僅讀取FS。
每個push的SBOM和CVE掃描;關鍵的CVE →被阻止。
環境中的圖像簽名和策略實現。
容器的冷啟動時間≤目標SLO(例如2-5秒),正確的graceful shutdown。
18)結論
成人容器化是OCI+裝配紀律+默認安全+可觀察性和交付策略的標準。使用multi-stage和BuildKit,最大限度地減少運行時映像,在嚴格的配置文件下運行非根映像,捕獲標簽,掃描和簽名,並控制日誌/資源/網絡。因此,容器將成為您平臺的可預測和可管理的基礎-從開發到生產。