前言
在入门篇中,我们学习了 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
docker run -d --name app1 --network my-net nginx
docker run -d --name app2 --network my-net alpine ping app1
默认 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 端口映射原理
docker run -p 8080:80 nginx
iptables -t nat -L DOCKER -n
1.5 网络排错工具箱
docker network ls
docker network inspect my-net
docker exec -it app1 sh
nslookup app2
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
docker run --rm -v db-data:/data alpine tar czf - -C /data . >
scp db.tar.gz target-host:
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 开发场景
services:
web:
image: node:20-alpine
working_dir: /app
command: npm run dev
volumes:
- ./src:/app/src
- /app/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"
services:
app:
tmpfs:
- /tmp:size=128M,noexec
- /run/secrets:size=1M,ro
第三章:Dockerfile 安全最佳实践
3.1 十条黄金法则
FROM node:20.11.1-alpine3.19
RUN addgroup -g 1000 app &
USER app
COPY package-lock.json ./
RUN npm ci --production
RUN apk add --no-cache curl &
curl -sSf https:
apk del curl
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http:
3.2 镜像安全扫描
docker scan my-app:latest
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image my-app:latest
docker run --rm -i hadolint/hadolint <
第四章:资源限制与监控
4.1 资源限制
docker run --memory=256m --cpus=1.5 nginx
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
思考题
- Docker 的 bridge 网络与 host 网络在性能上有什么差异?什么时候必须用 host?
- 如果两个容器不在同一网络,如何让它们通信?有哪些实现方式?
- Volume 和 Bind Mount 在 Docker Desktop(macOS)上的性能差异为什么特别大?
npm ci 和 npm install 在 Dockerfile 中应该用哪个?为什么?
- 如何安全地在构建阶段使用私有 npm registry 的 token?
下一步
- 学习 Docker Compose 生产部署模式
- 学习 Docker Swarm / Kubernetes 编排
- 学习 BuildKit 高级缓存策略
Docker 入门教程:容器化核心概念与最佳实践
1. Docker 解决了什么?
在传统部署中:
- 环境不一致:"我这里能跑"
- 依赖冲突:A 项目需要 Python 3.9,B 项目需要 Python 3.11
- 部署繁琐:安装依赖 → 配置环境 → 启动
- 资源浪费:VM 占用大量内存和磁盘
Docker 通过**镜像(Image)将应用和依赖打包,在任何地方以容器(Container)**形式运行。
2. 核心概念
Image vs Container
- Image:只读模板,类似 ISO 文件
- Container:Image 的运行实例,可读可写层叠加
Dockerfile 指令速查
FROM
RUN
COPY
ADD
WORKDIR
ENV
EXPOSE
CMD
ENTRYPOINT
VOLUME
USER
分层构建与缓存
FROM ubuntu:22.04 # Layer 1: 基础层
RUN apt update # Layer 2: apt 缓存
RUN apt install -y python # Layer 3: Python
COPY app.py . # Layer 4: 代码(变更频繁)
Docker 会缓存不变的层,只有变更的层需要重建。
3. 最佳实践
- ✅ 使用多阶段构建减小镜像体积
- ✅ 以非 root 用户运行
- ✅
.dockerignore 排除 node_modules/.git 等
- ✅ 固定基础镜像版本标签(不用
latest)
- ✅ 合并 RUN 指令减少层数:
RUN apt update && apt install -y pkg1 pkg2 && rm -rf /var/lib/apt/lists/*
- ❌ 不要在容器内存储数据(用 Volume)
- ❌ 不要在一个容器运行多个进程(用 Compose)
4. Docker Compose 实战技巧
x-common-env: &
ENV: production
LOG_LEVEL: info
services:
app:
environment:
<
PORT: 5000
depends_on:
db:
condition: service_healthy
5. 网络模式
| 模式 |
说明 |
| bridge |
默认,独立网络栈 |
| host |
使用宿主机网络(仅 Linux) |
| none |
无网络 |
| overlay |
跨主机容器通信(Swarm) |
6. 思考题
CMD 和 ENTRYPOINT 的区别?什么场景用哪个?
- 为什么推荐 Alpine 作为基础镜像?有什么缺点?
- Volume 和 Bind Mount 的区别?