Linux虚拟网络设备之bridge,route,ip route,ip rule

继前两篇介绍了tun/tapveth之后,本篇将介绍Linux下常用的一种虚拟网络设备,那就是bridge(桥)。

Linux ip netns 命令-CSDN博客

veth-pair,netns-CSDN博客

图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN_veth 转发 有拷贝-CSDN博客

virsh 获取虚机IP,网桥ip,brctl,arp使用_virsh查看虚拟机ip-CSDN博客

ip tunnel 隧道技术-CSDN博客

Linux ip netns 命令-CSDN博客

【网络】route和 IP route的区别|route 和 IP route 添加路由_ip r 添加路由_bandaoyu的博客-CSDN博客 

本篇将通过实际的例子来一步一步解释bridge是如何工作的。

什么是bridge?

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

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

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

桌面版
第一步:安装工具:
apt-get install gir1.2-spiceclientgtk-3.0 qemu-utils qemu-kvm virt-manager libvirt-daemon-system bridge-utils
检查服务是否启动
systemctl status libvirtd

第二步:
创建网桥
brctl addbr br0

第三步给网桥配置ip:
ifconfig br0 192.168.0.26 netmask 255.255.255.0 broadcast 192.168.0.255 up

第四步网卡加到桥上面去:
brctl addif br0 ens2p0

第五步
启动虚拟机安装windows系统即可

路由信息
allen@jettech-WS-C621E-SAGE-Series:~$ route
内核 IP 路由表
目标            网关            子网掩码        标志  跃点   引用  使用 接口
default         _gateway        0.0.0.0         UG    0      0        0 br1
default         _gateway        0.0.0.0         UG    100    0        0 enp4s0
default         _gateway        0.0.0.0         UG    20101  0        0 enp5s0
link-local      0.0.0.0         255.255.0.0     U     1000   0        0 br1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 br1
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 enp4s0
192.168.0.0     0.0.0.0         255.255.255.0   U     101    0        0 enp5s0

 结果是自上而下, 就是说, 哪条在前面, 哪条就有优先, 前面都没有, 就用最后一条default 

1、第一行的意思就是去往所有目标地址数据包通过网卡eth0 发到网关192.168.124.1 ,Flags那一列中有G时才会使用Gateway

2、第二行:表示去往192.168.1.0 的由eth0发出的数据 将发往网关192.168.124.254

3、第三行:表示去往192.168.2.0 的由eth0发出的数据 将发往网关192.168.1244.253

4、第四行:表示去往192.168.122.0地址的数据包通过virbr0网桥设备来转发

5、第五行:表示去往192.168.124.0 地址的数据 交给eth0网卡发送
 

1,2,4 行是网络ip ,当前主机发往这三个网络的信息 根据geteway 列是零,可以推断为现将信息发给缺省网关(192.168.1.254)再由它发给其他路由最终达到目的网路. 

Destination:目标,目标网络和目标主机
Gateway:网关, 网关地址
Genmask:网络掩码
Flags: 
Metric:距离,跳数
Ref:恒为0
Use:表示该路由使用的此处,
Iface:接口,即网卡名 

#添加一条路由(发往192.168.62这个网段的全部要经过网关192.168.1.1)
route add -net 192.168.62.0 netmask 255.255.255.0 gw 192.168.1.1
 
#删除一条路由 删除的时候不用写网关
route del -net 192.168.122.0 netmask 255.255.255.0
 

示例1:添加到主机路由 (指定一个主机-host 192.168.4.2)

route add –host 192.168.4.2 dev eth0:1
route add –host 192.168.4.1 gw 192.168.4.250

示例2:添加到网络的路由(指定一个网络-net 192.168.2.0/24)

route add –net IP netmask MASK eth0
route add –net IP netmask MASK gw IP
route add –net IP/24 eth1

routeadd -net 192.168.1.11 netmask 255.255.255.0 eth0

routeadd -net 192.168.1.11 netmask 255.255.255.0 gw 192.168.1.1

routeadd -net 192.168.1.0/24 eth0

routeadd-net192.168.1.0/24gw192.168.1.1

route add -net 192.168.2.0/24 gw 192.168.1.1
route add -host 192.168.2.100/32 gw 192.168.1.1
示例3:添加默认网关

route add default gw IP

route add default gw 192.168.1.1

删除路由
route del -net 192.168.2.0/24 gw 192.168.1.1
route del -host 192.168.2.100/32 gw 192.168.1.1
 

示例和说明:

有两块网卡if1和if2
eth0: 192.168.10.23/255.255.255.0
eth1: 192.168.20.22/255.255.255.0

添加路由命令如下
route add -net 192.168.10.0 netmask 255.255.255.0 dev eth0
route add -net 192.168.20.0 netmask 255.255.255.0 dev eth1

通过上面两个命令, 发往192.168.10.0网段的IP包会通过eth0发送, 发往192.168.20.0网段的IP包会通过eth1发送. 

如果其它网段的IP包如何发送? 需要设置一个默认网关, 命令如下
route add default gw 192.168.20.1

通过上面命令, 会将除了这两个网络的IP包都发往192.168.20.1网关, 如何转发到192.168.20.1网关? 在上面的两条路由项中已经定义了, 会通过eth1网口转发,

route  命令说明
route  [-v] [-A family |-4|-6] del [-net|-host] target [gw Gw] [netmask Nm] [metric N] [[dev] If]

简化版

route  [add|del] [-net|-host] target [netmask Nm] [gw Gw] [[dev] If]

注:虽然可指定网络接口,但是不建议这么做。

参数解释

add:添加一条路由规则

del:删除一条路由规则

-net:目的地址是一个网络

-host:目的地址是一个主机

target:目的网络或主机

netmask:目的地址的网络掩码

gw:路由数据包通过的网关

dev:为路由指定的网络接口

 route添加路由持久化:
Linux下配置永久路由的几种方式
命令行添加或删除,默认只在内存中生效。当重启网络或者重启主机后就失效了。为了路由开机加载生效可以将路由信息写到/etc/rc.local或者/etc/sysconfig/static-routes中;

其中写到/etc/rc.local的命令格式原样即可,写到/etc/sysconfig/static-routes中的命令格式如下:

添加到主机的路由:

any host 192.168.101.200 gw 192.168.101.1

添加到网络的路由:

any net 192.168.101.0/24 gw 192.168.101.1

1.在/etc/rc.local里添加路由信息

route add -net 192.168.3.0/24 dev eth0
route add -net 192.168.2.0/24 gw 192.168.3.254

#或者

route add -net192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1

2.在/etc/sysconfig/network里追加

GATEWAY=[网关IP或者网关网卡名称]

 GATEWAY=gw-ip 或者 GATEWAY=gw-dev

3./etc/sysconfig 中添加文件

添加永久静态路由(方法一):
  [root@localhost ~]# vi /etc/sysconfig/static-routes
  any  net 192.168.10.0/24 gw 172.16.15.254
  any  net 192.168.177.0/24 gw 172.16.15.254

  添加永久静态路由(方法二):
  vi route-ens33 (ens33是centos7的接口形式)
  192.168.177.0/24 via 172.16.15.254 dev ens33
  192.168.10.0/24 via 172.16.15.254 dev ens33
 

static-routes文件为路由固化文件。

1./etc/sysconfig目录下,系统一般不会自动生成static-routes文件,需要手工创建。
2.static-routes文件中路由固化的格式
① 添加默认路由
any net 0.0.0.0 netmask 0.0.0.0 gw 10.92.2.1
或者
any net 0.0.0.0/0 gw 10.92.2.1

② 添加网络路由
any net 1.1.1.0  netmask 255.255.255.0 gw 1.1.1.10
或者
any net 1.1.1.0/24 gw 1.1.1.10

/etc/sysconfig/static-router :

any net x.x.x.x/24 gw y.y.y.y

4.开启IP转发

1.临时开启

echo"1">/proc/sys/net/ipv4/ip_forward

2.永久开启

vim/etc/sysctl.conf

修改net.ipv4.ip_forward=1

不同方法的优劣
两种方式添加静态路由对比

写/etc/rc.local

重启服务器生效;

重启网络服务,则静态路由失效;

/etc/rc.local是系统启动后最后运行的一个脚本,因此如果有如NFS需要网络才能挂载的服务需求,则该方式不适合;

写/etc/sysconfig/static-routes

重启服务器生效;

重启网络服务生效:

适合需要网络需求的服务,如NFS;

总结:添加静态路由最好是写到/etc/sysconfig/static-routes中,避免重启网络或者重启主机后路由不生效。
 

添加路由:

//添加到主机的路由

route add –host 192.168.1.11 dev eth0
route add –host 192.168.1.12 gw 192.168.1.1

//添加到网络的路由

route add –net 192.168.1.11 netmask 255.255.255.0 eth0
route add –net 192.168.1.11 netmask 255.255.255.0 gw 192.168.1.1
route add –net 192.168.1.0/24 eth1

//添加默认网关

route add default gw 192.168.2.1

//删除路由

route del –host 192.168.1.11 dev eth0

 二:在linux下设置永久路由的方法:

./etc/sysconfig/static-routes :
any net 192.168.3.0/24 gw 192.168.3.254
any net 10.250.228.128 netmask 255.255.255.192 gw 10.250.228.129
使用static-routes的方法是最好的。无论重启系统和service network restart 都会生效
static-routes文件又是什么呢,这个是network脚本执行时调用的一个文件,这个文件的放置在/etc/sysconfig目录下,在network脚本中的位置是:
if [ -f /etc/sysconfig/static-routes ]; then
grep “^any” /etc/sysconfig/static-routes | while read ignore args ; do
/sbin/route add -$args
done
fi

从这段脚本可以看到,这个就是添加静态路由的方法,static-routes的写法是
any net 192.168.0.0/16 gw 网关ip

【网络】route和 IP route的区别|route 和 IP route 添加路由_ip r 添加路由_bandaoyu的博客-CSDN博客

命令	解释
ip route add default via 192.168.1.1	设置系统默认路由
ip route add 192.168.2.0/24 via 192.168.1.1	设置192.168.2.0网段的网关为192.168.1.1
ip route add 192.168.4.0/24 via 192.168.0.254 dev eth0	设置192.168.4.0网段的网关为192.168.0.254,数据走eth0接口
ip route add default via 192.168.0.254 dev eth0	设置默认网关为192.168.0.254
ip route add default via 192.168.1.1 table 1	在一号表中添加默认路由为192.168.1.1
ip route add 192.168.0.0/24 via 192.168.1.2 table 1	在一号表中添加一条到192.168.0.0网段的路由为192.168.1.2
ip route add prohibit 209.10.26.51	设置请求的目的地不可达的路由
ip route add prohibit 209.10.26.51 from 192.168.99.35	假设您不想阻止所有用户访问此特定主机,则可以使用该from选项,阻止了源IP 192.168.99.35到达209.10.26.51
ip route change default via 192.168.99.113 dev eth0	更改默认路由。此操作等同于先删除,后新增

创建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连上br0

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也可以向veth0发数据。

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

通过veth0 ping veth1失败:

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 :  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
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

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

 

上面如果没有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地址的问题,在无线网络环境下也工作良好)

上面两种部署方案中,同一网段的每个网卡都有自己单独的协议栈,所以不存在上面说的多个ARP的问题

======================================

前言

以下针对linux 下 virt-manager 管理kvm虚拟机配置网络类型,默认为nat。
nat网络模式,虚拟机之间可通信,虚拟机和主机可通信,不可与主机外的网络通信;
桥接网络模式,虚拟机之间可通信,虚拟机和主机可通信,可与主机外的网络通信。

配置桥接模式

1、创建新的以太网桥

brctl addbr br0

2、网桥配置ip

ifconfig br0 172.1.1.143 netmask 255.255.255.0 up

3、向现有网桥添加接口

1)首先保证ens9f0是down状态
执行,(如果是远程链接的宿主机,执行后你就掉线了)

nmcli c down ens9f0

(2)网桥添加接口

brctl addif br0 ens9f0

这个步骤可能会遇到的问题

device ens9f0is already a member of a bridge :can`t enslave it to bridge br0

即已经桥接了其他网桥,这时候
执行 nmcli connection 查看

nmcli connection

再执行 nmcli c de xxx 删除网桥xxx

nmcli c de xxx

最后再网桥添加接口

brctl addif br0 ens9f0

4、重启网络

systemctl restart NetworkManager
/etc/init.d/networking restart 

有可能不需要重启
重启后如果ifconfig看不见br0
那就执行
ifconfig br0 172.1.1.143 netmask 255.255.255.0 up

执行完 ,再执行ifconfig查看发现设备和网桥硬件地址一样

ifconfig

5、虚拟机配置

virt-manager

4、配置虚拟机ip
最后根据主机,配置一下虚拟机的ip即可,配置的ip和桥接的主机ip在同一网段即可。
如:
在这里插入图片描述

5、配置成功
ping 一下主机的ip,和主机外ip,能ping通即成功了!

最后附上网络配置的一些命令

显示所有网络连接的信息:
nmcli connection show

关闭指定连接:
nmcli c down ens9f0

启动指定连接:
nmcli c up ens9f0

删除指定连接:
nmcli c delete ens9f0# 或
nmcli c de ens9f0


使用 show 显示可用的以太网桥
brctl show

addbr 创建新的以太网桥
brctl addbr br0 

配置ip
ifconfig br0 192.168.0.100 netmask 255.255.255.0 up

关闭网桥STP
brctl stp br0 off

使用delbr删除现有的以太网桥
brctl delbr br0 

向现有网桥添加接口
brctl addif br0 ens9f0

向现有网桥删除接口
brctl delif br0 ens9f0


/etc/sysconfig/network-scripts/

/etc/network/interface

nmcli 网卡配置路径
/etc/NetworkManager/system-connections/

查看网口插接状态
cat /sys/class/net/eth0/carrier
1
1表示插接

如果是down的状态,需要先up下
cat /sys/class/net/eth0/operstate
ip link set dev eth1 up
然后再查看
cat /sys/class/net/eth0/carrier

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值