在云原生体系中,Docker 的核心技术依赖于 Linux 内核提供的两大基石:cgroups(资源限制) 与 namespaces(环境隔离)。而在诸多命名空间中,网络命名空间(Network Namespace)负责隔离独立的网络设备、IP 地址、路由表与端口列表。
很多开发者在日常使用 docker run -p 8080:80 时,往往只知道端口被映射了,却不清楚流量是如何在宿主机物理网卡、虚拟网桥与容器之间流转的。本文将为你拆解这一底层链路。
1. 四种常见 Docker 网络模式
| 网络模式 | 驱动类型 | 典型适用场景 |
|---|---|---|
| Bridge (默认) | 网桥驱动 | 单宿主机多容器隔离通信,最常见也是默认模式 |
| Host | 与宿主机共享 | 追求极致低网络损耗与超高吞吐,无独立端口隔离 |
| None | 无网络设备 | 高度安全离线作业,例如执行静态扫描与密钥生成 |
| Overlay | VxLAN 跨主机 | Swarm 或跨机器集群网络通信 |
2. Bridge 模式的物理机视角与 veth pair
当 Docker 服务启动时,会在宿主机内核创建一个名为 docker0 的虚拟以太网桥(Virtual Bridge),并默认分配 172.17.0.1/16 网段。每当你启动一个容器时:
- 内核创建一对虚拟网卡对(
veth pair,如vethxxxx和容器内的eth0)。 - 一端插在宿主机的
docker0网桥上。 - 另一端放进容器的 Network Namespace 并改名为
eth0。
# 查看宿主机上的网桥与连接的接口
brctl show docker0
# 查看网络命名空间接口
ip link show type veth
3. 端口映射背后的 iptables 规则链
当你执行 docker run -p 8080:80 nginx 时,Docker 守护进程会在宿主机的 iptables nat 表 和 filter 表 中悄悄注入两条链:DOCKER 和 DOCKER-USER。
# 检查 nat 表的 PREROUTING 与 DOCKER 链规则
sudo iptables -t nat -L -n -v
# 示例输出的关键规则(DNAT 端口重定向):
# DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
核心流向:外网请求到达宿主机物理网卡后,触发PREROUTING链的 DNAT 规则,目标 IP 和端口被篡改为容器私有 IP(172.17.0.2:80),随后经过路由决策交给docker0网桥,再通过veth pair投递给容器内部。
4. 常见网络故障与排查三板斧
- 容器无法访问公网: 检查宿主机内核是否开启了 IP 转发:
sysctl net.ipv4.ip_forward是否为 1。 - 容器内 DNS 解析超时: 确认
/etc/resolv.conf是否配置了正确的公共上游 DNS(如 1.1.1.1 或 114.114.114.114)。 - 端口监听冲突: 某些代理工具或 local 服务占用了 `0.0.0.0:8080`,使用
ss -tulpn | grep 8080快速定位 PID。