概述
ovn-controller是OVN在虚拟机上的agent,北向连接OVN的南向数据库,学习OVN的配置和状态,并使用虚拟机的状态来填充PN表以及Binding表的Chassis列;南向连接openflow控制器ovs-vswitchd,使用ovsdb-server来监控和控制Open vSwtich的配置。
CMS
|
|
+-----------|-----------+
| | |
| OVN/CMS Plugin |
| | |
| | |
| OVN Northbound DB |
| | |
| | |
| ovn-northd |
| | |
+-----------|-----------+
|
|
+-------------------+
| OVN Southbound DB |
+-------------------+
|
|
+------------------+------------------+
| | |
HV 1 | | HV n |
+---------------|---------------+ . +---------------|---------------+
| | | . | | |
| ovn-controller | . | ovn-controller |
| | | | . | | | |
| | | | | | | |
| ovs-vswitchd ovsdb-server | | ovs-vswitchd ovsdb-server |
| | | |
+-------------------------------+ +-------------------------------+
OVN信息流
在OVN信息流中,配置信息是南向北,状态信息是北向南。OVN当前仅仅提供很少的状态消息通知。
- 如果逻辑端口位于南向数据库Port_Binding表的chassis列不为空,那么ovn-northd将设置北向数据库Logical_Switch_Port表的up字段为true,否则为false,通过这个CMS可以判断VM的网络是否运行正常。
- CMS还可以通过OVN提供的反馈来判断其下发的配置是否生效
- 当CMS更新北向数据库的配置时,将同时增加NB_Global表的nb_cfg字段
- 当ovn-northd基于北向数据库的快照来更新南向数据库时,它将拷贝北向数据库NB_Global表的nb_cfg字段到南向数据库SB_Global表
- 在ovn-northd收到南向数据库的确认消息后,它将根据下发的nb_cfg版本来更新北向数据库NB_Global表的sb_cfg字段
- 在每个chassis上工作的ovn-controller将收到来自南向数据库更新后的nb_cfg。chassis将更新其Open vSwitch实例中的物理流表,chassis在收到更新完成确认后,将更新南向数据库中对应Chassis记录的nb_cfg
- ovn-northd监控南向数据库所有Chassis记录的nb_cfg列,持续跟踪所有记录,并设置其中的最小值到北向数据库NB_Global的hv_cfg字段
Chassis安装
部署OVN的所有chassis上都必须配置一个OVN的专用ovs网桥,称作聚合网桥(br-int)。在聚合网桥上的端口包含
- tunnel(隧道)端口用来维持逻辑网络的连通性
- VIF(虚拟网卡)都将关联逻辑网络
- 在网关,物理端口用于实现逻辑网络的连通性
其他端口不应该添加到聚合网桥,尤其是物理端口,应该被添加到独立的ovs网桥上。
聚合网桥受如下配置影响:
- fail-mode=secure
在ovn-contoller启动前,避免两个独立的逻辑网络之间存在数据包 - other-config:disable-in-band=true
抑制聚合网桥的同步控制流,不过这个并不常用,因为OVN使用本地控制器(通过unix域套接字),不过还是建议设置,为了预防同系统中存在远程控制器的情况
逻辑网络
逻辑网络实现与物理网络的相同的概念,但是通过隧道和封装技术实现和物理网络的隔离。这使得逻辑网络可以拥有独立的IP以及重叠的地址空间。
OVN中的逻辑网络概念:
- Logical switches,逻辑版本的以太网交换机
- Logical routers,逻辑版本IP路由器,逻辑交换机和逻辑路由器相连能构建出复杂的网络拓扑结构
- Logical datapaths,逻辑版本的OpenFlow交换机,逻辑交换机和逻辑路由器实现都是基于逻辑OpenFlow交换机
- Logical port,表示同逻辑交换机和逻辑路由器的连接点,逻辑端口的类型有:
- Logical ports 表示VIFs(虚拟网卡)
- Localnet ports 表示逻辑交换机和物理网络的连接点,连接通过在聚合网桥和独立的ovs网桥(需添加物理网卡)间建立ovs patch ports来实现。
- Logical patch ports 表示逻辑交换机和逻辑路由器之间的连接点,成对出现
- Localport ports 表示逻辑交换机和虚拟网卡之间的连接点。这些端口存在于所有chassis(并不绑定到某个上),从它们发出的数据包不会经过tunnel,localport被设计用来执行本地网络传输,一个典型的用例即OpenStack Neutron的metadata实现
虚拟网卡的生命周期
- VIF的生命周期始于CMS管理员的创建,CMS更新其配置,包括vif-id以及VIF的mac地址
- CMS插件向OVN北向数据库Logical_Switch_Port表插入一条VIF记录,并使用上面的vif-id和mac地址信息设置记录的name和mac字段,switch字段指向OVN逻辑交换机的Logical_Switch记录,其他字段使用默认值
- ovn-northd收到OVN北向数据库的更新后,相应的向Logical_Flow表插入一条反映新port的记录,同时还需要在Binding表新增一条记录
- 每台虚拟的ovn-controller在收到Logical_Flow表的更新后,首先添加VIP到OVN聚合网桥上,并且保存vif-id到external_ids : iface-id表明这个是VIF的一个实例,然后OVN南向数据库将更新Binding表对应逻辑端口记录的chassis字段的external_ids : iface-id,最后在ovn-controller更新本地OpenFlow表后,VIF就能够开始处理网络数据包了
- 一些CMS系统包括OpenStack,只有在网络就绪的情况下VM才算启动正常,这边是通过前面OVN信息流中提及的up字段来实现的
- VIF所在的主机给ovn-controller提供了逻辑端口的物理地址,需要更新其Logical_Flow来保证VIF能够处理来自tunnels的数据包
- 当VIF所属的VM被关闭后,VIF将从ovs聚合网桥移除
- 当ovn-controller侦测VIF被删除后,将移除Binding表对应逻辑端口的Chassis字段内容
- 当ovn-controller发现逻辑端口对应的Binding表的Chassis字段为空的时候,这意味着ovn-controller不在知晓逻辑端口的物理地址了,因此所有实例都需要更新其OpenFlow表
- 最后当VIF被CMS管理员删除后,CMS插件将删除Logical_Switch_Port表,ovn-northd将删除南向数据库的Logical_Flow表和Binding表中相应VIF记录
- ovn-controller不需要做什么动作,因为Binding表的记录已经没了
VM内容器网卡的生命周期
OVN通过将OVN_DB数据库写入OpenFlow流表来提供虚拟网络的抽象。多租户下的虚拟网络安全的保证在于ovn-controller是修改ovs流表的唯一入口。ovs的聚合网桥驻留在虚拟服务器,而运行在虚拟服务器VMs里的租户应用是无法修改ovs流表的。
如果ovs的聚合网桥也在容器里面,那么网卡的生命周期参见上面章节
这个章节讨论的是CIF的生命周期,容器跑在VMs里面,ovs聚合网桥驻留在虚拟服务器的情况。这种情况下,即使容器应用能绕过容器,其他租户也不会受到影响,因为运行在VMs的容器不能够修ovs聚合网桥的流表。
一个VM包含多个容器的情况下,OVN需要能够鉴别到达虚拟服务器的聚合网桥的网络数据包来自哪个CIFs,有两种方式:
- 一种方式就是每个CIF分配一个VIF,不过这会导致ovs变慢
- 第二种方式就是为所有CIFs分配一个VIF,通过对网络数据包打tag的方式(VLAN)来区分数据包来自哪个CIFs
- CIF的生命周期始于VM中容器的创建,可以是VM的拥有者创建的,也可以是CMS创建的,无论是谁创建的,都必须知道vif-id,同时还需要选择VM内未被使用的VLAN
- 往Logical_Switch_Port插入一条表示CIF的记录,name字段必须是唯一的,parent_name字段设置为VM的vif-id,并且设置一个能标识CIF网络的tag字段
- ovn-northd收到北向数据库更新后会往南向数据库的Logical_Flow插入一条反映新端口的记录,同时还要往Binding表插入一条新记录,填充chassis相关字段
- 所有虚拟服务器上,如果ovn-conntroller订阅了Binding表变更事件,当有新增记录时,将检测OVN聚合网桥的extenal_ids:iface-id是否同新增记录的vif-id相同,如果相同将更新本地虚拟服务器的流表使得VIF能够处理相应的VLAN tag数据包,最后更新Binding表的chassis字段来反映实际物理地址
- 容器内的应用只有在网络就绪的情况下才能被启动,检测网络是否就绪同样还是使用'OVN信息流'中介绍的up字段来实现
- 当容器关闭的时候,CMS将删除Logical_Switch_Port表的相应记录
- 在收到北向数据库删除事件后,ovn-northd将删除南向数据库Logical_Flow表和Binding表的相应记录
- ovn-controller将更新本地流表
数据包的生命周期
本段落主要介绍下几种数据和元数据字段,总结如下:
- tunnel key
当OVN使用Geneve或其他隧道封装数据包的时候,需要附加隧道关键字到数据包的扩展字段 - logical datapath field
表示数据包处理的逻辑数据路径,存放于OpenFlow的metadata字段 - logical input port field
表示数据包进入逻辑数据路径的入口,存放于OVS寄存器14,Geneve和STT隧道将这个字段作为隧道关键字的一部分,VXLAN隧道并不现实的携带logical input port,因为OVN仅仅使用VXLAN同VXLAN网关通信,因此logical input port字段被看做ovn逻辑管道的入口 - logical output port field
表示数据包离开逻辑数据路径的出口,在逻辑输入通道开始时被设置成0,存放于OVS寄存器15,Geneve和STT隧道将这个字段作为隧道关键字的一部分,VXLAN隧道并不携带这个字段,因此当虚拟服务器收到来自VXLAN隧道的数据包,需要重新提交到表8来判断输出端口,如果数据包来到了表32,将重新提交到表33检测MLF_RCV_FROM_VXLAN标志判断是否进行本地交付,来自VXLAN隧道的数据包都会设置此标志 - 逻辑端口的conntrack zone字段
此字段用于跟踪逻辑端口的连接,该值为本地局部变量,仅存在于当前chassis上,在chassis之间没有意义,在逻辑输入通道开始处被初始化为0,并存放于OVS寄存器13 - 逻辑路由的conntrack zone字段
此字段用于跟踪逻辑路由的连接,该值为本地局部变量,仅存在于当前chassis上,在chassis之间没有意义,在逻辑输入通道开始处被初始化为0,zone字段如果是DNATing信息,则存放于OVS寄存器11,是SNATing信息,则存放于OVS寄存器12 - logical flow flags
此字段保持流表之间的上下文信息,用于后续流表的匹配,该值为本地局部变量,仅存在于当前chassis上,在chassis之间没有意义,存放于OVS寄存器10 - VLAN ID
VLAN ID用于VM嵌套容器的网络
初始时位于ingress(输入)虚拟服务器上的VM或容器发送一个数据包到OVN聚合网桥上的端口,然后
- 流表0处理physical-to-logical的转换,匹配数据包的进入端口,然后设置数据包的逻辑源数据中用于标识数据包传输的逻辑数据路径字段以及标识数据包入口的逻辑输入端口字段,最后数据包被提交到流表8进入逻辑入口通道
如果数据包来自VM内的嵌套容器,则处理方式有稍许不同。容器的区分可以通过VLAN ID,所以physical-to-logical的转换需要额外步骤,即匹配VLAN ID然后去除数据包的VLAN首部,其余步骤同其他数据包
流表0同样处理来自其他chassis的数据包,通过进入端口将来自隧道的数据包同其他数据包区别开来。一旦数据包进入了OVN通道,流表动作通过逻辑数据路径和逻辑进入端口元数据来标注这些数据包,并设置逻辑输出端口字段。 - 流表8到31实现基于南向数据库的Logical_Flow表的逻辑输入通道,这些表表示的是逻辑上的概念,例如逻辑端口已经逻辑数据路径,ovn-controller很重要的一个工作就是将这些逻辑上的概念翻译成流表(Logical_Flow表0-23变成流表的8-31)
每个逻辑流表映射一条或多条OpenFlow流表,但实际上通常一个数据包只会匹配其中一条,虽然也会出现匹配多条的情况(这不是故障,因为它们的流表动作都是一样的)。ovn-controller使用逻辑流表UUID的前32位作为OpenFlow流表的cookie值(这个值没必要唯一,因为逻辑流表的UUID也不一定是唯一的)
一些逻辑流表映射成ovs的'联合匹配'扩展。动作为conjunction的流表的cookie值为0,因为它们能够对应多条逻辑流表,对于联合匹配的OpenFlow的流表吗,它们使用的是conj_id
如果一些逻辑流表在虚拟服务器上用不到的话,虚拟服务器的OpenFlow流表就不需要反映这些逻辑流表。例如如果一个VIF驻留的逻辑交换机没有网络可到达虚拟服务器,那么虚拟服务器的流表就不需要反映交换机的逻辑流表。
大多数OVN动作在OpenFlow已经有明显的实现了,例如next对应OpenFlow的实现就是resubmit;set_field详细阐述如下:- output
对应的OpenFlow实现是重新提交数据包到表32。如果通道执行不止一个输出动作,那么每个动作都要重新提交数据包到表32,可以利用这种方式可以将数据包的拷贝发送到不同端口 - get_arp(P, A)
- get_nd(P, A)
对应的OpenFlow实现是保存参数到OpenFlow字段,然后重新提交数据包到表66,一张由南向数据库的MAC_Binding表生成的流表。如果表66存在匹配项,那么相应的动作就是保存对应目的地址字段的MAC - put_arp(P, A, E)
- put_nd(P, A, E)
对应的OpenFlow实现是保存参数到OpenFlow字段,然后输出数据包到ovn-controller,并更新MAC_Binding表
- output
- 流表32到47实现逻辑输入通道的output动作,表32处理到远端虚拟服务器的数据包,表33处理到本地虚拟服务器的数据包,表34检测是否存在输入和输出端口相同的数据包,如果存在则丢弃
logical patch端口比较特殊,它并没有物理地址,因此对于输出端口是本地的情况,to do - 流表40到63实现基于南向数据库的Logical_Flow表的逻辑输出通道,输出通道负责对数据包交付前的最后验证,最终执行output动作,ovn-controller对应的实现就是重新提交数据包到表64
- 当MLF_ALLOW_LOOPBACK被设置的时候,流表64将绕过OpenFlow环回。逻辑环回在表34中被处理,但是OpenFlow默认阻止到OpenFlow输入端口的环回。因此当MLF_ALLOW_LOOPBACK被设置时,流表64保存OpenFlow的输入端口,然后将其设置为0,然后重新提交数据包到表65实现logical-to-physical的转换,然后恢复OpenFlow输入端口。如果MLF_ALLOW_LOOPBACK未被设置,那么表64仅仅简单的将数据包重新提交到表65
- 流表65执行logical-to-physical的转换,是流表0的逆向过程,匹配数据包的逻辑输出端口,然后将输出包输出到OVN聚合网桥上表示逻辑端口的物理端口,如果数据包来自VM内嵌套的容器,那么在发送数据包前还需要加上VLAN头部
逻辑路由以及逻辑Patch端口
逻辑路由和逻辑patch端口并没有相应的物理地址