Docker网络模式详解
约 1657 字大约 6 分钟
dockernetworking
2025-06-18
Docker 网络是容器通信的基础设施。理解各种网络模式及其底层实现机制,对于容器化应用的网络架构设计和故障排查至关重要。本文将深入剖析 Docker 的容器网络模型(CNM)和各种网络驱动。
容器网络模型(CNM)
Docker 采用 CNM(Container Network Model)作为网络抽象模型:
Bridge 网络(默认模式)
Bridge 是 Docker 的默认网络模式,创建虚拟网桥连接容器:
# 查看默认 bridge 网络
docker network inspect bridge
# 创建自定义 bridge 网络
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--ip-range 172.20.1.0/24 \
--gateway 172.20.0.1 \
--opt com.docker.network.bridge.name=br-custom \
--opt com.docker.network.bridge.enable_icc=true \
--opt com.docker.network.bridge.enable_ip_masquerade=true \
my-network默认 Bridge vs 自定义 Bridge
| 特性 | 默认 bridge | 自定义 bridge |
|---|---|---|
| DNS 解析 | 不支持(只能用 IP) | 支持容器名解析 |
| 容器隔离 | 所有容器同网络 | 可选择性加入 |
| 运行时连接/断开 | 不支持 | 支持 |
| 环境变量共享 | 支持 --link(已废弃) | 不支持 |
# 使用自定义网络
docker run -d --name web --network my-network nginx
docker run -d --name api --network my-network myapi:1.0
# api 容器可以通过容器名访问 web
docker exec api curl http://web:80Host 网络
容器直接使用宿主机网络栈,没有网络隔离:
docker run -d --name nginx --network host nginx:1.25
# Nginx 直接监听宿主机的 80 端口适用场景:对网络性能要求极高的应用(避免 NAT 开销)、需要访问宿主机网络接口的工具类容器。
注意:Host 模式在 macOS/Windows 的 Docker Desktop 中行为与 Linux 不同,因为 Docker Desktop 运行在虚拟机中。
None 网络
容器没有网络接口(仅有 loopback),完全隔离:
docker run -d --name isolated --network none busybox sleep 3600
docker exec isolated ip addr
# 只有 lo 接口适用场景:不需要网络的批处理任务、安全敏感的密钥生成任务。
Overlay 网络
Overlay 网络通过 VXLAN 隧道实现跨主机容器通信,是 Docker Swarm 和多主机网络的基础:
# 初始化 Swarm(Overlay 需要 Swarm 模式或外部 KV Store)
docker swarm init
# 创建 Overlay 网络
docker network create \
--driver overlay \
--subnet 10.0.9.0/24 \
--opt encrypted=true \
--attachable \
my-overlay--opt encrypted=true 启用 IPSec 加密,保护跨主机流量。--attachable 允许非 Swarm Service 容器加入。
Macvlan 网络
Macvlan 为每个容器分配独立的 MAC 地址,使容器像物理设备一样直接接入网络:
docker network create \
--driver macvlan \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
--opt parent=eth0 \
my-macvlan
docker run -d --name db \
--network my-macvlan \
--ip 192.168.1.50 \
mysql:8.0注意:Macvlan 容器和宿主机之间默认无法通信(需要配置 macvlan bridge 子接口)。
Macvlan 模式:
- bridge(默认):同一父接口的容器可以直接通信
- 802.1q trunk:支持 VLAN 标签
# 802.1q trunk 模式
docker network create \
--driver macvlan \
--subnet 192.168.10.0/24 \
--gateway 192.168.10.1 \
--opt parent=eth0.10 \
vlan10docker-proxy
当容器端口映射到宿主机时,Docker 使用 docker-proxy 进程处理从本机 localhost 发起的连接:
docker run -d -p 8080:80 nginx
# 查看 docker-proxy 进程
ps aux | grep docker-proxy
# docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.2 -container-port 80实际上跨主机的流量通过 iptables DNAT 规则转发,docker-proxy 主要处理 hairpin(本机到本机)场景。
iptables 规则
Docker 自动管理 iptables 规则实现网络功能:
# 查看 Docker 创建的 NAT 规则
iptables -t nat -L -n -v
# MASQUERADE - 容器出站 SNAT
# -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
# DNAT - 端口映射
# -A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
# 容器间通信
# -A FORWARD -i docker0 -o docker0 -j ACCEPT
# 查看 FILTER 规则
iptables -L DOCKER-USER -n -v自定义 iptables 规则
通过 DOCKER-USER 链添加自定义规则(Docker 不会修改此链):
# 限制外部只能访问特定端口
iptables -I DOCKER-USER -i eth0 -p tcp --dport 8080 -j ACCEPT
iptables -I DOCKER-USER -i eth0 -j DROPDNS 解析
自定义 Bridge 网络中,Docker 内置 DNS 服务器(127.0.0.11)提供容器名解析:
# 容器内 DNS 配置
docker exec web cat /etc/resolv.conf
# nameserver 127.0.0.11
# ndots:0
# 解析容器名
docker exec api nslookup web
# Server: 127.0.0.11
# Name: web
# Address: 172.20.1.2DNS 解析优先级:
- 容器名 -> 容器 IP
- 网络别名(
--network-alias) - 外部 DNS(宿主机配置的 DNS)
# 设置网络别名
docker run -d --name web-1 --network my-network --network-alias web-pool nginx
docker run -d --name web-2 --network my-network --network-alias web-pool nginx
# 解析 web-pool 会返回两个 IP(简单轮询负载均衡)
docker exec api nslookup web-pool多主机网络实践
在非 Swarm 环境中实现多主机网络的方案:
总结
Docker 网络模式选型指南:
| 网络模式 | 适用场景 | 性能 | 隔离性 |
|---|---|---|---|
| Bridge | 单机容器通信(默认推荐) | 中 | 好 |
| Host | 高性能网络应用 | 最高 | 无 |
| None | 不需要网络的任务 | - | 完全隔离 |
| Overlay | 跨主机容器通信 | 中 | 好 |
| Macvlan | 需要独立 MAC/IP 的场景 | 高 | 好 |
关键实践:
- 始终使用自定义 Bridge 网络而非默认 bridge,获得 DNS 解析能力
- 生产环境使用 Overlay 加密保护跨主机流量
- 通过 DOCKER-USER 链自定义防火墙规则
- Macvlan 适合传统基础设施集成但需注意与宿主机通信限制
贡献者
更新日志
9f6c2-feat: organize wiki content and refresh site setup于