Skip to content

网络模式详解

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 网络

下一节介绍自定义网络的详细配置。