Linux Bridge(网桥)
是一种虚拟网络设备,具备交换机所有的功能。Bridge
有多个端口,数据可以从多个端口进
和出
。
功能
担当交换机的角色,接入其他物理
/虚拟
网络设备。功能类似与物理交换机
,有很多 端口
,通过网线(veth pair
)连接终端设备。
Bridge
有以下特点:
Bridge
是二层设备,仅用来处理二层的通讯
Bridge
使用 MAC
地址表来决定怎么转发帧(Frame
)
Bridge
会从 host 之间的通讯数据包中学习 MAC
地址
使用场景
Bridge
设备通常会和 tap/tun
、veth pair
等设备用于虚拟机
、容器
等网络里。
与 veth pair 配合使用
用例说明:
下面通过 iproute
和 brctl
实现上述示例。
iproute 命令
$ ip link add br1 type bridge
$ ip link show br1
4: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether f6:bd:3a:67:9e:83 brd ff:ff:ff:ff:ff:ff
$ ip link set dev br1 up
$ ip link show br1
4: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/ether f6:bd:3a:67:9e:83 brd ff:ff:ff:ff:ff:ff
新创建的 br1
时,它是一个独立的网络设备
,可以看成是一端连接网络协议栈
,并且br1
没有任何端口
$ ip addr show # ens33 为物理网卡接口
$ ip link set dev ens33 master br1 # br1 的mac地址变成了 ens33 的mac地址
出现上述示例,说明ens33
已经绑定到br1
上了,注意:若当前采用 ens33 连接到主机,会断网。
$ ip addr del 192.168.179.152/24 dev ens33
$ ip link add veth1 type veth peer name veth2
$ ip link set dev veth1 up # DOWN -> LOWERLAYERDOWN
$ ip link set dev veth2 up
$ ip link set dev veth2 master br1 # 将 tap 挂载到 bridge
$ ip addr add 192.168.179.152/24 dev veth1
$ ip route add default via 192.168.179.1
- 通过
veth1
ping xiexianbin.cn
可以通到外网,br1
上抓包情况如下:
$ tcpdump -i br1 -nnt -vv icmp
tcpdump: listening on br1, link-type EN10MB (Ethernet), capture size 262144 bytes
IP (tos 0x0, ttl 64, id 18168, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.179.152 > 47.105.172.234: ICMP echo request, id 1834, seq 1, length 64
IP (tos 0x0, ttl 46, id 9335, offset 0, flags [none], proto ICMP (1), length 84)
47.105.172.234 > 192.168.179.152: ICMP echo reply, id 1834, seq 1, length 64
IP (tos 0x0, ttl 64, id 18331, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.179.152 > 47.105.172.234: ICMP echo request, id 1834, seq 2, length 64
$ bridge link
2: ens33 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br1 state forwarding priority 32 cost 4
5: veth2 state UP @veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br1 state forwarding priority 32 cost 2
$ bridge vlan
port vlan ids
ens33 1 PVID Egress Untagged
br1 1 PVID Egress Untagged
veth2 1 PVID Egress Untagged
$ bridge fdb
3a:f9:d3:81:3c:64 dev ens33 master br1
00:50:56:3b:49:58 dev ens33 master br1 permanent
00:50:56:3b:49:58 dev ens33 vlan 1 master br1 permanent
33:33:00:00:00:01 dev ens33 self permanent
01:00:5e:00:00:01 dev ens33 self permanent
33:33:ff:3b:49:58 dev ens33 self permanent
33:33:00:00:00:01 dev br1 self permanent
01:00:5e:00:00:01 dev br1 self permanent
33:33:ff:67:9e:83 dev br1 self permanent
9e:93:33:72:f9:f9 dev veth2 vlan 1 master br1 permanent
7e:c0:0e:2f:dc:36 dev veth2 master br1
9e:93:33:72:f9:f9 dev veth2 master br1 permanent
33:33:00:00:00:01 dev veth2 self permanent
01:00:5e:00:00:01 dev veth2 self permanent
33:33:ff:72:f9:f9 dev veth2 self permanent
33:33:00:00:00:01 dev veth1 self permanent
01:00:5e:00:00:01 dev veth1 self permanent
33:33:ff:2f:dc:36 dev veth1 self permanent
brctl 命令
yum install bridge-utils -y
brctl --help
Usage: brctl [commands]
commands:
addbr <bridge> add bridge
delbr <bridge> delete bridge
addif <bridge> <device> add interface to bridge
delif <bridge> <device> delete interface from bridge
hairpin <bridge> <port> {on|off} turn hairpin on/off
setageing <bridge> <time> set ageing time
setbridgeprio <bridge> <prio> set bridge priority
setfd <bridge> <time> set bridge forward delay
sethello <bridge> <time> set hello time
setmaxage <bridge> <time> set max message age
setpathcost <bridge> <port> <cost> set path cost
setportprio <bridge> <port> <prio> set port priority
show [ <bridge> ] show a list of bridges
showmacs <bridge> show a list of mac addrs
showstp <bridge> show bridge stp info
stp <bridge> {on|off} turn stp on/off # 解决二层环路问题
$ brctl addbr br2
$ brctl show br2
bridge name bridge id STP enabled interfaces
br2 8000.000000000000 no
$ ip link set dev br2 up # ifup br2
$ ip addr show # ens33 为物理网卡接口
$ brctl addif br2 ens33 # 将网卡接口添加到网桥,同时添加多个,命令:brctl addif br2 ens33 ens34 ... ,br2的mac地址变成了ens33的mac地址
$ brctl show br2
bridge name bridge id STP enabled interfaces
br2 8000.000000000000 no ens33
出现上述示例,说明ens33
已经绑定到br2
上了,注意:若当前采用ens33连接到主机,会断网。
$ ip addr del 192.168.179.152/24 dev ens33
$ ip link add veth1 type veth peer name veth2
$ ip link set dev veth1 up
$ ip link set dev veth2 up
$ brctl addif br2 veth2
$ ip addr add 192.168.179.152/24 dev veth1
$ ip route add default via 192.168.179.1
也可以配置veth1的配置文件,/etc/sysconfig/network-scripts/ifcfg-veth1
:
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
NAME="veth1"
DEVICE="veth1"
ONBOOT="yes"
IPADDR=192.168.179.152
GATEWAY=192.168.179.1
NETMASK=255.255.255.0
启动网卡接口:
ifdown veth1; ifup veth1
$ ping -c 1 192.168.179.1
PING 192.168.179.1 (192.168.179.1) 56(84) bytes of data.
64 bytes from 192.168.179.1: icmp_seq=1 ttl=64 time=0.279 ms
--- 192.168.179.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.279/0.279/0.279/0.000 ms
实现 docker 通信
上图通过 Bridge
连接两个 Docker 容器
的 tap
虚拟网卡和物理网卡 ens33
环境:
以 c7-1 容器为例,获取pid
$ docker inspect -f '{{.State.Pid}}' c7-1
3489
ping
的时候在 br0
抓包:
$ tcpdump -vv -nnt -i br0
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP (tos 0x0, ttl 64, id 44118, offset 0, flags [DF], proto ICMP (1), length 84)
172.20.0.2 > 172.20.0.1: ICMP echo request, id 120, seq 1, length 64
IP (tos 0x0, ttl 64, id 30180, offset 0, flags [none], proto ICMP (1), length 84)
172.20.0.1 > 172.20.0.2: ICMP echo reply, id 120, seq 1, length 64
ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.20.0.2 tell 172.20.0.1, length 28
ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.20.0.1 tell 172.20.0.2, length 28
ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.20.0.1 is-at 06:d9:35:e0:9e:e1, length 28
ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.20.0.2 is-at ba:2f:78:24:ad:d1, length 28