进阶篇 - Docker 网络与存储深入

知识库
知识库文档
/tech-stacks/docker/tutorial/进阶篇 - Docker 网络与存储深入.md

文档

前言

在入门篇中,我们学习了 Docker 的核心概念和基本操作。本篇深入两个关键子系统:网络存储。理解它们是跑好生产级容器的前提。


第一章:Docker 网络深入

1.1 五种网络驱动对比

驱动 适用场景 跨主机 DNS 隔离性
bridge 单机容器通信(默认) ✅ 内置 中等
host 高性能、直接使用宿主机网络
overlay 跨主机容器通信(Swarm)
macvlan 容器直接接入物理网络(IP/MAC 独立)
none 完全禁用网络 最高

1.2 自定义 Bridge 网络(生产推荐)

# 创建自定义网络
docker network create \
  --driver bridge \
  --subnet=172.28.0.0/16 \
  --ip-range=172.28.5.0/24 \
  --gateway=172.28.5.1 \
  my-net

# 同一网络的容器互 Ping(自动 DNS 解析)
docker run -d --name app1 --network my-net nginx
docker run -d --name app2 --network my-net alpine ping app1
# PING app1 (172.28.5.2): 56 data bytes ← 自动域名解析!

默认 bridge 网络不支持 DNS 解析,必须用 --link(已废弃)。自定义网络默认启用 DNS。

1.3 容器间通信模式

场景 1:同一自定义网络
  ContainerA ←→ ContainerB  [通过容器名直接通信]

场景 2:不同网络
  ContainerA (net1) ←→ ContainerB (net2)  [不通,需要 docker network connect]

场景 3:容器 ↔ 宿主机
  Container → host.docker.internal (macOS/Windows)
  Container → 172.17.0.1 (Linux 默认网关)

场景 4:容器 ↔ 外部服务
  默认 NAT 出站,无需配置

1.4 端口映射原理

# -p 宿主机端口:容器端口
docker run -p 8080:80 nginx

# 流量路径:
# 外部请求 → 宿主机:8080 → iptables DNAT → 容器IP:80
# 查看 iptables 规则
iptables -t nat -L DOCKER -n

1.5 网络排错工具箱

# 查看网络列表
docker network ls

# 查看网络详情(含连接容器 IP)
docker network inspect my-net

# 进容器排查
docker exec -it app1 sh
# 容器内:
nslookup app2          # 测试 DNS
ping app2              # 测试连通性
ip addr show           # 查看容器网卡
netstat -tlnp          # 查看监听端口

第二章:Docker 存储深入

2.1 三种存储类型对比

类型 数据位置 生命周期 跨容器 性能 适用场景
Volume /var/lib/docker/volumes/ 独立于容器 生产数据持久化
Bind Mount 宿主机任意路径 独立于容器 最好 开发热更新
tmpfs 内存 随容器 极佳 临时缓存/密钥

2.2 Volume 最佳实践

# 创建命名卷
docker volume create --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.100,rw \
  --opt device=:/exports/data \
  nfs-vol

# 使用卷
docker run -d \
  -v db-data:/var/lib/mysql \
  -v app-logs:/var/log/app \
  --name mysql mysql:8

# 备份卷数据
docker run --rm \
  -v db-data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/db-backup.tar.gz -C /data .

# 恢复卷数据
docker run --rm \
  -v db-data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/db-backup.tar.gz -C /data

# 卷迁移
# 1. 源主机导出
docker run --rm -v db-data:/data alpine tar czf - -C /data . >; db.tar.gz
# 2. 传输到目标主机
scp db.tar.gz target-host:
# 3. 目标主机导入
docker volume create db-data
docker run --rm -v db-data:/data -v $(pwd):/src alpine sh -c "cd /data && tar xzf /src/db.tar.gz"

2.3 Bind Mount 开发场景

# docker-compose.yml(开发模式)
services:
  web:
    image: node:20-alpine
    working_dir: /app
    command: npm run dev
    volumes:
      - ./src:/app/src        # 代码热更新
      - /app/node_modules     # 匿名卷,不覆盖 node_modules
    ports:
      - "3000:3000"

2.4 tmpfs 安全场景

# 敏感数据不落盘
docker run --rm \
  --tmpfs /run/secrets:rw,noexec,nosuid,size=64m \
  alpine sh -c "echo 'secret-key' > /run/secrets/key && cat /run/secrets/key"

# Docker Compose
services:
  app:
    tmpfs:
      - /tmp:size=128M,noexec
      - /run/secrets:size=1M,ro

第三章:Dockerfile 安全最佳实践

3.1 十条黄金法则

# 1. 使用特定版本,不用 latest
FROM node:20.11.1-alpine3.19

# 2. 非 root 运行
RUN addgroup -g 1000 app &;& adduser -u 1000 -G app -s /bin/sh -D app
USER app

# 3. 固定依赖版本
COPY package-lock.json ./
RUN npm ci --production

# 4. 最小化层数(用 && 串联)
RUN apk add --no-cache curl &;& \
    curl -sSf https://example.com/script.sh | sh && \
    apk del curl

# 5. 使用 .dockerignore
# node_modules/
# .git/
# *.md

# 6. COPY 优于 ADD(ADD 会自动解压 tar)

# 7. HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:8080/health || exit 1

# 8. 使用多阶段构建减小攻击面(见例程)

# 9. 不写入密钥
# 用 BuildKit secrets:
# RUN --mount=type=secret,id=npmrc npm install

# 10. 扫描漏洞
# docker scan my-image

3.2 镜像安全扫描

# Docker 官方扫描(需要 Docker Hub 登录)
docker scan my-app:latest

# Trivy(开源,推荐)
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image my-app:latest

# Hadolint(Dockerfile 静态分析)
docker run --rm -i hadolint/hadolint <; Dockerfile

第四章:资源限制与监控

4.1 资源限制

# 硬限制(超出 OOM Kill)
docker run --memory=256m --cpus=1.5 nginx

# Docker Compose
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 128M

4.2 实时监控

# 容器资源概况
docker stats

# 单个容器进程
docker top my-container

# 实时日志
docker logs -f --tail 100 my-container

思考题

  1. Docker 的 bridge 网络与 host 网络在性能上有什么差异?什么时候必须用 host?
  2. 如果两个容器不在同一网络,如何让它们通信?有哪些实现方式?
  3. Volume 和 Bind Mount 在 Docker Desktop(macOS)上的性能差异为什么特别大?
  4. npm cinpm install 在 Dockerfile 中应该用哪个?为什么?
  5. 如何安全地在构建阶段使用私有 npm registry 的 token?

下一步

  • 学习 Docker Compose 生产部署模式
  • 学习 Docker Swarm / Kubernetes 编排
  • 学习 BuildKit 高级缓存策略

信息

路径
/tech-stacks/docker/tutorial/进阶篇 - Docker 网络与存储深入.md
更新时间
2026/5/31