OVN架构图如下所示:

ovn-architecture 摘要-LMLPHP

1、OVN Southbound Database由以下三种数据构成:

  • Physical Network(PN)table用于确定如何到达hypervisor以及其他node
  • Logical Network(LN)table用"logical datapath flows"描述的逻辑网络
  • Binding table用于将逻辑网络组件的位置和物理网络相关联

其中hypervisor填充PN和Port_Binding tables,ovn-northd填充LN tables

2、网络的配置信息从CMS到OVS的流动及反馈过程如下所示:

  • 当CMS更新northbound database中的configuration时,它会对NB_Global table中的nb_cfg加1
  • 当ovn-northd根据northbound database更新southbound database时,它会将NB_Global中的nb_cfg拷贝到southbound database中的SB_Global
  • 当ovn-northd接收到来自southbound database已经将变更提交的确认信息之后,它会更新NB_Global中的sb_cfg使其和之前更新过的nb_cfg一致(这样,没有连接到southbound database的CMS也能知道southbound database已经及时更新了)
  • 每个chassis上的ovn-controller发现southbound database中的nb_cfg更新了,它就会更新其所在chassis的OVS实例的physical flow。当它收到来自OVS physical flow已更新的消息,它就会更新在southbound database中其对应chassis记录的nb_cfg
  • ovn-northd会监视southbound database中所有Chassis记录中的nb_cfg,它会追踪所有这些记录中的最小值,并且会将它写入NB_Global table中的hv_cfg。从而CMS就能确认什么时候所有的hypervisor都已经和northbound configuration同步了。

3、每一个chassis中都必须配置一个OVN专用的OVS bridge,叫做integration bridge。该bridge包含以下端口:

  • tunnel ports用于连接逻辑网络的连通性。ovn-controller负责添加,更新和删除该端口
  • 所有连接到逻辑网络的VIF
  • 在gateway中,还有用于逻辑网络连通性的physical port

4、Logical ports用来表示进出logical switches和logical routers的连接点。有以下几种logical ports:

  • 用来表示VIF的Logical ports
  • Local ports用于logical switch和physical network的连接。它通常是一个OVS patch ports用来连接integration bridge和与underlay physical ports相连的separate OVS bridge
  • Logical patch ports表示logical switch和logical routers的连接点,在有些情况下也用于连接两个logical routers。一般都有一对logical patch ports,两端各一个
  • Localport ports用于logical switches和VIF的本地连接。该类型的端口每一个chassis中都有,所有来自它们的流量都不会通过隧道。localport一般只生成发往本地的流量,通常就是用于回复它所收到的请求。

5、VIF就是和虚拟机或者直接在hypervisor上运行的容器相绑定的virtual network interface。它的整个生命周期如下:

  • CMS administrator创建一个新的VIF并且将它加入一个switch中。CMS会更新它的配置,包括关联一个唯一的vif-id以及mac地址
  • CMS plugin通过在OVN Northbound database的Logical_Switch_Port table中加入新的一行表示创建一个新的VIF。该行中的name为vif-id,mac为mac,switch指向OVN logical switch的Logical_Switch记录,其他各列都进行适当的初始化
  • ovn-northd获取了OVN Northbound database中的更新之后,就会对OVN Southbound database进行相应的更新,通过在OVN Southbound database的Logical_Flow table中加入一行来表示新的端口。以及增加一条flow用于识别发往该端口的mac地址的包,并将包传送给它。还需要更新传输broadcast和multicast的flow,让它们包含该新端口。同时还需要在Binding table中创建一条记录,填充其中除了chassis的各列
  • 在每个hypervisor中,ovn-controller获取了上一步中Logical_Flow table所做的更新。不过,只要拥有该VIF的虚拟机还是关机状态,ovn-controller就并不能做什么,比如它不能向该VIF发送或接收包,因为该VIF事实上还并不存在
  • 最终,用户启动了拥有该VIF的虚拟机。而该虚拟机所在hypervisor的integration会将VIF添加到OVN的integration bridge上,并且将vif-id存储到external_ids:iface-id用来表示该interface是新的VIF的实例(这些都不是OVN新加的,这些都是原本支持OVS的hypervisor已有的)
  • 在虚拟机所处的hypervisor中,ovn-controller会注意到新的interface的external_ids:iface-id。接着它就会更新OVN Southbound DB中该external_ids:iface-id对应的logical port在Binding table中所在chassis列,让它指向该hypervisor。接着ovn-controller会更新local hypervisor的OpenFlow table,从而让进出该VIF的包能被恰当的处理
  • 有的CMS系统,包括OpenStack,都会在网络已经准备好的情况下才完全启动虚拟机。为了支持该特性,ovn-northd会检测到Binding table中对应行chassis的变化,转而向上更新OVN Northbound database中的Logical_Switch_Port table中的up列,用于表示VIF已经启动。如果CMS利用了该特性,那么就可以让虚拟机开始启动了
  • 除了VIF所在的每一个hypervisor上的ovn-controller都监听到了Binding table中有一行被完全填满了。它为ovn-controller提供了logical port的物理位置,所以每个实例都更新了它的switch的OpenFlow tables(基于OVN DB Logical_Flow table中的logical datapath flows),从而让发往或者来自该VIF的包都能通过隧道进行处理
  • 最终,用户关闭了拥有该VIF的虚拟机,该虚拟机所在的hypervisor上的VIF就会从OVN integration bridge上删除
  • 虚拟机所在的hypervisor上的ovn-controller会监听到VIF已经被删除了。因此,它会删除Binding table中该logical port的chassis列
  • 接着每一个hypervisor上的ovn-controller都会监听到该Binding table中该logical port对应行的chassis变为空了。这意味着ovn-controller不再知道该logical port的物理地址了,所以每个实例都会更新它的OpenFlow table用来反应这一结果
  • 最终,当VIF完全不再需要时,administrator就会删除它,CMS也会更新它的配置
  • CMS plugin删除OVN Northbound database中的Logical_Switch_Port table中的对应行来移除VIF
  • ovn-northd监听到了OVN Northbound database的更新,接着它就会对OVN Southbound database进行相应的更新,通过移除或更新Southbound database中的Logical_Flow table和Binding table中的对应行
  • 每一个hypervisor的ovn-controller监听到了ovn-northd在上一步中对Logical_Flow table所做的更新。ovn-controller会相应地对OpenFlow table进行更新,虽然也许并没有太多工作需要做,因为VIF在上一步从Binding table中移除之后,已经不能到达了

6、一开始,ingress hypervisor上的虚拟机或者容器会将包传输给与OVN integration bridge相连的端口,接着:

  • OpenFlow table 0用于physical-to-logical translation。它匹配包的ingress port。它的action是用logical metadata注释packet,设置logical datapath域来标识packet流经的logical datapath,logical input port标识ingress port。之后再重新提交到table 8进入logical ingress pipeline。Table 0同样处理来自其他chassis的包,它通过ingress port来进行区分,因为它们是来自tunnel port的。当包进入OVN pipeline,action同样是用logical datapath和logical ingress port metadata进行注释,另外actions还包括logical output field。这三项信息都是从tunnel encapsulation metadata中获取的。之后又被重新提交到table 33从而进入logical egress pipelien
  • OpenFlow table 8到31用于执行OVN Southbound database中Logical_Flow table的logical ingress pipeline。这些table都完全是用一些逻辑概念,例如logical ports和logical datapaths来表达的。ovn-controller很重要的一部分工作就是将它们转换为对应的OpenFlow(特别地,它还会对table number进行转化,例如Logical_Flow table 0到23会变成OpenFlow table 8到31)。
    • 每一个logical flow对应一个或多个OpenFlow flow。一个包通常会匹配其中的一个,但是也有可能会和这些flow中的多个相匹配(这并不会造成太大的问题,因为这些flow的action都是相同的)。ovn-controller使用logical flow的UUID的前32位作为OpenFlow flow的cookie(这并不一定是全局唯一的)。
    • 还有些logical flow会映射到OVS的"conjunctive match"的扩展
    • 有的logical flow可能不会出现在给定的hypervisor的OpenFlow table中,如果它们不能被该hypervisor所用的话。例如,如果没有一个logical switch的VIF位于给定的hypervisor中,那么该hypervisor就不能访问该logical switch,因此对应的logical flow就不会出现在该hypervisor中。
    • 大多数OVN actions都在OpenFlow中有对应的实现(包括OVS扩展),比如next由resubmit实现,field = constant由set_field实现。
  • OpenFlow table 32到47用于在logical ingress pipeline中实现output action。其中table 32处理发往remote hypervisor的包,table 33处理发往local hypervisor的包,table 34用于确认logical ingress和egress port相同的包是否应该被丢弃。Logical patch port是一个特例。Logical patch port没有物理位置,而是会在每一个hypervisor中。因此,flow table 33,不仅用于输出到local hypervisor的端口,还用于输出到单播的logical patch port。每个table 32中的flow用于匹配一个logical output port用于单播或多播,甚至位于远程的hypervisor。每个flow的actions都是实现将包传送到匹配的端口。对于位于远程主机上的单播端口,actions通常是将tunnel key设置为正确值,之后再通过tunnel port将包送往正确的hypervisor。Table 34最后进行匹配,如果logical input和logical output都相同并且MLF_ALLOW_LOOPBACK没有被设置,那么该包就被丢弃,否则将包提交被table 40
  • OpenFlow tables 40到63根据OVN Southbound database中的Logical_Flow table执行logical egress pipeline。egress pipeline用于在包发送前进行最后的检查。最后,它可能会执行output action,被提交给table 64。而没有执行output的包就被丢弃了。egress pipeline不能改变logical output port或者造成tunneling
  • Table 64用于在MLF_ALLOW_LOOPBACK设置的时候绕过OpenFlow loopback。Logical loopback由table 34处理,但是OpenFlow默认禁止ingress port的loopback。因此,当MLF_ALLOW_LOOPBACK设置时,OpenFlow table 64会保存OpenFlow ingress port,将它设置为零,再提交给table 65进行logical-to-physical的转换,接着再恢复OpenFlow ingress port,从而有效避免了OpenFlow loopback prevents。当MLF_ALLOW_LOOPBACK未被设置时,table 64直接传给table 65
  • OpenFlow table 65用于logical-to-physical转换,和table 0的作用刚好相反。它和包的logical egress port相匹配。它的action是输出到integration bridge中代表该logical port的端口。

7、Logical Routers and Logical Patch Ports

现在来假设有一个包从一台虚拟机或容器发往位于另一个子网内的虚拟机或容器。这个包会如上文所述,流经table 0到table 65,其中logical datapath表示与发送者相连的logical switch。在table 32,这个包会使用table 32的fallback flow重新发送到本地的hypervisor。在这种情况下,table 0到table 65的所有处理都是在发送者所在的hypervisor进行的。当包到达table 65时,logical egress port是一个logical patch port。在OVS 2.7及以后的版本中,该包会被克隆,并且直接提交到ingress pipeline的第一个OpenFlow flow table中,将logical ingress port设置为peer logical patch port,并且使用peer logical patch port的logical datapath(代表了logical router)。于是这个包重新进入了ingress pipeline,从而再次流经table 8到65,这次的logical datapath代表的是logical router。处理过程和上文相同。当包再次到达table 65时,logical egress port还是一个logical patch port。同样,logical patch port会将包重新提交到OpenFlow table 8到65,这次使用的logical datapath代表的是目的虚拟机或容器所在的logical switch。接着包第三次,也是最后一次流经table 8到65。如果目标虚拟机或容器位于remote hypervisor,那么table 32将会通过tunnel port将包从发送者的hypervisor发送到remote hypervisor。最终,table 65会直接将包发给目的虚拟机或容器。

8、Gateway Routers

gatewat router是一种与物理位置绑定的logical switch。如果logical egress port是l3gateway,则代表了与一个gateway router相连接,那么包就会和table 32中的一条flow相匹配,然后通过一个tunnel port将包发往gateway router所在的chassis。这一过程和table 32对于VIF的操作是一样的。distributed router和gateway router需要通过另一个logical switch相连,有时将其称之为join logical switch。另外,gateway router还和另一个logical switch相连,该logical switch包含一个localnet port用于连接physical network

9、Distributed Gateway Ports

Distributed Gateway Ports是一种logical router patch ports,它将distributed logical routers和有着localnet ports的logical switch相连。设计distributed gateway ports的主要目的是允许尽可能多的流量在虚拟机或容器所在的hypervisor进行本地处理。不管在什么时候,如果有可能的话,所有虚拟机或容器发往外部世界的流量都应该在本地处理完成,并且通过hypervisor的localnet port发往物理网络。同样,任何从外部世界发往虚拟机或容器的网络都应该直接通过物理网络到达对应的hypervisor,并且通过localnet port进入integration bridge。

为了实现上文中描述的内容,distributed gateway ports必须是位于每一个hypervisor中的logical patch ports,而不是和特定的chassis相绑定的l3gateway。并且与distributed gateway ports相关的flow必须与物理位置绑定。

05-11 09:34