bigywater.tech
Docker · 51

默认 bridge:docker0、veth 对与 NAT

默认 bridge 和自己创建的 bridge 网络有什么区别?为什么有的容器能按名字互访、有的不能?跨网络为什么不通?这篇用 ping 逐项验证,并进入虚拟机看网桥和 veth 设备。

按 IP 通、按名字不通
默认 bridge 上两个容器的互访表现
172.19.0.0/16
新建自定义 bridge 网络分到的子网(172.18 已被占用)
+5 个 veth
起 4 个容器(其中一个连两个网络)后虚拟机里增加的 veth 设备数

默认 bridge

实测 · 本机执行输出
  docker network ls 里的内置网络:bridge/bridge host/host kind/bridge none/null
  bridge 网络的 Subnet / Gateway:172.17.0.0/16 172.17.0.1
  两个默认 bridge 上的容器 IP:a=172.17.0.2 b=172.17.0.3
  a ping b 的 IP:退出码 0
  a ping b 的名字 bwlab-c46b:退出码 1;ping: bad address 'bwlab-c46b'
  容器里的默认路由:default via 172.17.0.1 dev eth0 ; 172.17.0.0/16 dev eth0 scope link  src 172.17.0.2

默认 bridge 的子网是 172.17.0.0/16,网关 172.17.0.1(虚拟机里 docker0 的地址)。同一个网络里的容器按 IP 互通,但容器名解析不了(bad address)。

自定义 bridge

实测 · 本机执行输出
  docker network create 之后新网络的 Subnet / Gateway:172.19.0.0/16 172.19.0.1
  自定义网络里 c ping d 的名字 bwlab-c46d:退出码 0;解析到 PING bwlab-c46d (172.19.0.3): 56 data bytes

docker network create 出来的网络按顺序分配新的 /16 子网(这里是 172.19,因为 172.18 已被另一个网络占用);容器按名字互访可以。名字解析的细节见后面的内置 DNS 一篇。

隔离与连接

实测 · 本机执行输出
  自定义网络里的 c ping 默认 bridge 上的 a(172.17.0.2):退出码 1
  默认 bridge 上的 a ping c(172.19.0.2):退出码 1
  docker network connect bwlab-c46net bwlab-c46a 之后,a 有 2 个 IP:['172.17.0.2', '172.19.0.4']
  a ping c 的名字:退出码 0

不同 bridge 网络之间不通;docker network connect 把容器接入第二个网络,它就有了两个 IP,可以访问新网络里的容器。我没有查隔离是靠哪条 iptables 规则实现的。

虚拟机里的样子

实测 · 本机执行输出
  虚拟机里的网桥设备:docker0 br-c76c209e2a7a br-ae1a41b9fb47
  虚拟机里 veth 设备个数:起容器前 10 个,起 4 个容器(其中 a 连了两个网络)之后 15 个,增加 5 个——每个容器每连一个网络就多一个 veth
  docker0 的地址:172.17.0.1/16

每个自定义网络对应虚拟机里一个 br-<网络ID前缀> 网桥,默认 bridge 是 docker0;每个容器的每个网卡对应虚拟机里一个 veth 设备(另一端在容器的网络命名空间里,见后面的 veth 一篇)。

分步演示

bridge 网络
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。连通性用 busybox ping(-c 1 -W 2)判断退出码;网络信息取自 docker network inspect 和 docker inspect;虚拟机里的网桥与 veth 用特权容器加 nsenter 读取 ip link(方法见 c19);虚拟机里同时还有其它网络(如 kind)和容器,所以 veth 只看变化量;实验后已删除容器和网络
    • 没有验证:iptables 隔离规则、ICMP 以外的协议(TCP / UDP)、IPv6、macvlan / overlay 网络、--network host 与 none(见后面的 host 网络一篇)、容器访问外网的 NAT、Linux 宿主机上 docker0 的位置
    京ICP备2026067502号-1京公网安备11010502063487号