容器解决的核心问题:环境一致性。开发、测试、生产环境完全相同,消除了"在我电脑上能跑"的困境。
虚拟机 (VM)
每个 VM 自带完整 OS,资源开销大
容器 (Container)
共享宿主内核,轻量快速
| 维度 | 虚拟机 | 容器 |
|---|---|---|
| 启动时间 | 分钟级 | 秒级(~0.5s) |
| 磁盘占用 | GB 级 | MB 级 |
| 内存开销 | 每个 VM 1-2GB+ OS | 只占应用所需 |
| 隔离性 | 强(硬件级) | 中(进程级) |
| 密度 | 每主机几个 | 每主机数百个 |
Docker 是容器的事实标准。从 2013 年发布至今,几乎改变了软件交付方式。
来源:github.com/moby/moby(Docker Engine 开源上游,2026-05)。Docker Engine 从 v29 起模块路径迁移至 github.com/moby/moby/v2。
只读模板,包含运行应用所需的一切。通过 Dockerfile 构建,分层存储。
# 查看本地镜像
docker images
# 拉取镜像
docker pull node:22-alpine
# 构建镜像
docker build -t myapp:latest .
镜像的运行实例。可创建、启动、停止、删除。每个容器是隔离的进程。
# 运行容器
docker run -d -p 3000:3000 --name app myapp:latest
# 查看运行中容器
docker ps
# 进入容器
docker exec -it app sh
容器间通信。默认 bridge 网络,自定义网络支持 DNS 解析。
# 创建自定义网络
docker network create mynet
# 容器加入网络
docker run --network mynet --name api myapi
docker run --network mynet --name db postgres
# api 容器内可通过 db:5432 访问数据库
持久化存储。容器删除后数据不丢失。
# 创建数据卷
docker volume create pgdata
# 挂载到容器
docker run -v pgdata:/var/lib/postgresql/data postgres
# 绑定挂载(开发用)
docker run -v ./src:/app/src myapp
# ---- 多阶段构建 ----
# Stage 1: 依赖安装
FROM node:22-alpine AS deps
RUN corepack enable pnpm
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod=false
# Stage 2: 构建
FROM node:22-alpine AS builder
RUN corepack enable pnpm
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN pnpm build
# Stage 3: 生产运行
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
alpine 基础镜像(~5MB vs ~1GB).dockerignore 排除无关文件pnpm install --prod 只装生产依赖output: 'standalone' 输出精简包DOCKER_BUILDKIT=1--mount=type=cachedocker buildx--cache-from type=gha# Dockerfile 中使用缓存挂载
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
# 多平台构建缓存
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
apt-get update && apt-get install -y ...
:latest 标签——不可复现--secret 或 Build Argsroot 运行应用——用 USER 指令Docker Compose 用一个 YAML 文件定义和运行多容器应用。开发环境利器。
来源:github.com/docker/compose(2026-05)。Compose v5 基于 Go 重写,v1 (Python) 已停止维护。
# compose.yaml
services:
# Next.js 前端
web:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/myapp
- REDIS_URL=redis://redis:6379
- NEXTAUTH_SECRET=dev-secret
volumes:
- ./src:/app/src # 热重载
- ./public:/app/public
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
command: pnpm dev
# PostgreSQL
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: myapp
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
# Redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redisdata:/data
# MinIO (S3 兼容存储)
minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001" # 管理面板
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- miniodata:/data
command: server /data --console-address ":9001"
# Meilisearch (搜索)
search:
image: getmeili/meilisearch:v1.8
ports:
- "7700:7700"
environment:
MEILI_MASTER_KEY: dev-master-key
volumes:
- searchdata:/meili_data
volumes:
pgdata:
redisdata:
miniodata:
searchdata:
| 命令 | 用途 |
|---|---|
docker compose up -d | 后台启动所有服务 |
docker compose down | 停止并删除容器、网络 |
docker compose down -v | 同时删除数据卷(⚠️ 数据丢失) |
docker compose logs -f web | 查看 web 服务实时日志 |
docker compose exec db psql -U postgres | 进入数据库 |
docker compose build --no-cache | 重新构建(不使用缓存) |
docker compose pull | 拉取最新镜像 |
docker compose up -d --build | 重新构建并启动 |
当你的用户使用 ARM(M1/M2 Mac、ARM 服务器)和 x86 时,需要构建多平台镜像。
来源:Docker Docs - Multi-platform builds(docs.docker.com,2026-05)。Docker Engine 29+ 默认使用 containerd image store,原生支持多平台。
# 创建多平台 builder
docker buildx create --name multiplatform --use
# 同时构建 amd64 和 arm64 并推送
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t ghcr.io/myapp:latest \
--push .
# 使用交叉编译(推荐,比 QEMU 快)
# Dockerfile 中:
FROM --platform=$BUILDPLATFORM node:22-alpine AS builder
ARG TARGETPLATFORM
ARG TARGETARCH
RUN echo "Building for $TARGETARCH"
# 用交叉编译工具链代替 QEMU 模拟
Kubernetes (K8s) 是 Google 基于 Borg 系统经验开源的容器编排平台,由 CNCF 托管。当你的 SaaS 需要高可用、自动扩缩、滚动部署时,K8s 是终极选择。
来源:github.com/kubernetes/kubernetes(2026-05)、kubernetes.io(2026-05)
Control Plane(控制面)
Worker Nodes(工作节点)
最小调度单位,包含一个或多个容器。同一 Pod 内共享网络和存储。
apiVersion: v1
kind: Pod
metadata:
name: api
spec:
containers:
- name: api
image: myapp:latest
ports:
- containerPort: 3000
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
管理 Pod 副本集,支持滚动更新和回滚。
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapp:latest
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /health
port: 3000
为 Pod 提供稳定的网络端点(ClusterIP/NodePort/LoadBalancer)。
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- port: 80
targetPort: 3000
type: ClusterIP
HTTP 路由规则,将外部流量导入 Service。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 80
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
除非你有专职运维团队,否则<强>强烈推荐托管 K8s——云厂商负责控制面维护、升级、安全补丁。
| 维度 | GKE (Google) | EKS (AWS) | AKS (Azure) | 自建 K8s |
|---|---|---|---|---|
| 控制面费用 | 免费(含 Autopilot) | $0.10/hour (~$73/月) | 免费 | 需自建 + 运维 |
| 节点费用 | 按 GCE 定价 Autopilot: 按Pod资源计费 |
按 EC2 定价 | 按 VM 定价 | 按 VPS 定价 |
| 自动升级 | ✅ 原生支持 | ✅ 需配置 | ✅ 原生支持 | ❌ 手动 |
| 集成生态 | GCP 全家桶 | AWS 全家桶 | Azure 全家桶 | 自选 |
| 学习曲线 | 低 | 中 | 中 | 高 |
| 适合场景 | 通用、ML 工作负载 | AWS 深度用户 | 企业/微软生态 | 完全自控需求 |
来源:各云厂商官方定价页(2026-05),价格可能随时调整
Red Hat 出品的 Docker 替代品。无守护进程、rootless 安全、兼容 Docker CLI。
来源:podman.io(2026-05),最新稳定版 5.8.2,Apache 2.0 许可
alias docker=podman)与 Podman 配套的构建和镜像传输工具。
# Buildah 构建
buildah bud -t myapp:latest .
# Skopeo 复制镜像
skopeo copy docker://docker.io/library/nginx:alpine \
docker://ghcr.io/myorg/nginx:alpine
VS Code 的 Dev Containers 让整个开发环境容器化——团队成员 clone 后一键启动,无需本地安装 Node/Python/PostgreSQL。
// .devcontainer/devcontainer.json
{
"name": "SaaS Dev",
"dockerComposeFile": ["../compose.yaml"],
"service": "web",
"workspaceFolder": "/app",
"features": {
"ghcr.io/devcontainers/features/node:1": { "version": "22" },
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"postCreateCommand": "pnpm install",
"forwardPorts": [3000, 5432, 6379],
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"prisma.prisma"
]
}
}
}
| 方案 | 原理 | 优势 | 劣势 |
|---|---|---|---|
| Dev Containers | VS Code + Docker | 一键启动、团队一致 | 首次构建慢、依赖 Docker |
| Gitpod | 云端开发环境 | 浏览器即可开发 | 延迟、付费 |
| GitHub Codespaces | 云端 VS Code | GitHub 深度集成 | $0.18/hour(4-core) |
| Docker Compose + 本地 IDE | 服务容器化 + 代码挂载 | 灵活、热重载 | 需要本地安装 IDE |
| 层次 | 措施 | 工具 |
|---|---|---|
| 镜像安全 | 扫描已知漏洞 | Trivy、Snyk、Grype |
| 基础镜像 | 使用最小化镜像 | distroless、alpine、chainguard |
| 运行权限 | 非 root 运行 | Dockerfile USER 指令、K8s SecurityContext |
| 密钥管理 | 不硬编码 secrets | Docker Secrets、K8s Secrets、Vault |
| 网络隔离 | 最小网络暴露 | K8s NetworkPolicy、服务网格 |
| 资源限制 | 防止资源耗尽 | K8s Resource Limits、Docker --memory |
| 镜像签名 | 验证镜像来源 | cosign、Notation |
| 运行时安全 | 检测异常行为 | Falco、Tracee |
# K8s SecurityContext 示例
securityContext:
runAsNonRoot: true
runAsUser: 1001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
Level 0:不用容器
Level 1:Docker + Compose
Level 2:Docker + 托管容器服务
Level 3:Kubernetes
Level 4:K8s + 服务网格