写在前面
容器是隔离的——隔离进程、文件系统、网络。但应用需要对外通信(网络)和保存数据(存储)。本文讲 Docker 的网络模型和存储机制,这是把容器用到生产的关键。
一、Docker 网络模型
1.1 四种网络模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| bridge(默认)— 桥接
容器连到虚拟网桥 docker0,通过 NAT 访问外部
容器间用端口映射对外
最常用
host — 主机网络
容器直接用宿主机网络栈(无隔离)
性能最好,但端口冲突
适合对网络性能极致要求的场景
none — 无网络
完全隔离,只有 lo 回环
用于不需要网络的计算任务
container:xxx — 共享容器网络
新容器和某已有容器共享网络栈
少用
macvlan — 容器有独立 MAC/IP,像物理机(进阶)
overlay — 跨主机容器网络(Docker Swarm / K8s 用)
|
1.2 bridge 网络详解
1
2
3
4
5
6
7
8
9
10
11
12
| 默认 bridge(docker0):
所有容器默认连这
✗ 容器间只能用 IP 互访(没有 DNS 名字解析)
✗ 旧,不推荐生产
自定义 bridge(推荐):
docker network create mynet
✓ 自带 DNS,容器间用「容器名」互访
✓ 更好的隔离
✓ 可配置子网、网关
→ 生产/开发都该用自定义网络,不用默认 bridge
|
1
2
3
4
5
6
7
8
| # 创建网络
docker network create mynet
# 容器加入网络
docker run -d --name web --network mynet nginx
docker run -d --name app --network mynet myapp
# app 容器里:curl http://web ← 用容器名访问(DNS 自动解析)
|
1.3 端口映射
1
2
3
4
5
6
7
8
| # 端口映射(宿主机:容器)
docker run -p 8080:80 nginx # 宿主机 8080 → 容器 80
docker run -p 127.0.0.1:8080:80 nginx # 只绑本地回环
docker run -p 8080:80 -p 8443:443 nginx # 多端口
docker run -P nginx # 随机映射宿主机高端口
# 查看端口映射
docker port web
|
二、跨主机网络(Overlay)
1
2
3
4
5
6
7
8
9
| 单机:bridge 够用
多机:容器跨机器通信需要 overlay 网络
overlay 网络在多台机器间建虚拟二层网络
容器像在同一局域网
依赖:键值存储(etcd/consul)或 Docker Swarm
实际多机方案多用 K8s(自己的网络模型 CNI:Calico/Flannel/Cilium)
纯 Docker 多机用 Swarm(已式微)
|
三、Docker 存储
容器删除后,容器内的数据消失。要持久化,三种方式:
3.1 Volume(卷,推荐)
1
2
3
4
5
6
| # 命名卷(Docker 管理)
docker volume create mydata
docker run -v mydata:/var/lib/mysql mysql
# 匿名卷
docker run -v /var/lib/mysql mysql
|
1
2
3
4
5
6
7
8
| Volume:
Docker 管理的存储(Linux 下 /var/lib/docker/volumes/)
✓ 跨容器共享
✓ 生命周期独立于容器(容器删了卷还在)
✓ 性能好(绕过联合文件系统)
✓ 支持 volume driver(NFS、云盘等)
→ 数据库数据、应用状态等持久化数据,首选 Volume
|
3.2 Bind Mount(绑定挂载)
1
2
3
4
| # 宿主机目录/文件挂到容器
docker run -v /host/path:/container/path nginx
docker run -v /host/conf:/etc/nginx/conf.d:ro nginx # 只读
docker run --mount type=bind,source=/host,target=/container nginx # 新语法
|
1
2
3
4
5
6
7
8
| Bind Mount:
直接映射宿主机路径
✓ 开发时挂源码(改了立即生效,热重载)
✓ 挂配置文件
✗ 依赖宿主机路径(移植性差)
✗ 容器能改宿主机文件(小心)
→ 本地开发挂代码、挂配置,用 Bind Mount
|
3.3 tmpfs(内存挂载)
1
2
3
| # 数据存在内存,不落盘
docker run --tmpfs /cache nginx
docker run --mount type=tmpfs,target=/cache,tmpfs-size=100m nginx
|
1
2
3
4
5
6
7
| tmpfs:
数据在内存,容器停了就没
✓ 极快
✓ 适合临时/敏感数据(不想落盘)
✗ 不持久
→ 临时缓存、密钥文件,用 tmpfs
|
四、三种存储对比
1
2
3
4
5
6
7
| Volume Bind Mount tmpfs
──────────────────────────────────────────────────────────────
位置 Docker 管理 宿主机路径 内存
移植性 好 差 好
持久化 是 是 否
管理命令 docker volume 文件系统 无
适合 持久数据(DB) 开发挂载/配置 临时数据
|
五、Volume 实战
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 创建/列出/删除
docker volume create pgdata
docker volume ls
docker volume rm pgdata
# 查看卷详情
docker volume inspect pgdata
# 备份卷
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
tar czf /backup/pgdata.tar.gz -C /data .
# 恢复卷
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
tar xzf /backup/pgdata.tar.gz -C /data
# 多容器共享卷
docker run -d --name app1 -v sharedata:/data myapp
docker run -d --name app2 -v sharedata:/data myapp # 共享同一卷
|
六、数据共享模式
1
2
3
4
5
6
7
8
9
10
11
| 1. 容器间共享:多个容器挂同一个命名卷
docker run -v sharevol:/data ...
docker run -v sharevol:/data ...
2. 只读配置共享:宿主机配置挂成只读
docker run -v /host/nginx.conf:/etc/nginx/nginx.conf:ro nginx
3. 数据容器模式(旧,已少用):专门一个容器持有卷,其他 --volumes-from
4. 开发热重载:源码 bind mount,代码改了容器内即时生效
docker run -v $(pwd)/src:/app/src myapp
|
七、生产实践
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| 网络:
✓ 用自定义 bridge,不用默认 docker0
✓ 服务名做 DNS 互访
✓ 对外端口收敛(只暴露必要端口)
✓ 生产用反向代理(Nginx)收口
存储:
✓ 数据库数据用命名 Volume(独立于容器)
✓ 配置用 Bind Mount(方便修改)
✓ 敏感文件用 tmpfs 或 Docker Secret
✓ 定期备份重要 Volume
✓ 不要把数据存在容器内(容器是无状态的,随时可删)
容器无状态原则:
应用代码 → 进镜像
配置 → 环境变量 / 挂载
数据 → Volume(容器外)
→ 容器本身随时可删可重建,数据不丢
|
八、小结
- 网络模式:bridge(默认,用自定义)、host(高性能)、none、overlay(跨机)
- 自定义 bridge:自带 DNS,容器间用服务名互访(推荐)
- 端口映射:
-p 宿主机:容器 - 存储三种:
- Volume(Docker 管理,持久数据首选)
- Bind Mount(宿主机路径,开发/配置)
- tmpfs(内存,临时数据)
- 无状态原则:数据放 Volume,容器随时可删可重建
下一篇讲 Docker 生产实践与安全。