集装箱化: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,最大限度地减少运行时映像,在严格的配置文件下运行非根映像,捕获标签,扫描和签名,并控制日志/资源/网络。因此,容器将成为您平台的可预测和可管理的基础-从开发到生产。