强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

18 - 最佳实践

18 - 最佳实践

镜像瘦身、安全扫描、生产环境部署规范,以及 Kubernetes 入门导引。


18.1 镜像瘦身

选择最小基础镜像

基础镜像大小包含内容
ubuntu:22.04~77MB完整 Ubuntu 系统
debian:bookworm-slim~75MB精简 Debian
alpine:3.19~7MB最小 Linux 发行版
python:3.11~1GBPython + 完整系统
python:3.11-slim~125MBPython + 精简系统
python:3.11-alpine~50MBPython + Alpine
golang:1.22~800MBGo + 完整系统
gcr.io/distroless/static~2MB仅 CA 证书和时区数据

多阶段构建

# ---- 构建阶段 ----
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server .

# ---- 最终阶段 ----
FROM gcr.io/distroless/static-debian12
COPY --from=builder /server /server
ENTRYPOINT ["/server"]
# 对比镜像大小
docker images my-app
# REPOSITORY   TAG           SIZE
# my-app       single-stage  1.2GB    ← 单阶段
# my-app       multi-stage   15MB     ← 多阶段

减少镜像层数

# ❌ 多个 RUN 产生多层
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y wget
RUN rm -rf /var/lib/apt/lists/*

# ✅ 合并为一层,最后清理
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl \
        wget \
        ca-certificates && \
    rm -rf /var/lib/apt/lists/*

使用 .dockerignore

# .dockerignore
.git
node_modules
__pycache__
*.pyc
.env
*.md
Dockerfile
docker-compose*.yml
dist
build
coverage
.vscode
.idea

镜像瘦身技巧汇总

技巧效果说明
多阶段构建⭐⭐⭐⭐⭐分离构建和运行环境
Alpine 基础镜像⭐⭐⭐⭐从 77MB 降到 7MB
Distroless 镜像⭐⭐⭐⭐仅包含运行时,无 shell
合并 RUN 层⭐⭐⭐减少镜像层数
清理缓存⭐⭐⭐删除包管理器缓存
.dockerignore⭐⭐⭐避免发送无关文件
--no-install-recommends⭐⭐不安装推荐包
Go 静态编译⭐⭐⭐⭐⭐CGO_ENABLED=0 无依赖

使用 dive 分析镜像

# 安装 dive
# https://github.com/wagoodman/dive

# 分析镜像层
dive nginx:alpine

# dive 界面:
#   左侧: 镜像层列表
#   右侧上: 选中层的文件变更
#   右侧下: 最终文件系统
#   底部: 镜像效率评分

18.2 安全扫描

Docker Scout

# 快速概览
docker scout quickview nginx:alpine

# 详细漏洞报告
docker scout cves nginx:alpine

# 仅查看高危漏洞
docker scout cves --only-severity critical,high nginx:alpine

# 比较两个镜像
docker scout compare nginx:1.25-alpine nginx:1.24-alpine

# 推荐修复版本
docker scout recommendations nginx:alpine

# SBOM(软件物料清单)
docker scout sbom nginx:alpine

Trivy

# 扫描镜像漏洞
trivy image nginx:alpine

# 仅扫描高危和严重漏洞
trivy image --severity HIGH,CRITICAL nginx:alpine

# 以 JSON 格式输出
trivy image --format json --output results.json nginx:alpine

# 扫描 Dockerfile
trivy config Dockerfile

# 扫描文件系统
trivy fs --security-checks vuln,config .

# 作为 CI/CD 中的门禁
trivy image --exit-code 1 --severity CRITICAL my-app:latest

漏洞管理策略

漏洞严重等级:
  CRITICAL (严重)  → 必须立即修复,阻断部署
  HIGH (高危)      → 24 小时内修复
  MEDIUM (中危)    → 1 周内修复
  LOW (低危)       → 下次版本修复

处理流程:
  1. CI/CD 中自动扫描
  2. CRITICAL/HIGH 阻断部署
  3. 查看修复建议(升级基础镜像/依赖)
  4. 修复后重新构建和扫描
  5. 记录已知漏洞的例外(accepted risk)

18.3 生产环境规范

Dockerfile 规范

# ✅ 生产环境 Dockerfile 规范

# 1. 使用官方最小基础镜像
FROM python:3.11-slim-bookworm

# 2. 设置元数据
LABEL maintainer="[email protected]"
LABEL version="1.0.0"
LABEL description="My application"

# 3. 设置工作目录
WORKDIR /app

# 4. 安装系统依赖(合并层 + 清理缓存)
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        libpq-dev \
        curl && \
    rm -rf /var/lib/apt/lists/*

# 5. 复制依赖文件(利用缓存)
COPY requirements.txt .

# 6. 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt

# 7. 创建非 root 用户
RUN addgroup --system appgroup && \
    adduser --system --ingroup appgroup appuser

# 8. 复制应用代码
COPY --chown=appuser:appgroup . .

# 9. 切换到非 root 用户
USER appuser

# 10. 声明端口
EXPOSE 8000

# 11. 健康检查
HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=10s \
    CMD curl -f http://localhost:8000/health || exit 1

# 12. 设置停止信号
STOPSIGNAL SIGTERM

# 13. 启动命令(exec 格式)
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"]

运行时安全规范

# ✅ 生产环境容器运行规范
docker run -d \
    --name my-app \
    --user 1000:1000 \
    --read-only \
    --tmpfs /tmp:rw,noexec,nosuid,size=100m \
    --cap-drop ALL \
    --cap-add NET_BIND_SERVICE \
    --security-opt no-new-privileges \
    --security-opt seccomp=default.json \
    --memory 512m \
    --memory-reservation 256m \
    --cpus 1.0 \
    --pids-limit 100 \
    --restart unless-stopped \
    --health-cmd "curl -f http://localhost:8000/health || exit 1" \
    --health-interval 30s \
    --log-driver json-file \
    --log-opt max-size=10m \
    --log-opt max-file=3 \
    -p 8000:8000 \
    my-app:1.0.0

Compose 生产配置

services:
  app:
    image: my-app:1.0.0  # 使用具体版本,不要用 latest
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=100m
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 128M
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - app-net

networks:
  app-net:
    driver: bridge

18.4 镜像标签策略

# 语义化版本 (SemVer)
docker build -t my-app:1.0.0 -t my-app:1.0 -t my-app:1 -t my-app:latest .

# Git commit hash
GIT_SHA=$(git rev-parse --short HEAD)
docker build -t my-app:sha-${GIT_SHA} .

# CI/CD 构建
BUILD_DATE=$(date +%Y%m%d)
BUILD_NUM=${BUILD_NUMBER:-local}
docker build -t my-app:${BUILD_DATE}-${BUILD_NUM} .
标签用途是否推荐用于生产
1.0.0正式发布版本
1.0次版本(会更新)
sha-abc1234CI/CD 构建标识
latest开发/测试
develop开发分支
stable稳定版(可变)⚠️ 谨慎使用

18.5 日志规范

// 结构化日志(JSON 格式)
{
  "timestamp": "2024-01-01T12:00:00.000Z",
  "level": "info",
  "message": "User login successful",
  "service": "auth-service",
  "request_id": "abc-123",
  "user_id": "42",
  "duration_ms": 150
}
字段说明
timestampISO 8601 时间戳
level日志级别:debug, info, warn, error
message日志消息
service服务名称
request_id请求追踪 ID
error错误详情(仅 error 级别)

18.6 监控规范

必要监控指标

类别指标告警阈值
容器CPU 使用率> 80% 持续 5 分钟
容器内存使用率> 85%
容器重启次数> 3 次/小时
容器健康检查失败连续 3 次
宿主机磁盘使用率> 85%
宿主机磁盘 I/O 等待> 20%
应用请求延迟 P99> 1 秒
应用错误率> 1%

18.7 备份策略

#!/bin/bash
# docker-backup.sh — Docker 数据备份脚本

BACKUP_DIR="/backup/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"

# 备份所有命名卷
for volume in $(docker volume ls -q); do
    echo "Backing up volume: $volume"
    docker run --rm \
        -v "$volume":/source:ro \
        -v "$BACKUP_DIR":/backup \
        alpine:latest \
        tar czf "/backup/volume-${volume}.tar.gz" -C /source .
done

# 备份 compose 配置
cp /opt/myapp/docker-compose.yml "$BACKUP_DIR/"
cp /opt/myapp/.env "$BACKUP_DIR/" 2>/dev/null

# 保留最近 7 天的备份
find /backup -maxdepth 1 -mtime +7 -exec rm -rf {} \;

echo "Backup completed: $BACKUP_DIR"

18.8 Kubernetes 入门导引

为什么需要 Kubernetes

场景Docker ComposeDocker SwarmKubernetes
单机开发
小型生产⚠️
中型生产
大型生产
多云混合
自动扩缩容
学习曲线

K8s 核心概念

Kubernetes 资源模型:
  ┌────── Cluster ──────┐
  │                      │
  │  ┌──── Node ────┐   │
  │  │               │   │
  │  │  ┌─── Pod ───┐│   │
  │  │  │ Container ││   │
  │  │  │ Container ││   │
  │  │  └───────────┘│   │
  │  │               │   │
  │  │  ┌─── Pod ───┐│   │
  │  │  │ Container ││   │
  │  │  └───────────┘│   │
  │  └───────────────┘   │
  │                      │
  │  ┌──── Node ────┐   │
  │  │  ┌─── Pod ───┐│   │
  │  │  │ Container ││   │
  │  │  └───────────┘│   │
  │  └───────────────┘   │
  └──────────────────────┘

核心资源:
  Pod          → 最小部署单元(1+ 容器)
  Deployment   → 管理 Pod 副本和滚动更新
  Service      → 网络服务发现和负载均衡
  ConfigMap    → 配置数据
  Secret       → 敏感数据
  Ingress      → HTTP(S) 路由
  PV/PVC       → 持久化存储
  Namespace    → 资源隔离

Docker Compose → Kubernetes 迁移

# docker-compose.yaml
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    environment:
      - NODE_ENV=production
    depends_on:
      - api

  api:
    image: my-api:v1
    ports:
      - "8080:3000"
    environment:
      - DB_HOST=db
# 等效的 Kubernetes 配置
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: my-api:v1
          ports:
            - containerPort: 3000
          env:
            - name: DB_HOST
              value: "db"

Kompose:自动转换工具

# 安装 kompose
# https://kompose.io/

# 将 docker-compose.yaml 转换为 Kubernetes 资源
kompose convert

# 直接部署到 K8s 集群
kompose up

# 清理
kompose down

本地 K8s 学习环境

工具说明适用场景
Minikube单节点 K8s 集群本地开发学习
kindDocker 中运行 K8sCI/CD 测试
k3s轻量级 K8s边缘计算、IoT
Docker Desktop内置 K8smacOS/Windows 开发
# 使用 kind 创建本地集群
kind create cluster --name my-cluster

# 使用 kubectl 操作
kubectl get nodes
kubectl get pods -A

# 部署应用
kubectl apply -f deployment.yaml
kubectl get pods
kubectl logs -f <pod-name>

# 删除集群
kind delete cluster --name my-cluster

18.9 综合检查清单

镜像检查清单

  • 使用官方最小基础镜像
  • 多阶段构建分离构建和运行
  • 固定镜像版本标签
  • 使用 .dockerignore 排除无关文件
  • 非 root 用户运行
  • 包含健康检查
  • 无已知高危漏洞(扫描通过)
  • 镜像大小合理(< 100MB 理想)

运行时检查清单

  • 设置内存和 CPU 限制
  • 设置 PID 限制
  • 使用只读文件系统
  • 禁用特权模式
  • 仅添加必要 capabilities
  • 启用 no-new-privileges
  • 配置日志轮转
  • 设置重启策略
  • 网络隔离(自定义网络)

CI/CD 检查清单

  • 自动化构建和测试
  • 镜像漏洞扫描
  • 使用构建缓存加速
  • 语义化版本标签
  • 安全存储敏感信息(Secrets)
  • 自动化部署(至少到 staging)
  • 生产部署需审批

生产环境检查清单

  • 监控告警(Prometheus + Grafana)
  • 集中日志(Loki / ELK)
  • 数据备份策略
  • 灾难恢复计划
  • 安全扫描定期执行
  • 镜像仓库(Harbor)
  • 文档化运维手册

18.10 学习路线图

Docker 学习路线:
  初级 (1-2 周):
    ├── 理解容器概念
    ├── 掌握 Docker 基本命令
    ├── 编写简单 Dockerfile
    └── 使用 Docker Compose

  中级 (2-4 周):
    ├── 深入理解镜像分层和缓存
    ├── 多阶段构建优化
    ├── 网络模型和存储方案
    ├── CI/CD 集成
    └── 基本安全加固

  高级 (4-8 周):
    ├── 生产环境部署规范
    ├── 监控和日志方案
    ├── 安全扫描和合规
    ├── Swarm 集群管理
    └── Kubernetes 入门

  专家:
    ├── Kubernetes 深入
    ├── 服务网格 (Istio)
    ├── GitOps (ArgoCD)
    ├── 平台工程
    └── 成本优化

要点回顾

要点核心内容
镜像瘦身多阶段构建 + Alpine/distroless + .dockerignore
安全扫描Docker Scout / Trivy 集成到 CI/CD
生产规范非 root 运行、资源限制、只读文件系统、日志轮转
标签策略语义化版本,避免 latest 用于生产
K8s 导引Kompose 转换、本地集群学习、核心资源理解

注意事项

持续优化: Docker 最佳实践是演进的。定期回顾和更新 Dockerfile、Compose 配置和安全策略。

不要过度优化: 开发环境优先考虑效率,生产环境才需要严格执行安全和性能规范。

社区资源: 关注 Docker 官方博客、CNCF 项目和安全公告,保持知识更新。


恭喜完成!

🎉 你已经完成了 Docker 完全指南的全部 18 章学习。

回顾你的学习成果:
  ✅ 理解容器技术原理和 OCI 标准
  ✅ 掌握 Docker 安装、配置和镜像管理
  ✅ 熟练编写 Dockerfile 和多阶段构建
  ✅ 掌握网络模型和数据持久化
  ✅ 使用 Compose 编排多容器应用
  ✅ 了解 Swarm 集群和服务编排
  ✅ 实施安全加固和监控方案
  ✅ 集成 CI/CD 自动化流水线
  ✅ 具备故障排查能力
  ✅ 了解 Kubernetes 入门知识

下一步建议:
  1. 实战: 将自己的项目容器化
  2. 深入: 学习 Kubernetes
  3. 认证: 考取 Docker DCA 认证
  4. 社区: 参与开源项目贡献