Appearance
网络模式详解
Docker 提供多种网络驱动,每种模式适用于不同的使用场景。本节深入介绍各网络模式的原理和用法。
bridge 网络(桥接网络)
工作原理
bridge 是 Docker 的默认网络模式。Docker 在宿主机上创建一个虚拟网桥(docker0),每个容器通过 veth pair(虚拟网卡对)连接到该网桥。
宿主机
┌──────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │Container1│ │Container2│ │
│ │ eth0 │ │ eth0 │ │
│ │172.17.0.2│ │172.17.0.3│ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ┌────┴───────────────┴────┐ │
│ │ docker0(网桥) │ │
│ │ 172.17.0.1 │ │
│ └────────────┬────────────┘ │
│ │ iptables NAT │
│ 宿主机网络接口 │
│ 192.168.1.100 │
└──────────────────────────────────────────┘默认 bridge 网络的限制
bash
# 创建两个容器
docker run -d --name c1 alpine sleep 3600
docker run -d --name c2 alpine sleep 3600
# 查看 IP
docker inspect c1 -f '{{.NetworkSettings.IPAddress}}' # 172.17.0.2
docker inspect c2 -f '{{.NetworkSettings.IPAddress}}' # 172.17.0.3
# 通过 IP 可以通信
docker exec c1 ping 172.17.0.3 # 可以 ping 通
# 但不能通过容器名访问
docker exec c1 ping c2 # 失败!默认 bridge 不支持容器名 DNS用户定义 bridge 网络(推荐)
bash
# 创建自定义网络
docker network create mynet
# 在自定义网络中运行容器
docker run -d --name c1 --network mynet alpine sleep 3600
docker run -d --name c2 --network mynet alpine sleep 3600
# 通过容器名可以直接通信(内置 DNS)
docker exec c1 ping c2 # 成功!
docker exec c1 ping c2 # 通过名称解析
# 查看网络信息
docker network inspect mynet自定义网络相比默认 bridge 的优势:
- 支持容器名 DNS 解析(自动服务发现)
- 可以动态连接/断开容器
- 更好的网络隔离
host 网络(主机网络)
容器共享宿主机的网络命名空间,没有网络隔离:
bash
# 使用 host 网络
docker run -d --network host nginx
# 容器直接占用宿主机的 80 端口
# 无需 -p 端口映射
curl localhost:80宿主机网络
┌──────────────────────────────────────┐
│ 宿主机进程 │
│ Docker容器(共享相同网络命名空间) │
│ 127.0.0.1 / 192.168.1.100 │
└──────────────────────────────────────┘适用场景:
- 需要最高网络性能(无 NAT 开销)
- 容器需要监听多个或动态端口
- 网络监控、抓包等工具
注意事项:
- 降低安全隔离性
- 端口冲突风险
- macOS / Windows Docker Desktop 上不生效(容器运行在 Linux VM 中)
none 网络(无网络)
容器没有任何网络接口(除回环 lo):
bash
# 使用 none 网络
docker run -it --network none alpine sh
# 验证:只有 lo,没有网络
ip addr
# 1: lo: <LOOPBACK,UP> ...
# 没有 eth0适用场景:
- 批处理任务,不需要网络
- 安全敏感任务,完全隔离
- 自行配置网络插件
overlay 网络(覆盖网络)
用于 Docker Swarm 集群,实现跨主机容器通信:
主机 A 主机 B
┌──────────────┐ ┌──────────────┐
│ Container1 │ │ Container2 │
│ 10.0.0.2 │ │ 10.0.0.3 │
└──────┬───────┘ └──────┬───────┘
│ │
┌──────┴───────────────────────────────┴───────┐
│ overlay 网络 │
│ 10.0.0.0/24 │
└──────────────────────────────────────────────┘
(通过 VXLAN 封装,跨物理网络通信)bash
# 需要先初始化 Swarm
docker swarm init
# 创建 overlay 网络
docker network create --driver overlay --attachable my-overlay
# 在不同主机的容器可以通过容器名通信macvlan 网络
容器获得宿主机网络上的真实 MAC 地址,直接接入物理网络:
bash
# 创建 macvlan 网络
docker network create \
--driver macvlan \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
-o parent=eth0 \
my-macvlan
# 运行容器,指定静态 IP
docker run -d \
--network my-macvlan \
--ip 192.168.1.200 \
--name web \
nginx适用场景:
- 容器需要直接接入物理网络
- 需要特定 IP 地址
- 传统网络设备集成
ipvlan 网络
与 macvlan 类似,但共享父接口的 MAC 地址,适用于限制 MAC 地址数量的环境:
bash
docker network create \
--driver ipvlan \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
-o parent=eth0 \
my-ipvlan网络模式对比
| 模式 | 隔离性 | 性能 | 跨主机 | 端口映射 | 适用场景 |
|---|---|---|---|---|---|
| bridge | 中 | 中 | 否 | 需要 | 单机默认 |
| 自定义bridge | 中 | 中 | 否 | 需要 | 单机推荐 |
| host | 无 | 最高 | 否 | 无需 | 高性能 |
| none | 完全 | N/A | 否 | 无需 | 完全隔离 |
| overlay | 中 | 中 | 是 | 需要 | Swarm集群 |
| macvlan | 中 | 高 | 否 | 无需 | 物理网络集成 |
实用操作
bash
# 查看所有网络
docker network ls
# 创建网络(指定子网)
docker network create \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
my-network
# 容器连接到多个网络
docker network connect network1 my-container
docker network connect network2 my-container
# 断开网络
docker network disconnect network1 my-container
# 删除网络
docker network rm my-network
# 清理未使用的网络
docker network prune
# 查看容器的网络配置
docker inspect my-container --format '{{json .NetworkSettings.Networks}}'总结
- 单机开发/测试:使用用户定义 bridge 网络,支持容器名 DNS
- 高性能需求:使用 host 网络,无 NAT 开销
- Swarm 集群:使用 overlay 网络,跨主机通信
- 与物理网络集成:使用 macvlan 或 ipvlan
- 安全隔离:使用 none 网络
下一节介绍自定义网络的详细配置。