网络虚拟化之虚拟交换机技术Linux Bridge

一、概述

接上篇网络虚拟化之虚拟网卡技术veth再来看看虚拟交换机技术Linux Bridge。

网络虚拟化之虚拟交换机技术Linux Bridge_第1张图片

 几个核心点:

1.veth只能成对出现,多对多就需要一个交换机

2.Linux Bridge覆盖物理交换机所有功能

3.Linux Bridge比物理交换机多一个转发本机协议栈的数据包

4.单IP的主机上多个容器可以通过Bridge与外部通讯,此时主机扮演路由器角色实现SNAT和DNAT转换

二、核心原理

有了虚拟网卡,很自然也会联想到让网卡接入到交换机里,实现多个容器间的相互连接。Linux Bridge 便是 Linux 系统下的虚拟化交换机,虽然它以“网桥”(Bridge)而不是“交换机”(Switch)为名,然而使用过程中,你会发现 Linux Bridge 的目的看起来像交换机,功能使用起来像交换机、程序实现起来也像交换机,实际就是一台虚拟交换机。Linux Bridge 是在 Linux Kernel 2.2 版本开始提供的二层转发工具,由 brctl 命令创建和管理。Linux Bridge 创建以后,便能够接入任何位于二层的网络设备,无论是真实的物理设备(譬如 eth0)抑或是虚拟的设备(譬如 veth 或者 tap)都能与 Linux Bridge 配合工作

Linux Bridge 允许给自己设置 IP 地址,比普通交换机多出一种特殊的转发情况:
如果数据包的目的 MAC 地址为网桥本身,并且网桥有设置了 IP 地址的话,那该数据包即被认为是收到发往创建网桥那台主机的数据包,此数据包将不会转发到任何设备,而是直接交给上层(三层)协议栈去处理。通过这种方式可以实现连接到Linux bridge的设备与外部通信,主机扮演路由器角色。

三、使用示例

1.用iproute2创建一个bridge:

sudo ip link add name mbr0 type bridge
sudo ip link set mbr0 up

ifconfig可以看到这个设备

ifconfig

br0: flags=4163  mtu 1500
        inet6 fe80::2c0a:ceff:fe21:d304  prefixlen 64  scopeid 0x20
        ether 2e:0a:ce:21:d3:04  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

新建一个bridge时,它是一个独立的网络设备,只有一个端口连着协议栈,其它的端口啥都没连,这样的bridge没有任何实际功能。注意此时的Mac地址!

2.将bridge和veth设备相连

 上篇网络虚拟化之虚拟网卡技术veth 中创建过一对veth设备,并配置上IP

sudo ip link add veth0 type veth peer name veth1
sudo ip addr add 10.1.1.100/24 dev veth0
sudo ip addr add 10.1.1.101/24 dev veth1
sudo ip link set veth0 up
sudo ip link set veth1 up

将veth0连上mbr0

sudo ip link set dev veth0 master mbr0

再次ifconfig看一下:

mbr0: flags=4163  mtu 1500
        inet6 fe80::2c0a:ceff:fe21:d304  prefixlen 64  scopeid 0x20
        ether 92:53:19:cf:65:d4  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

mbr0的Mac地址变了,变成veth0的Mac地址。

通过bridge link命令可以看到mbr0上连接了哪些设备

sudo bridge link

网络连接如下:

5: veth5479fd5 state UP @(null): mtu 1500 master docker0 state forwarding priority 32 cost 2
17: veth0 state UP @veth1: mtu 1500 master br0 state forwarding priority 32 cost 2

(本机还有另外一个veth,忽略。)

先来测试下通过veth0能否连接上veth1。

ping 10.1.1.101 -I veth0
PING 10.1.1.101 (10.1.1.101) from 10.1.1.100 veth0: 56(84) bytes of data.
^C
--- 10.1.1.101 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms

结果是没通!

veth0抓包如下:

sudo tcpdump -n -i veth0 -v
tcpdump: listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:35:10.736503 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.1.1.101 tell 10.1.1.100, length 28
17:35:10.736537 ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28
17:35:11.738057 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.1.1.101 tell 10.1.1.100, length 28
17:35:11.738103 ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28
17:35:12.740059 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.1.1.101 tell 10.1.1.100, length 28
17:35:12.740143 ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28

veth1抓包如下:

sudo ip netns exec test-yao 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
17:35:10.736516 ARP, Request who-has 10.1.1.101 tell 10.1.1.100, length 28
17:35:10.736536 ARP, Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28
17:35:11.738069 ARP, Request who-has 10.1.1.101 tell 10.1.1.100, length 28
17:35:11.738103 ARP, Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28
17:35:12.740122 ARP, Request who-has 10.1.1.101 tell 10.1.1.100, length 28
17:35:12.740142 ARP, Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28

都存在ARP包,并且回复了mac地址。

虚拟交互机mbr0的包数据:

sudo tcpdump -n -i mbr0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on mbr0, link-type EN10MB (Ethernet), capture size 262144 bytes

17:41:25.954578 ARP, Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28
17:41:26.956075 ARP, Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28
17:41:27.958091 ARP, Reply 10.1.1.101 is-at 82:ed:5e:ed:4f:94, length 28

mbr0收到了所有的ARP的Reply,但是并没有往协议栈发送,所以ping进程并读不到Mac就通信失败了。

结论:mbr0拦截在veth0和协议栈之间,将veth0本来要转发给协议栈的数据给拦截了,全部转发给bridge了,同时mbr0也可以向veth0发数据。

上面提到过如果mbr0不配置IP是不能转发数据包给协议栈了,在这种情况,通过veth0来ping veth1当然就不通了。

接下来给虚拟交换机mbr0配置上IP,可以配置成跟veth0一致试试。因为veth0已经不会从协议栈接收和发送数据,而是通过mbr0,veth0只负责连接mbr0和veth1,退化成一根网线。

sudo ip addr add 10.1.1.100/24 dev mbr0

看下路由表信息:

route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway         0.0.0.0         UG    0      0        0 eth0
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 veth0
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 mbr0
link-local      0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.1.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.2.4.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

为避免veth0路由影响建议删除:sudo ip addr del 10.1.1.100/24 dev veth0

此时通过mbr0来访问veth1,试验一下:

ping 10.1.1.101 -I mbr0
PING 10.1.1.101 (10.1.1.101) from 10.1.1.100 mbr0: 56(84) bytes of data.
64 bytes from 10.1.1.101: icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from 10.1.1.101: icmp_seq=2 ttl=64 time=0.107 ms
64 bytes from 10.1.1.101: icmp_seq=3 ttl=64 time=0.108 ms

成功啦! 

PS: 此时直接ping 101地址,不指定mbr0也是可以通的;在未配置IP前也是不通的。

可以创建很多veth pair,一端都连在同一个bridge上,另一端连在容器里,这样就可以互相通讯,解决同一台主机上多个容器间的通讯问题。如果bridge指定IP后,主机可以访问容器内,容器内可以访问主机和外部。

你可能感兴趣的:(网络技术,Linux,网络,linux,bridge,容器网络)