Docker Bridge网络原理是虚拟网桥docker0、veth对、Network Namespace和iptables NAT四者协同:docker0是内核bridge模块创建的二层交换机;veth对一端连docker0、一端进容器命名空间;Network Namespace实现网络隔离;NAT规则(MASQUERADE)配合ip_forward使容器访问外网。
Docker Bridge 网络底层原理不是靠死记概念,而是抓住“虚拟网桥 + veth 对 + 网络命名空间 + NAT”这四个关键环节,一层一层拆开看,边动手边验证,效果最好。
先搞懂 docker0 是什么
docker0 不是 Docker 自己写的程序,它是 Linux 内核的 bridge 模块创建的一个虚拟网桥设备。你可以把它理解成一台软件实现的二层交换机:- 它有 MAC 地址、能学习 MAC 表、会泛洪未知帧、只转发已知目标端口的数据- 默认 IP 是 172.17.0.1,子网是 172.17.0.0/16(可启动时用 `--bip` 修改)- 运行 `ip link show docker0` 或 `brctl show docker0` 就能看到它
别把它当成 Docker 的专属组件——它和你用 `ip link add br0 type bridge` 创建的 br0 本质一样,只是名字和初始化方式不同。
重点掌握 veth pair 怎么连通容器和宿主机
每个容器启动时,Docker 会创建一对 veth 设备(比如 vethabc123 ↔ vethxyz789),其中:- 一端(如 vethxyz789)挂到 docker0 上,作为网桥的一个端口- 另一端(vethabc123)放进容器的 Network Namespace,并重命名为 eth0- 数据从容器 eth0 发出 → 经 veth 对 → 到达 docker0 → 被桥接转发
你可以手动验证:启动一个容器后,在宿主机执行 `ip link | grep veth` 找到对应 veth,再用 `ip link show ` 查看它的 master 是否为 docker0;进容器 `ip addr show eth0` 看 IP 是否属于 docker0 子网。
看清网络命名空间隔离是怎么起作用的
容器的网络是独立的,靠的是 Linux 的 Network Namespace:- 每个容器有自己的 /proc/net/、自己的路由表、自己的 iptables 规则- `docker exec -it ip route` 看到的默认网关就是 docker0 的 IP(172.17.0.1)- 宿主机上 `ls /var/run/docker/netns/` 能看到对应命名空间文件,用 `ip netns exec` 可临时进入(需 nsenter 或配置)
没有 Network Namespace,容器就无法拥有独立的网络视图;没有 veth pair,这个独立视图就无法连到宿主机网络。
理解容器怎么访问外网:iptables + NAT 是关键
容器要访问互联网,必须经过 SNAT(源地址转换):- Docker 在宿主机的 iptables nat 表里自动加了 POSTROUTING 规则,把来自 docker0 子网的包源 IP 替换为宿主机出口 IP- 同时开启 ip_forward(`sysctl net.ipv4.ip_forward=1`),否则转发不通- 外部返回的响应包靠 conntrack 自动回写,不需要额外配置
运行 `iptables -t nat -L -n -v` 就能看到类似 `MASQUERADE all -- 172.17.0.0/16 anywhere` 的规则——这就是容器上网的“翻译官”。
动手比读文档更有效
- 启一个容器:`docker run -d --name test-nginx nginx`- 查看它的网络接口、IP、网关- 在宿主机找对应的 veth,确认是否挂在 docker0 下- 进容器 ping 宿主机 docker0 IP(172.17.0.1),再 ping 外网(如 8.8.8.8)- 关掉 `net.ipv4.ip_forward`,再试一次 ping 外网,观察失败现象
每一步失败,都是理解原理的好机会。不复杂但容易忽略。