侧边栏壁纸
博主头像
汪洋

即使慢,驰而不息,纵会落后,纵会失败,但一定可以达到他所向的目标。 - 鲁迅

  • 累计撰写 190 篇文章
  • 累计创建 74 个标签
  • 累计收到 108 条评论

Linux 虚拟网络设备之 bridge

汪洋
2021-08-26 / 0 评论 / 1 点赞 / 266 阅读 / 14,229 字

什么是 bridge ?

首先,bridge 是一个虚拟网络设备,所以具有网络设备的特征,可以配置 IP、MAC 地址等;其次,bridge 是一个虚拟交换机,和物理交换机有类似的功能。

对于普通的网络设备来说,只有两端,从一端进来的数据会从另一端出去,如物理网卡从外面网络中收到的数据会转发给内核协议栈,而从协议栈过来的数据会转发到外面的物理网络中。

而 bridge 不同,bridge 有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多,要看 mac 地址。

创建 bridge

我们先用 iproute2 创建一个 bridge:

dev@debian:~$ sudo ip link add name br0 type bridge
dev@debian:~$ sudo ip link set br0 up

当刚创建一个 bridge 时,它是一个独立的网络设备,只有一个端口连着协议栈,其它的端口啥都没连,这样的 bridge 没有任何实际功能,如下图所示:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|              ↑                                ↑                |
|..............|................................|................|
|              ↓                                ↓                |
|        +----------+                     +------------+         |
|        |   eth0   |                     |     br0    |         |
|        +----------+                     +------------+         |
| 192.168.3.21 ↑                                                 |
|              |                                                 |
|              |                                                 |
+--------------|-------------------------------------------------+
               ↓
         Physical Network

这里假设 eth0 是我们的物理网卡,IP 地址是 192.168.3.21,网关是 192.168.3.1

将 bridge 和 veth 设备相连

创建一对veth设备,并配置上IP

dev@debian:~$ sudo ip link add veth0 type veth peer name veth1
dev@debian:~$ sudo ip addr add 192.168.3.101/24 dev veth0
dev@debian:~$ sudo ip addr add 192.168.3.102/24 dev veth1
dev@debian:~$ sudo ip link set veth0 up
dev@debian:~$ sudo ip link set veth1 up

将 veth0 连上 vbr0

dev@debian:~$ sudo ip link set dev veth0 master br0

# 通过bridge link命令可以看到br0上连接了哪些设备
dev@debian:~$ sudo bridge link
6: veth0 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2

这时候,网络就变成了这个样子:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|            ↑            ↑              |            ↑          |
|............|............|..............|............|..........|
|            ↓            ↓              ↓            ↓          |
|        +------+     +--------+     +-------+    +-------+      |
|        | .3.21|     |        |     | .3.101|    | .3.102|      |
|        +------+     +--------+     +-------+    +-------+      |
|        | eth0 |     |   br0  |<--->| veth0 |    | veth1 |      |
|        +------+     +--------+     +-------+    +-------+      |
|            ↑                           ↑            ↑          |
|            |                           |            |          |
|            |                           +------------+          |
|            |                                                   |
+------------|---------------------------------------------------+
             ↓
     Physical Network

这里为了画图方便,省略了IP地址前面的192.168,比如.3.21就表示192.168.3.21

br0 和 veth0 相连之后,发生了几个变化:

  • br0 和 veth0 之间连接起来了,并且是双向的通道
  • 协议栈和 veth0 之间变成了单通道,协议栈能发数据给veth0,但veth0从外面收到的数据不会转发给协议栈
  • br0 的 mac 地址变成了 veth0 的 mac 地址

相当于 bridge 在 veth0 和协议栈之间插了一脚,在 veth0 上面做了点小动作,将 veth0 本来要转发给协议栈的数据给拦截了,全部转发给 bridge 了,同时 bridge 也可以向 veth 0发数据。

下面来检验一下是不是这样的:

通过 veth0 ping veth1 vv失败:

dev@debian:~$ ping -c 1 -I veth0 192.168.3.102
PING 192.168.2.1 (192.168.2.1) from 192.168.2.11 veth0: 56(84) bytes of data.
From 192.168.2.11 icmp_seq=1 Destination Host Unreachable

--- 192.168.2.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

为什么 veth0 加入了 bridge 之后,就 ping 不通 veth2 了呢?先抓包看看:

# 由于 veth0 的 arp 缓存里面没有 veth1 的 mac 地址,所以 ping 之前先发 arp 请求
# 从 veth1 上抓包来看,veth1 收到了 arp 请求,并且返回了应答

dev@debian:~$ sudo tcpdump -n -i veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
21:43:48.353509 ARP, Request who-has 192.168.3.102 tell 192.168.3.101, length 28
21:43:48.353518 ARP, Reply 192.168.3.102 is-at 26:58:a2:57:37:e9, length 28

# 从 veth0 上抓包来看,数据包也发出去了,并且也收到了返回
dev@debian:~$ sudo tcpdump -n -i veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:44:09.775392 ARP, Request who-has 192.168.3.102 tell 192.168.3.101, length 28
21:44:09.775400 ARP, Reply 192.168.3.102 is-at 26:58:a2:57:37:e9, length 28

# 再看 br0 上的数据包,发现只有应答
dev@debian:~$ sudo tcpdump -n -i br0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:45:48.225459 ARP, Reply 192.168.3.102 is-at 26:58:a2:57:37:e9, length 28

从上面的抓包可以看出,去和回来的流程都没有问题,问题就出在 veth0 收到应答包后没有给协议栈,而是给了 br0,于是协议栈得不到 veth1 的 mac 地址,从而通信失败

给 bridge 配上 IP

通过上面的分析可以看出,给 veth0 配置 IP 没有意义,因为就算协议栈传数据包给 veth0,应答包也回不来。这里我们就将 veth0 的 IP 让给 bridge

dev@debian:~$ sudo ip addr del 192.168.3.101/24 dev veth0
dev@debian:~$ sudo ip addr add 192.168.3.101/24 dev br0

于是网络变成了这样子:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|            ↑            ↑                           ↑          |
|............|............|...........................|..........|
|            ↓            ↓                           ↓          |
|        +------+     +--------+     +-------+    +-------+      |
|        | .3.21|     | .3.101 |     |       |    | .3.102|      |
|        +------+     +--------+     +-------+    +-------+      |
|        | eth0 |     |   br0  |<--->| veth0 |    | veth1 |      |
|        +------+     +--------+     +-------+    +-------+      |
|            ↑                           ↑            ↑          |
|            |                           |            |          |
|            |                           +------------+          |
|            |                                                   |
+------------|---------------------------------------------------+
             ↓
     Physical Network

其实 veth0 和协议栈之间还是有联系的,但由于 veth0 没有配置 IP,所以协议栈在路由的时候不会将数据包发给 veth0,就算强制要求数据包通过 veth0 发送出去,但由于 veth0 从另一端收到的数据包只会给 br0,所以协议栈还是没法收到相应的 arp 应答包,导致通信失败。这里为了表达更直观,将协议栈和 veth0 之间的联系去掉了,veth0 相当于一根网线。

再通过 br0 ping 一下 veth1,结果成功

dev@debian:~$ ping -c 1 -I br0 192.168.3.102
PING 192.168.3.102 (192.168.3.102) from 192.168.3.101 br0: 56(84) bytes of data.
64 bytes from 192.168.3.102: icmp_seq=1 ttl=64 time=0.121 ms

--- 192.168.3.102 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.121/0.121/0.121/0.000 ms

但 ping 网关还是失败,因为这个 bridge 上只有两个网络设备,分别是 192.168.3.101 和 192.168.3.102,br0 不知道 192.168.3.1 在哪

dev@debian:~$ ping -c 1 -I br0 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.101 br0: 56(84) bytes of data.
From 192.168.3.101 icmp_seq=1 Destination Host Unreachable

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

将物理网卡添加到 bridge

将 eth0 添加到 br0 上:

dev@debian:~$ sudo ip link set dev eth0 master br0
dev@debian:~$ sudo bridge link
2: eth0 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 4
6: veth0 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2

br0 根本不区分接入进来的是物理设备还是虚拟设备,对它来说都一样的,都是网络设备,所以当 eth0 加入 br0 之后,落得和上面 veth0 一样的下场,从外面网络收到的数据包将无条件的转发给 br0,自己变成了一根网线

这时通过 eth0 来 ping 网关失败,但由于 br0 通过 eth0 这根网线连上了外面的物理交换机,所以连在 br0 上的设备都能 ping 通网关,这里连上的设备就是 veth1 和 br0 自己,veth1 是通过 veth0 这根网线连上去的,而 br0 可以理解为自己有一块自带的网卡

# 通过 eth0 来 ping 网关失败
dev@debian:~$ ping -c 1 -I eth0 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.21 eth0: 56(84) bytes of data.
From 192.168.3.21 icmp_seq=1 Destination Host Unreachable

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

# 通过 br0 来 ping 网关成功
dev@debian:~$ ping -c 1 -I br0 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.101 br0: 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=27.5 ms

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 27.518/27.518/27.518/0.000 ms

# 通过 veth1 来 ping 网关成功
dev@debian:~$ ping -c 1 -I veth1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.102 veth1: 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=68.8 ms

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 68.806/68.806/68.806/0.000 ms

由于 eth0 已经变成了和网线差不多的功能,所以在 eth0 上配置 IP 已经没有什么意义了,并且还会影响协议栈的路由选择,比如如果上面 ping 的时候不指定网卡的话,协议栈有可能优先选择 eth0,导致 ping 不通,所以这里需要将 eth0 上的 IP 去掉。

# 在本人的测试机器上,由于 eth0 上有 IP,
# 访问 192.168.3.0/24 网段时,会优先选择 eth0
dev@debian:~$ sudo route -v
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.3.1     0.0.0.0         UG    0      0        0 eth0
link-local      *               255.255.0.0     U     1000   0        0 eth0
192.168.3.0     *               255.255.255.0   U     0      0        0 eth0
192.168.3.0     *               255.255.255.0   U     0      0        0 veth1
192.168.3.0     *               255.255.255.0   U     0      0        0 br0

# 由于 eth0 已结接入了 br0,所有它收到的数据包都会转发给br0,
# 于是协议栈收不到 arp 应答包,导致 ping 失败
dev@debian:~$ ping -c 1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
From 192.168.3.21 icmp_seq=1 Destination Host Unreachable

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

# 将 eth0 上的 IP 删除掉
dev@debian:~$ sudo ip addr del 192.168.3.21/24 dev eth0

# 再 ping 一次,成功
dev@debian:~$ ping -c 1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=3.91 ms

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 3.916/3.916/3.916/0.000 ms

# 这是因为 eth0 没有 IP 之后,路由表里面就没有它了,于是数据包会从 veth1 出去
dev@debian:~$ sudo route -v
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.3.0     *               255.255.255.0   U     0      0        0 veth1
192.168.3.0     *               255.255.255.0   U     0      0        0 br0
# 从这里也可以看出,由于原来的默认路由走的是 eth0,所以当 eth0 的 IP 被删除之后,
# 默认路由不见了,想要连接 192.168.3.0/24 以外的网段的话,需要手动将默认网关加回来

# 添加默认网关,然后再 ping 外网成功
dev@debian:~$ sudo ip route add default via 192.168.3.1
dev@debian:~$ ping -c 1 baidu.com
PING baidu.com (111.13.101.208) 56(84) bytes of data.
64 bytes from 111.13.101.208: icmp_seq=1 ttl=51 time=30.6 ms

--- baidu.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 30.690/30.690/30.690/0.000 ms

经过上面一系列的操作后,网络变成了这个样子:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|                         ↑                           ↑          |
|.........................|...........................|..........|
|                         ↓                           ↓          |
|        +------+     +--------+     +-------+    +-------+      |
|        |      |     | .3.101 |     |       |    | .3.102|      |
|        +------+     +--------+     +-------+    +-------+      |
|        | eth0 |<--->|   br0  |<--->| veth0 |    | veth1 |      |
|        +------+     +--------+     +-------+    +-------+      |
|            ↑                           ↑            ↑          |
|            |                           |            |          |
|            |                           +------------+          |
|            |                                                   |
+------------|---------------------------------------------------+
             ↓
     Physical Network

上面的操作中有几点需要注意:

  • 如果是在虚拟机上做上述操作,记得打开网卡的混杂模式(不是在 Linux 里面,而是在虚拟机的配置上面,如 VirtualBox 上相应虚拟机的网卡配置项里面),不然 veth1 的网络会不通,因为 eth0 不在混杂模式的话,会丢掉目的 mac 地址是 veth1 的数据包

  • 上面虽然通了,但由于 Linux 下 arp 的特性,当协议栈收到外面的 arp 请求时,不管是问 101 还是 102,都会回复两个 arp 应答,分别包含 br0 和 veth1 的 mac 地址,也即 Linux 觉得外面发给 101 和 102 的数据包从 br0 和 veth1 进协议栈都一样,没有区别。由于回复了两个 arp 应答,而外面的设备只会用其中的一个,并且具体用哪个会随着时间发生变化,于是导致一个问题,就是外面回复给 102 的数据包可能从 101 的 br0 上进来,即通过102 ping 外面时,可能在 veth1 抓不到回复包,而在 br0 上能抓到回复包。说明数据流在交换机那层没有完全的隔离开,br0 和 veth1 会收到对方的 IP 应答包。为了解决上述问题,可以配置 rp_filter, arp_filter, arp_ignore, arp_announce等参数,但不建议这么做,容易出错,调试比较麻烦。

  • 在无线网络环境中,情况会变得比较复杂,因为无线网络需要登录,登陆后无线路由器只认一个 mac 地址,所有从这台机器出去的 mac 地址都必须是那一个,于是通过无线网卡上网的机器上的所有虚拟机想要上网的话,都必须依赖虚拟机管理软件(如VirtualBox )将每个虚拟机的网卡 mac 地址转成出口的 mac 地址(即无线网卡的 mac 地址),数据包回来的时候还要转回来,所以如果一个 IP 有两个 ARP 应答包的话,有可能导致 mac 地址的转换有问题,导致网络不通,或者有时通有时不通。解决办法就是将连接进 br0 的所有设备的 mac 地址都改成和 eth0 一样的 mac 地址,因为 eth0 的 mac 地址会被虚拟机正常的做转换。在上面的例子中,执行下面的命令即可:

    dev@debian:~$ sudo ip link set dev veth1 down
    #08:00:27:3b:0d:b9是eth0的mac地址
    dev@debian:~$ sudo ip link set dev veth1 address 08:00:27:3b:0d:b9
    dev@debian:~$ sudo ip link set dev veth1 up
    

bridge 必须要配置 IP 吗?

在我们常见的物理交换机中,有可以配置 IP 和不能配置 IP 两种,不能配置 IP 的交换机一般通过 com 口连上去做配置(更简单的交换机连 com 口的没有,不支持任何配置),而能配置 IP 的交换机可以在配置好 IP 之后,通过该 IP 远程连接上去做配置,从而更方便。

bridge 就属于后一种交换机,自带虚拟网卡,可以配置 IP,该虚拟网卡一端连在 bridge 上,另一端跟协议栈相连。和物理交换机一样, bridge 的工作不依赖于该虚拟网卡,但 bridge 工作不代表机器能连上网,要看组网方式。

删除 br0 上的 IP:

dev@debian:~$ sudo ip addr del 192.168.3.101/24 dev br0

于是网络变成了这样子,相当于 br0 的一个端口通过 eth0 连着交换机,另一个端口通过 veth0 连着 veth1:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|                                                     ↑          |
|.....................................................|..........|
|                                                     ↓          |
|        +------+     +--------+     +-------+    +-------+      |
|        |      |     |        |     |       |    | .3.102|      |
|        +------+     +--------+     +-------+    +-------+      |
|        | eth0 |<--->|   br0  |<--->| veth0 |    | veth1 |      |
|        +------+     +--------+     +-------+    +-------+      |
|            ↑                           ↑            ↑          |
|            |                           |            |          |
|            |                           +------------+          |
|            |                                                   |
+------------|---------------------------------------------------+
             ↓
     Physical Network

ping 网关成功,说明这种情况下 br0 不配置 I P 对通信没有影响,数据包还能从 veth1 出去:

dev@debian:~$ ping -c 1 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.
64 bytes from 192.168.3.1: icmp_seq=1 ttl=64 time=1.24 ms

--- 192.168.3.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.242/1.242/1.242/0.000 ms

上面如果没有 veth0 和 veth1 的话,删除 br0 上的 IP 后,网络将会不通,因为没有设备和协议栈完全相连

bridge常用场景

上面通过例子展示了 bridge 的功能,但例子中的那种部署方式没有什么实际用途,还不如在一个网卡上配置多个IP地址来的直接。这里来介绍两种常见的部署方式。

虚拟机

虚拟机通过 tun/tap 或者其它类似的虚拟网络设备,将虚拟机内的网卡同 br0 连接起来,这样就达到和真实交换机一样的效果,虚拟机发出去的数据包先到达 br0,然后由 br0 交给 eth0 发送出去,数据包都不需要经过 host 机器的协议栈,效率高。

+----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+
|                          Host                                  |              VirtualMachine1            |              VirtualMachine2            |
|                                                                |                                         |                                         |
|       +------------------------------------------------+       |       +-------------------------+       |       +-------------------------+       |
|       |             Newwork Protocol Stack             |       |       |  Newwork Protocol Stack |       |       |  Newwork Protocol Stack |       |
|       +------------------------------------------------+       |       +-------------------------+       |       +-------------------------+       |
|                          ↑                                     |                   ↑                     |                    ↑                    |
|..........................|.....................................|...................|.....................|....................|....................|
|                          ↓                                     |                   ↓                     |                    ↓                    |
|                     +--------+                                 |               +-------+                 |                +-------+                |
|                     | .3.101 |                                 |               | .3.102|                 |                | .3.103|                |
|        +------+     +--------+     +-------+                   |               +-------+                 |                +-------+                |
|        | eth0 |<--->|   br0  |<--->|tun/tap|                   |               | eth0  |                 |                | eth0  |                |
|        +------+     +--------+     +-------+                   |               +-------+                 |                +-------+                |
|            ↑             ↑             ↑                       |                   ↑                     |                    ↑                    |
|            |             |             +-------------------------------------------+                     |                    |                    |
|            |             ↓                                     |                                         |                    |                    |
|            |         +-------+                                 |                                         |                    |                    |
|            |         |tun/tap|                                 |                                         |                    |                    |
|            |         +-------+                                 |                                         |                    |                    |
|            |             ↑                                     |                                         |                    |                    |
|            |             +-------------------------------------------------------------------------------|--------------------+                    |
|            |                                                   |                                         |                                         |
|            |                                                   |                                         |                                         |
|            |                                                   |                                         |                                         |
+------------|---------------------------------------------------+-----------------------------------------+-----------------------------------------+
             ↓
     Physical Network  (192.168.3.0/24)
docker

由于容器运行在自己单独的 network namespace 里面,所以都有自己单独的协议栈,情况和上面的虚拟机差不多,但它采用了另一种方式来和外界通信:

+----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+
|                          Host                                  |              Container 1                |              Container 2                |
|                                                                |                                         |                                         |
|       +------------------------------------------------+       |       +-------------------------+       |       +-------------------------+       |
|       |             Newwork Protocol Stack             |       |       |  Newwork Protocol Stack |       |       |  Newwork Protocol Stack |       |
|       +------------------------------------------------+       |       +-------------------------+       |       +-------------------------+       |
|            ↑             ↑                                     |                   ↑                     |                    ↑                    |
|............|.............|.....................................|...................|.....................|....................|....................|
|            ↓             ↓                                     |                   ↓                     |                    ↓                    |
|        +------+     +--------+                                 |               +-------+                 |                +-------+                |
|        |.3.101|     |  .9.1  |                                 |               |  .9.2 |                 |                |  .9.3 |                |
|        +------+     +--------+     +-------+                   |               +-------+                 |                +-------+                |
|        | eth0 |     |   br0  |<--->|  veth |                   |               | eth0  |                 |                | eth0  |                |
|        +------+     +--------+     +-------+                   |               +-------+                 |                +-------+                |
|            ↑             ↑             ↑                       |                   ↑                     |                    ↑                    |
|            |             |             +-------------------------------------------+                     |                    |                    |
|            |             ↓                                     |                                         |                    |                    |
|            |         +-------+                                 |                                         |                    |                    |
|            |         |  veth |                                 |                                         |                    |                    |
|            |         +-------+                                 |                                         |                    |                    |
|            |             ↑                                     |                                         |                    |                    |
|            |             +-------------------------------------------------------------------------------|--------------------+                    |
|            |                                                   |                                         |                                         |
|            |                                                   |                                         |                                         |
|            |                                                   |                                         |                                         |
+------------|---------------------------------------------------+-----------------------------------------+-----------------------------------------+
             ↓
     Physical Network  (192.168.3.0/24)

容器中配置网关为 .9.1,发出去的数据包先到达 br0,然后交给 host 机器的协议栈,由于目的 IP 是外网 IP,且 host 机器开启了 IP forward 功能,于是数据包会通过 eth0 发送出去,由于 . 9.1 是内网 IP,所以一般发出去之前会先做 NAT 转换(NAT 转换和 IP forward 功能都需要自己配置)。由于要经过 host 机器的协议栈,并且还要做 NAT 转换,所以性能没有上面虚拟机那种方案好,优点是容器处于内网中,安全性相对要高点。(由于数据包统一由 IP 层从 eth0 转发出去,所以不存在 mac 地址的问题,在无线网络环境下也工作良好)

0

评论区