如何理解vxlan在openstack中的使用场景

86次阅读
没有评论

共计 7652 个字符,预计需要花费 20 分钟才能阅读完成。

这篇文章给大家介绍如何理解 vxlan 在 openstack 中的使用场景,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

一、前言

介绍前,首先讲一下网络中 underlay 和 overlay 的概念。underlay 指的是物理网络层,overlay 是指在物理网络层之上的逻辑网络或者又称为虚拟网络。overlay 是建立在 underlay 的基础上,需要物理网络中的设备两两互联,overlay 的出现突破了 underlay 的物理局限性,使得网络的架构更为灵活。以 vlan 为例,在 underlay 环境下不同网络的设备需要连接至不同的交换机下,如果要改变设备所属的网络,则要调整设备的连线。引入 vlan 后,调整设备所属网络只需要将设备加入目标 vlan 下,避免了设备的连线调整。

二、云环境下 vlan 的痛点

vlan id 数量不足  
vlan header 由 12bit 组成,理论上限为 4096 个,可用 vlan 数量为 1~4094 个,无法满足云环境下的需求。

vm 热迁移  
云计算场景下,传统服务器变成一个个运行在宿主机上的 vm。vm 是运行在宿主机的内存中,所以可以在不中断的情况下从宿主机 A 迁移到宿主机 B,前提是迁移前后 vm 的 ip 和 mac 地址不能发生变化,这就要求 vm 处在一个二层网络。毕竟在三层环境下,不同 vlan 使用不同的 ip 段,否则路由器就犯难了。

mac 表项有限  
普通的交换机 mac 表项有 4k 或 8k 等,在小规模场景下不会成为瓶颈,云计算环境下每台物理服务器上运行多台 vm,每个 vm 有可能有多张 vnic,mac 地址会成倍增长,交换机的表项限制则成为必须面对的问题。

三、针对痛点 vxlan 的解决方法

以多取胜  
vxlan header 由 24bit 组成,所以理论上 VNI 的数量为 16777216 个,解决了 vid 数量不足的问题。 
此处需要说明的是:在 openstack 中,尽管 br-tun 上的 vni 数量增多,但 br-int 上的网络类型只能是 vlan,所有 vm 都有一个内外 vid(vni)转换的过程,将用户层的 vni 转换为本地层的 vid。 
细心的你可能会有这样的疑问:尽管 br-tun 上 vni 的数量为 16777216 个,但 br-int 上 vid 只有 4096 个,那引入 vxlan 是否有意义?答案是肯定的,以目前的物理机计算能力来说,假设每个 vm 属于不同的 tenant,1 台物理机上也不可能运行 4094 个 vm,所以这么映射是有意义的。 
如何理解 vxlan 在 openstack 中的使用场景    
上图是 2 计算节点间 vm 通信的示意图,图中所有的 vm 属于同一个 tenant,尽管在用户层同一 tenant 的 vni 一致,但在本地层,同一 tenant 由 nova-compute 分配的 vid 可以不一致,同一宿主机上同一 tenant 的相同 subnet 之间的 vm 相互访问不需要经过内外 vid(vni)转换,不同宿主机上相同 tenant 的 vm 之间相互访问则需要经过 vid(vni)转换。如果所有宿主机上 vid 和 vni 对应关系一致,整个云环境最多只能有 4094 个 tenant,引入 vxlan 才真的没有意义。

暗渡陈仓  
前面说过,vm 的热迁移需要迁移前后 ip 和 mac 地址不能发生管改变,所以需要 vm 处于一个二层网络中。vxlan 是一种 overlay 的技术,将原有的报文进行再次封装,利用 udp 进行传输,所以也称为 mac in udp,表面上传输的是封装后的 ip 和 mac,实际传播的是封装前的 ip 和 mac。   
如何理解 vxlan 在 openstack 中的使用场景

销声匿迹  
在云环境下,接入交换机的表项大小会成为瓶颈,解决这个问题的方法无外乎两种: 
1. 扩大表项:更高级的交换机有着更大的表项,使用高级交换机取代原有接入交换机,此举会增加成本。   
2. 隐藏 mac 地址:在不增加成本的前提下,使用 vxlan 也能达到同样的效果。前文得知,vxlan 是对原有的报文再次封装,实现 vxlan 功能的 vetp 角色可以位于交换机或者 vm 所在的宿主机,如果 vtep 角色位于宿主机上,接入交换机只会学习经过再次封装后 vtep 的 mac 地址,不会学习其上 vm 的 mac 地址。 
如何理解 vxlan 在 openstack 中的使用场景      
如果 vtep 角色位于接入交换机上,处理报文的效率更高,但是接入交换机会学习到 vm 的 mac 地址,表项的限制依然没有得到解决,后续对这两种情况会做详细说明。 
以上就是 openstack 场景中使用 vxlan 的原因,下面将会对 vxlan 的实现原理进行详细说明。

四、vxlan 实现机制

vxlan 报文长什么样  
vxlan 报文是在原有报文的基础上再次进行封装,已实现三层传输二层的目的。   
如何理解 vxlan 在 openstack 中的使用场景    
如上图所示,原有封装后的报文成为 vxlan 的 data 部分,vxlan header 为 vni,ip 层 header 为源和目的 vtep 地址,链路层 header 为源 vtep 的 mac 地址和到目的 vtep 的下一个设备 mac 地址。 
在笔者所从事的公有云架构中,vtep 角色通过宿主机上的 ovs 实现,宿主机上联至接入交换机的接口类型为 trunk,在物理网络中为 vtep 专门规划出一个网络平面    
如何理解 vxlan 在 openstack 中的使用场景    
vm 在经过 vtep 时,通过流表规则,去除 vid,添加上 vni  
如何理解 vxlan 在 openstack 中的使用场景      
vtep 平面规划的 vid 在 vxlan 的封装过程中被打上,原因如下图所示,vxlan 的 mac header 中可以设置 vlan tag  
如何理解 vxlan 在 openstack 中的使用场景

vtep 是什么  
vtep 全称 vxlan tunnel endpoint,vxlan 可以抽象的理解为在三层网络中打通了一条条隧道,起点和终点的两端就是 vetp。vtep 是实现 vxlan 功能的重要模型,可以部署在接入交换机或者服务器上,部署在不同的位置除了前文中提到是否学习 vm 的 mac 地址外,实现的机制也所有不同,以下内容如无特别说明,默认 vtep 部署在接入交换机上,vtep 部署在服务器上后面会单独说明。

vxlan 隧道的建立  
对于物理交换机而言,vtep 是物理交换机上的一个角色,换句话说,vtep 只是交换机上的一部分功能,并非所有的报文都需要走 vxlan 隧道,报文也可能走普通的二三层转发。那么哪些报文需要走 vxlan 隧道?   
如何理解 vxlan 在 openstack 中的使用场景      
如上图所示,vxlan 打造了一个大二层的概念,当连接两个不同 vtep 的 vm 需要进行通信时,就需要建立 vxlan 隧道。每一个大二层域称为一个 bridge-domain,简称 bd,类似于 vlan 的 vid,不同的 bd 用 vni 表示,bd 与 vni 是 1:1 的关系。 
创建 bd 和设置 bd 与 vni 对应关系的配置如下: 

# 
bridge-domain 10 // 创建一个编号为 10 的 bd 
vxlan vni 5000 // 设置 bd10 对应的 vni 为 5000 
#

vtep 会根据以上配置生成 bd 与 vni 的映射关系表,该映射表可以通过命令行查看,如下所示: 
如何理解 vxlan 在 openstack 中的使用场景    
有了映射表后,进入 vtep 的报文就可以根据自己所属的 bd 来确定报文封装时该添加哪个 vni。问题就剩下报文根据什么来确定自己属于哪个 bd。 
它可以通过二层子接口接入 vxlan 隧道和 vlan 接入 vxlan 隧道来实现。二层子接口主要做两件事:一是根据配置来检查哪些报文需要进入 vxlan 隧道;二是判断对检查通过的报文做怎样的处理。 
如何理解 vxlan 在 openstack 中的使用场景    
如上图所示,基于二层物理接口 10GE 1/0/1,分别创建二层子接口 10GE 1/0/1.1 和 10GE 1/0/1.2,且分别配置其流封装类型为 dot1q 和 untag。配置如下:

# 
interface 10GE1/0/1.1 mode l2 // 创建二层子接口 10GE1/0/1.1 
encapsulation dot1q vid 10 // 只允许携带 VLAN Tag 10 的报文进入 VXLAN 隧道  
bridge-domain 10 // 报文进入的是 BD 10 
# 
interface 10GE1/0/1.2 mode l2 // 创建二层子接口 10GE1/0/1.2 
encapsulation untag // 只允许不携带 VLAN Tag 的报文进入 VXLAN 隧道  
bridge-domain 20 // 报文进入的是 BD 20 
#

基于二层物理接口 10GE 1/0/2,创建二层子接口 10GE 1/0/2.1,且流封装类型为 default。配置如下:

# 
interface 10GE1/0/2.1 mode l2 // 创建二层子接口  
10GE1/0/2.1 encapsulation default // 允许所有报文进入 VXLAN 隧道  
bridge-domain 30 // 报文进入的是 BD 30 
#

至此,所有条件都已具备,就可以通过协议自动建立 vxlan 隧道隧道,或者手动指定 vxlan 隧道的源和目的 ip 地址在本端 vtep 和对端 vtep 之间建立静态 vxlan 隧道。对于华为 CE 系列交换机,以上配置是在 nve(network virtualization Edge)接口下完成的。配置过程如下:

# 
interface Nve1 // 创建逻辑接口  
NVE 1 source 1.1.1.1 // 配置源 VTEP 的 IP 地址(推荐使用 Loopback 接口的 IP 地址) 
vni 5000 head-end peer-list 2.2.2.2 
vni 5000 head-end peer-list 2.2.2.3 
#

其中,vni 5000 的对端 vtep 有两个,ip 地址分别为 2.2.2.2 和 2.2.2.3,至此,vxlan 隧道建立完成。 
VXLAN 隧道两端二层子接口的配置并不一定是完全对等的。正因为这样,才可能实现属于同一网段但是不同 VLAN 的两个 VM 通过 VXLAN 隧道进行通信。 
总结一下,vxlan 目前支持三种封装类型,如下表所示: 
如何理解 vxlan 在 openstack 中的使用场景    
这种方法当有众多个 vni 的时候,需要为每一个 vni 创建一个子接口,会变得非常麻烦。 
如何理解 vxlan 在 openstack 中的使用场景    
此时就应该采用 vlan 接入 vxlan 隧道的方法。vlan 接入 vxlan 隧道只需要在物理接口下允许携带这些 vlan 的报文通过,然后再将 vlan 与 bd 绑定,建立 bd 与 vni 对应的 bd 信息,最后创建 vxlan 隧道即可。   
如何理解 vxlan 在 openstack 中的使用场景    
vlan 与 bd 绑定的配置如下:

# 
bridge-domain 10 // 创建一个编号为 10 的 bd 
l2 binding vlan 10 // 将 bd10 与 vlan10 绑定  
vxlan vni 5000 // 设置 bd10 对应的 vni 为 5000 
#

同子网 vxlan 通信流程  
如何理解 vxlan 在 openstack 中的使用场景    
如上图所示,假设 vtep 是通过接入交换机上的子接口实现,VM_A 与 VM_C 进行首次进行通信。由于是,VM_A 上没有 VM_C 的 MAC 地址,所以会发送 ARP 广播报文请求 VM_C 的 MAC 地址。就以 ARP 请求报文及 ARP 应答报文的转发流程,来说明 MAC 地址是如何进行学习的。 
如何理解 vxlan 在 openstack 中的使用场景    
ARP 请求报文的转发流程如下: 
1. VM_A 发送源 MAC 为 MAC_A、目的 MAC 为全 F、源 IP 为 IP_A、目的 IP 为 IP_C 的 ARP 广播报文,请求 VM_C 的 MAC 地址。 
2. VTEP_1 收到这种 BUM(Broadcast Unknown-unicast Multicast)请求后,会根据头端复制列表对报文进行复制,并分别进行封装。根据二层子接口上的配置判断报文需要进入 VXLAN 隧道。确定了报文所属 BD 后,也就确定了报文所属的 VNI。同时,VTEP_1 学习 MAC_A、VNI 和报文入接口(Port_1,即二层子接口对应的物理接口)的对应关系,并记录在本地 MAC 表中。 
3. 报文到达 VTEP_2 和 VTEP_3 后,VTEP 对报文进行解封装,得到 VM_A 发送的原始报文。同时,VTEP_2 和 VTEP_3 学习 VM_A 的 MAC 地址、VNI 和远端 VTEP 的 IP 地址(IP_1)的对应关系,并记录在本地 MAC 表中。之后,VTEP_2 和 VTEP_3 根据二层子接口上的配置对报文进行相应的处理并在对应的二层域内广播。 
VM_B 和 VM_C 接收到 ARP 请求后,比较报文中的目的 IP 地址是否为本机的 IP 地址。VM_B 发现目的 IP 不是本机 IP,故将报文丢弃;VM_C 发现目的 IP 是本机 IP,则对 ARP 请求做出应答。 
ARP 应答报文转发流程如下图所示: 
如何理解 vxlan 在 openstack 中的使用场景      
4. 由于此时 VM_C 上已经学习到了 VM_A 的 MAC 地址,所以 ARP 应答报文为单播报文,单播报文就不再进行头端复制。报文源 MAC 为 MAC_C,目的 MAC 为 MAC_A,源 IP 为 IP_C、目的 IP 为 IP_A。 
5. VTEP_3 接收到 VM_C 发送的 ARP 应答报文后,识别报文所属的 VNI(识别过程与步骤 2 类似)。同时,VTEP_3 学习 MAC_C、VNI 和报文入接口(Port_3)的对应关系,并记录在本地 MAC 表中。之后,VTEP_3 对报文进行封装。这里封装的外层源 IP 地址为本地 VTEP(VTEP_3)的 IP 地址,外层目的 IP 地址为对端 VTEP(VTEP_1)的 IP 地址;外层源 MAC 地址为本地 VTEP 的 MAC 地址,而外层目的 MAC 地址为去往目的 IP 的网络中下一跳设备的 MAC 地址。封装后的报文,根据外层 MAC 和 IP 信息,在 IP 网络中进行传输,直至到达对端 VTEP。 
6. 报文到达 VTEP_1 后,VTEP_1 对报文进行解封装,得到 VM_C 发送的原始报文。同时,VTEP_1 学习 VM_C 的 MAC 地址、VNI 和远端 VTEP 的 IP 地址(IP_3)的对应关系,并记录在本地 MAC 表中。之后,VTEP_1 将解封装后的报文发送给 VM_A。
至此,VM_A 和 VM_C 均已学习到了对方的 MAC 地址。之后,VM_A 和 VM_C 将采用单播方式进行通信。

不同子网 vxlan 通信流程  
如何理解 vxlan 在 openstack 中的使用场景    
如上图所示,VM_A 和 VM_B 分别属于 10.1.10.0/24 网段和 10.1.20.0/24 网段,且分别属于 VNI 5000 和 VNI 6000。VM_A 和 VM_B 对应的三层网关分别是 VTEP_3 上 BDIF 10 和 BDIF20 的 IP 地址(BDIF 接口的功能与 VLANIF 接口类似,是基于 BD 创建的三层逻辑接口,用以实现不同子网 VM 之间或 VXLAN 网络与非 VXLAN 网络之间的通信。)。VTEP_3 上存在到 10.1.10.0/24 网段和 10.1.20.0/24 网段的路由。此时,VM_A 想与 VM_B 进行通信。 
由于是首次进行通信,且 VM_A 和 VM_B 处于不同网段,VM_A 需要先发送 ARP 广播报文请求网关(BDIF 10)的 MAC,获得网关的 MAC 后,VM_A 先将数据报文发送给网关;之后网关也将发送 ARP 广播报文请求 VM_B 的 MAC,获得 VM_B 的 MAC 后,网关再将数据报文发送给 VM_B。以上 MAC 地址学习的过程与同子网互通中 MAC 地址学习的流程一致,不再赘述。现在假设 VM_A 和 VM_B 均已学到网关的 MAC、网关也已经学到 VM_A 和 VM_B 的 MAC,不同子网 VM 互通报文转发流程如下图所示: 
如何理解 vxlan 在 openstack 中的使用场景    
1. VM_A 先将数据报文发送给网关。报文的源 MAC 为 MAC_A,目的 MAC 为网关 BDIF10 的 MAC_10,源 IP 地址为 IP_A,目的 IP 为 IP_B。 
2. VTEP_1 收到数据报文后,识别此报文所属的 VNI(VNI 5000),并根据 MAC 表项对报文进行封装。这里封装的外层源 IP 地址为本地 VTEP 的 IP 地址(IP_1),外层目的 IP 地址为对端 VTEP 的 IP 地址(IP_3);外层源 MAC 地址为本地 VTEP 的 MAC 地址(MAC_1),而外层目的 MAC 地址为去往目的 IP 的网络中下一跳设备的 MAC 地址。 
3. 报文进入 VTEP_3,VTEP_3 对报文进行解封装,得到 VM_A 发送的原始报文。然后,VTEP_3 会对报文做如下处理: 
(1)VTEP_3 发现该报文的目的 MAC 为本机 BDIF 10 接口的 MAC,而目的 IP 地址为 IP_B(10.1.20.1),所以会根据路由表查找到 IP_B 的下一跳。 
(2)发现下一跳为 10.1.20.10,出接口为 BDIF 20。此时 VTEP_3 查询 ARP 表项,并将原始报文的源 MAC 修改为 BDIF 20 接口的 MAC(MAC_20),将目的 MAC 修改为 VM_B 的 MAC(MAC_B)。 
(3)报文到 BDIF20 接口时,识别到需要进入 VXLAN 隧道(VNI 6000),所以根据 MAC 表对报文进行封装。这里封装的外层源 IP 地址为本地 VTEP 的 IP 地址(IP_3),外层目的 IP 地址为对端 VTEP 的 IP 地址(IP_2);外层源 MAC 地址为本地 VTEP 的 MAC 地址(MAC_3),而外层目的 MAC 地址为去往目的 IP 的网络中下一跳设备的 MAC 地址。 
4. 报文到达 VTEP_2 后,VTEP_2 对报文进行解封装,得到内层的数据报文,并将其发送给 VM_B。VM_B 回应 VM_A 的流程与上述过程类似,不再赘述。 
需要说明的是:VXLAN 网络与非 VXLAN 网络之间的互通,也需要借助于三层网关。其实现不同点在于报文在 VXLAN 网络侧会进行封装,而在非 VXLAN 网络侧不需要进行封装。报文从 VXLAN 侧进入网关并解封装后,就按照普通的单播报文发送方式进行转发。

五、vtep 角色部署在 ovs 中

ovs 如何创建 vxlan 隧道  
从前文得知,vtep 部署在接入交换机上时还是会学习到 vm 的 mac 地址,并没有解决表项限制问题,这也是为什么在公有云场景下 vtep 角色都是部署在宿主机的 ovs 中。 
不同于在接入交换机上通过手动的方式建立 vxlan 隧道,openstack 中负责网络的 neutron-server 启动后,会自己建立隧道,下面来介绍 neutron-server 如何自动建立隧道。 
如何理解 vxlan 在 openstack 中的使用场景    
如上图所示,每个宿主机上的 ovs 是由 ovs-aget 创建,当计算节点 1 接入网络中时,他首先会去向 neutron-server 报告自己的网络类型和 local_ip,neutron-server 收到这些资源信息后(neutron 中 network、port、subnet 都称为资源)会进行处理,找到相同网络类型的其他计算节点并为他们之间创建隧道,同时将这个消息同步给其他计算节点上的 ovs-agent。     
如何理解 vxlan 在 openstack 中的使用场景    
每当 neutron 资源发生变化时,或者 ovs 对流量不知该处和处理时,都会像 neutron-server 汇报或等待它的通知,再加上之前的流表,是不是感觉很熟悉?没错,neutron-server 除了接受 api 请求外,他还是一个 sdn 控制器。

与接入交换机实现 vtep 的区别  
1. 使用 ovs 实现的 vtep 接入交换机只会学习经过 vtep 封装后的 mac 地址,学习不到 vm 的 mac 地址,这样解决了 mack 地址表项的问题。 
2. 物理交换机是通过 bd 和 vni 绑定的方法建立不同的隧道,ovs 实现时每一个 vtep 内可以有多个 vsi(virtual switch instance),每一个 vsi 对用一个 vni。 
以上就是 vxlan 在 openstack 中通过物理设备或者 ovs 实现的方式。

关于如何理解 vxlan 在 openstack 中的使用场景就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-25发表,共计7652字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)