openstack中使用neutron创建router的网络结构及报文转发过程

一、首先给出openstack中neutron创建了两个vlan网络,一个router的网络结构,左图是控制节点和网络节点合并部署,右图是计算节点,可以看到计算节点上已创建出三台测试用虚拟机cirros-vm1、cirros-vm2、cirros-vm3,两个物理机节点底层通过交换机相连
openstack中使用neutron创建router的网络结构及报文转发过程_第1张图片
二、在没有创建路由器之前(上述结构图中的qrouter虚线部分还未创建),我们看一下为何cirros-vm2(172.16.101.3)去ping cirros-vm1(172.16.100.6)ping不通
2.1、172.16.101.3 ping 172.16.100.6
在这里插入图片描述
2.2、172.16.101.3上的路由如下,因为172.16.101.3 ping的目的地址172.16.100.6是外网地址,所以匹配如下路由
在这里插入图片描述
2.3、因此172.16.101.3 需要全网二层广播arp包去寻找默认网关172.16.101.1的mac地址,以便建立172.16.101.3的eth0与其网关之间的二层链路,根据网络知识,这个arp广播包应该在二层泛洪,因此在计算节点的ens37口,控制节点的ens37口,控制节点上的dhcp port口172.16.101.2均能收到172.16.101.3寻找172.16.101.1的mac地址的二层广播包
openstack中使用neutron创建router的网络结构及报文转发过程_第2张图片
openstack中使用neutron创建router的网络结构及报文转发过程_第3张图片
openstack中使用neutron创建router的网络结构及报文转发过程_第4张图片
疑问1:为什么172.16.100.2这个dhcp port不能收到arp广播报文呢?
openstack中使用neutron创建router的网络结构及报文转发过程_第5张图片
答案:这个报文是带有tag的,虽然从openstack的网络结构看,172.16.100.2和172.16.101.3是连接在同一个控制节点的br-int上,但是因为172.16.100.2和172.16.101.3这两个端口打上了不同的tag,因此这两个端口就不属于同一个网络了,其实模拟的如同如下传统网络结构,openvswitch创建的这个br-int,就相当于传统网络中的交换机,如果这个交换机没有划分vlan,那么一个全F的MAC地址会被泛洪到连接交换机的所有端口,但是openvswitch创建的这个br-int是一个模拟了打tag的交换机,也就是划分了vlan,vlan可以隔离二层广播域
openstack中使用neutron创建router的网络结构及报文转发过程_第6张图片
疑问2:172.16.101.1这个网关地址从何而来,配置在哪里呢?
答案:在使用命令创建network和subnet后,neutron subnet-show就可以看到网关的信息,这只是记录在数据库里,并没有真正配置到路由器上,待创建router后,这个网关地址就会配置到router的interface上。
openstack中使用neutron创建router的网络结构及报文转发过程_第7张图片
疑问3:紧接着疑问2,既然当前没有配置到router上,为何命令查询到数据库里有这么一个网关呢?这个网关IP还有一个作用就是是给虚拟机做默认路由用的
在这里插入图片描述
三、使用neutron创建虚拟router,分析连通性原理
3.1、创建路由打通vlan100和vlan101之间的网络,使用如下所示命令
openstack中使用neutron创建router的网络结构及报文转发过程_第8张图片
3.2、openstack网络结构如文章开头的结构图,实际模拟出如下网络结构(这个图是从虚拟机角度看底层网络,是如下网络结构,实际上,vlan、router、sw等概念均由neutron软件模拟,这里也就可以理解什么叫SDN,即软件定义网络了)
openstack中使用neutron创建router的网络结构及报文转发过程_第9张图片
此时172.16.101.3 ping 172.16.100.6肯定是可以ping通的,我们推测整个过程如下,然后同步抓包验证。
(1)cirros-vm2发现要封装的ICMP报文的目的IP地址是172.16.100.6,匹配其路由表上的默认路由,决定要将这个ICMP报文发送给下一跳,也就是网关172.16.101.1
在这里插入图片描述
但是不知道172.16.101.1的mac地址是多少,于是二层广播arp报文“who has 172.16.101.1 mac,tell 172.16.101.3”,172.16.101.1收到该报文,返回其mac地址
《在cirros-vm2的tap口和qrouter namespace 172.16.101.1的qr-xxx中抓包,能够同时抓到请求和响应的arp》
openstack中使用neutron创建router的网络结构及报文转发过程_第10张图片
在这里插入图片描述
这样cirros-vm2就可以封装二层数据帧如下,将该ICMP请求发送到GW 172.16.101.1
在这里插入图片描述
(2)GW 172.16.101.1从SW接收到该二层数据帧,从数据链路层这个层面判断目的MAC地址是给自己的,进而继续判断其三层IP信息,发现目的IP地址是172.16.100.6,通过路由表判断该地址要从本机的qr-xxx(172.16.100.1)端口转发出去
在这里插入图片描述
但是不知道172.16.100.6的MAC地址,无法封装其二层数据帧,因此需要从172.16.100.1接口发出arp二层广播请求“who has 172.16.100.6 mac,tell 172.16.100.1”
《在cirros-vm1的tap口和qrouter的172.16.100.1口抓包,可以同时抓取到请求和响应的arp》
在这里插入图片描述
openstack中使用neutron创建router的网络结构及报文转发过程_第11张图片
可以思考一下,这个二层广播请求可以在其他哪些端口抓到?
揭晓答案:可以确定的是bond0和br-int流表上均可以抓到arp广播请求,此外在172.16.100.6和172.16.100.2也可以抓到,最终响应该arp请求的是172.16.100.6
然后router就可以封装二层数据帧,将源和目的MAC换成如下,然后将该报文发送到cirros-vm1上
在这里插入图片描述
(3)cirros-vm1接收到该报文,数据链路层判断MAC地址是自己的MAC,因此解包,网络层判断目的IP地址是自己,因此处理数据,根据ICMP协议规定,收到Echo request后,需要返回一个同样的报文Echo reply给源主机,因此cirros-vm1开始封装报文,目的IP是172.16.101.3 ,查看路由表,需要将该报文发给网关 172.16.100.1
可以思考一下,那么此时cirros-vm1知不知道其网关172.16.100.1的MAC地址呢?
揭晓答案:根据步骤(2)描述的过程,GW-100这个网关曾经向cirros-vm1发送过arp广播,这个arp广播中已经包含了GW-100的IP地址和MAC地址,cirros-vm1已经学到了该MAC地址,所以直接封装数据包发送到网关GW-100
在这里插入图片描述
(4)网关拿到该数据包,根据路由表判断目的IP为172.16.101.3应该从qr-xxx(172.16.101.1)转发出去,路由器修改源和目的MAC地址后,最终交付到cirros-vm2,至此,ping过程正常结束
四、与传统网络相比,neutron模拟的网络是如何实现的
对于传统网络,VM就相当于一个终端,连接到物理交换机和物理路由器上,他们之间的数据转发依照我们所理解的传统网络一样;而openstack上的虚拟机发送的报文,对于虚拟机的应用来说,它只负责按照ISO七层模型封装数据,然后从其tap口发出,至于报文从tap口出去之后,如何交付到目的地,是由neutron构建的虚拟网络以及连接计算节点之间的物理网络设备来负责转发,neutron中使用了ovs-agent去调用ovs的命令行创建br-int,并且给连接上br-int的各个qvo或者tap口打上tag,打tag的过程就相当于给连接到br-int的端口划分了vlan,这个tag是给虚拟机使用的,虚拟机视角看到的br-int即交换机,tag即交换机划分的vlan tag,虚拟机在封装网络报文时,就会打上相应的tag来区分,但是这个tag只能在虚机层面识别,当这个tag走到计算节点之外的物理交换机时,br-int上这样的tag就无法被物理交换机识别了,物理交换机上有其自己的vlan tag,br-int上的tag如何与物理交换机上的tag转化,这就需要流表来做转化。看到这里一个客户想当然的疑问就出来了,为何物理交换机不使用br-int上相同的tag呢?这样不是更简单?给出的解释就是,如果br-int和物理交换机使用同一个tag,这样openstack虚拟机的网络,就要和底层物理网络有很大的关联性,比如底层物理网络交换机使用的是vxlan,vxlan的id范围比较大,这个vxlan id也没办法和ovs的br-int上的vlan tag对应起来的;云环境中虚拟机数量很大,network的数量也多,每个network都需要唯一的vlan id来识别,br-int上的vlan id也是不够用的。

你可能感兴趣的:(openstack中使用neutron创建router的网络结构及报文转发过程)