数据驱动的网络
从数据驱动的角度来看网络,会发现一张现实中的网络存在着各种数据。设计和管理一张网络,主要是设计数据,存储数据,管理数据和分析数据。网络数据的规模、复杂度和变化速度,这3方面决定了数据处理的难度。对照下图的SDN网络结构,网络数据按照用途可以分成下面几类。
- 设备元数据。例如图中每台虚拟交换机的的基本数据:设备型号,设备软件版本和管理IP地址等。
- 拓扑数据,例如图中一台虚拟机交换机有几个端口,每个端口的类型和速率是多少,每个端口是2层还是3层的,对端的端口数据,端口和端口之间的线路类型。控制器和虚拟交换机之间的连接方式。
- 转发数据,例如图中一台虚拟机交换机内部的转发表项,指导报文在交换机内部如何转发。也包括控制面各种网络协议和配置接口生成的转发路由数据。
- 测量数据,例如从图中一台虚拟机交换机上每个端口上采集的各类流量数据,这些数据还可以聚合,用于分析各种业务的运行流量情况。
一个SDN VPC控制器,通常要管理成千上万个虚拟交换机节点,其作用是存储、计算和传输网络数据。其中转发数据是最重要的一类数据,直接决定了报文在网络中的转发行为。本文主要分析SDN控制器将转发数据传输到虚拟机交换机的一些方法,希望从这个角度能介绍一下SDN网络遇到的主要问题,以及如何设计一个SDN网络控制器。
为了简要描述,下文中的交换机,路由器和virtual vswitch偶尔会交替使用,他们都代表了具有路由功能的虚拟网络转发设备。
VPC 网络转发数据
云网络内部根据数据面功能也分成多块,本文主要介绍VPC网络。下图是一个VPC内的转发数据。分别从控制器和虚拟交换机的视角来看,控制器内的转发数据,和虚拟交换机内的转发数据并不相同。控制器上是整个VPC1的转发数据,而每个虚拟交换机内是本节点网卡相关的VPC转发数据。
从控制器的视角看VPC1的转发数据:VPC 1内有2个子网,子网1内有网卡1/2,子网2内有网卡3/4。
- VPC 1内有3张路由表:系统路由表,路由表1/2。有3个安全组:安全组1/2/3。
- 子网1关联路由表1,子网2关联路由表2。
- 网卡1/2关联安全组1,网卡3关联安全组2,网卡4关联安全组3。
- 网卡1(eni1)是分配给虚拟机1,mac1,ip1,连接在虚拟交换机1的port1。网卡2(eni2)是分配给虚拟机2,mac2,ip2,连接在虚拟交换机1的port1。网卡3(eni3)是分配给虚拟机3,mac3,ip3,连接在虚拟交换机3的port1。网卡4(eni4)是分配给虚拟机4,mac4,ip4,连接在虚拟交换机4的port2。
从虚拟交换机1的视角看VPC1内的转发数据:
- 本节点有一张属于vpc1的网卡1,mac1,ip1,连接在port1。
- vpc1内的其他网卡有,网卡2/3/4。
- 网卡1关联着安全组1,路由表1。访问vpc1内的网卡2/3/4,需要查询系统路由表。并且和每个虚拟交换机之间建立点对点的隧道。
根据上面的例子,可以罗列一下VPC网转发数据的几个特点:
- 转发数据规模大。大的云厂商一个最大的VPC可能有几十万台甚至更多的虚拟机,导致一张VPC网络内的转发数据规模很大。上面的例子只介绍了一个VPC 1,正常一个地域会存在很多个租户VPC。Google的数据是如果一个控制器管理着40K虚拟机的网络,控制器要写入487M条flow,消耗10GB的内存。
- 转发数据关系复杂。转发数据包括路由、安全规则和隧道数据,转发数据分为位置表、路由、安全组等类型,这些数据之间有复杂的绑定关系。控制面和数据面处理的转发数据格式不同,每个虚拟交换机需要的转发数据内容也不相同。
- 转发数据变化快。云网络支持虚拟机快速动态创建和迁移,网络变更频繁,导致转发数据变化速度很快。控制器需要在短时间内计算出变更后的结果,并快速下发给数据面。
- 转发数据是分布式的,一张VPC路由表的转发数据分布在各个转发节点上,需要确保各个节点上的转发数据是协调一致的。控制面和数据面之间的数据传输需要经过中间的物理网络,转发数据的传输可能会丢失或者中断。
- 数据面的转发数据,具有网络自身的特点,转发数据用于报文的转发查找,所以一般以表的形式存储,例如路由表,安全规则表等。对于表的更新,也是以增量更新的形式,不然每次都是对整表进行,会中断网络传输。数据面的报文依赖于转发数据的正确性,如果数据有错误会导致网络中断。
一个SDN VPC控制器,管理着成千上万个虚拟交换机,以上面的例子为例,控制器需要将VPC1内的转发数据,转换成虚拟交换机期望的数据,并正确的传输到众多虚拟交换机上。下面介绍控制器将转发数据传输到虚拟交换机的3种方式,以及这3种方式下的数据一致性。
传输转发数据
分布式系统,是通过分布式算法让一群机器对外像一台机器在工作。云网络的特点,是通过分布式系统和网络技术让一群虚拟交换机逻辑上像一台虚拟交换机在工作。
数据模型和格式
数据模型和格式,就是控制器将转发数据以什么格式发送给虚拟交换机,例如json/xml/protobuff。
虚拟交换机的实现大多参考开源的OpenvSwitch,OpenvSwitch以Openflow协议和控制面交互转发数据,以OVSDB和控制面交互管理信息。转发数据以Openflow Rule格式表示,Openflow Rule存储在Openflow Table中。控制面通过Openflow协议读写Openflow Table,接收数据面上送的协议报文。Openflow协议支持数据面将一些流表更新事件和端口事件上报给控制面,类似于中断通知。
如果控制面直接以Openflow协议传输转发数据,Openflow Rule的表达是偏向转发面的,没法直接表示子网和路由表的关联关系,以及网卡和安全组之间的关联关系。另外为了表示控制面的一条路由,需要在rule中指定匹配条件和vxlan tunnel的信息。当有多条路由数据指向同一条vxlan tunnel时,会导致重复的vxlan tunnel数据。例如下面,如果再新增一条路由,nw_dst=192.168.1.30,tun_dst=10.33.0.12,tun_id=1,那么这条tunnel数据会在转发面重复存在。
ovs-ofctl add-flow br-tun "nw_dst=192.168.1.11 actions=set_field:10.33.0.12->tun_dst, set_field:1->tun_id, output:1
ovs-ofctl add-flow br-tun "nw_dst=192.168.1.12 actions=set_field:10.33.0.13->tun_dst, set_field:1->tun_id, output:1
ovs-ofctl add-flow br-tun "nw_dst=192.168.1.20 actions=set_field:10.44.0.24->tun_dst, set_field:1->tun_id, output:1
解决的办法是,进一步对Open vSwitch的Table做拆分,独立复用的数据。另外一些解决方案是控制器不直接对接虚拟交换机,不再直接发送原始的数据面转发规则,而是引入一层proxy。控制器和proxy之间传输自定义格式的转发数据,使用json或者protobuff,由proxy再翻译成Openflow写入虚拟交换机。
自定义的数据格式,对比Openflow表达上偏向控制器,可以减少控制器和虚拟交换机之间传输时的大量重复数据,也可以方便的自定义扩展。如下所示,如果使用自定义格式,只需要指定列出虚拟机和宿主机的IP地址列表,那么虚拟交换机可以将此翻译成上面的Openflow Rule,不存在重复的vxlan tunnel。
hosts = vpcHosts {
vpcID = vpcxxxx,
vni = 1,
subnetID = subnetxxxx,
{
vmIP = "192.168.1.10/24",
hostIP = "10.22.0.16"
},
{
vmIP = "192.168.1.11/24",
hostIP = "10.33.0.12"
},
{
vmIP = "192.168.1.12/24"
hostIP = "10.33.0.13"
},
{
vmIP = "192.168.1.20/24"
hostIP = "10.44.0.24"
},
}
数据流
数据流是指控制器通过什么方式将转发数据传输给虚拟交换机。目前有以下3种方式:
- via database,数据发送方将数据写入数据库,数据接收方从数据库读取数据再消费。双方使用数据库进行数据的传输。
- via rpc,数据发送方和接收方之间建立一对一的RPC连接,使用RPC传输数据。
- via asynchronous message system,数据接收方订阅消息队列对应的topic,数据发送方先将数据发送给消息队列的对应topic,消息队列将数据推送给数据接收方。
我们来具体分析使用上述3种方式实现控制面和数据面的数据同步。
via database
使用数据库来传输数据,需要清晰的定义数据在数据库中的存储的格式。一般是控制器来写数据库,虚拟交换机Agent来读数据库。数据库的数据,表示的是转发数据最新的状态,没有数据的历史状态。如果控制器出现错误,导致数据被篡改,一般要通过同时留存日志的方式,追溯出篡改的时间点和原始数据。同时要注意数据库的事务,防止出现脏数据。
控制器需要和虚拟交换机Agent定义清楚数据库转发数据schema的版本,以及双方软件的版本,不然可能导致转发面读取数据库出错。一般这种情况是控制器在数据库中添加了新字段,但是虚拟交换机Agent的版本还是旧的,此时无法提取新的字段,导致出现错误。
数据库中的数据一般是持久化的,只要数据的写入者不主动删除数据,转发数据就不会丢失,这样即使数据面节点重启了,还可以从数据库中恢复出转发面的状态。
使用数据库来传输数据,控制器和数据面是异步的,控制器写入新数据到数据库之后,数据库无法通知数据面及时来读取数据,导致新的转发规则不能及时生效。但是现在出现了一些数据库具备类似消息队列的消息通知功能,数据面可以订阅数据库的某些消息来实现异步的通知,例如redis/etcd。但是使用数据库模式,由于一般数据面Agent数目特别多,所以数据库的读性能以及并发连接数会是这个方案的一个瓶颈。
另外一种方式,是虚拟机交换机自带数据库,例如Open vSwitch自带Open Flow Table,作用类似数据库,报文转发查找时会使用Table。控制面直接写Open Flow Table,这种方式的好处在于转发规则可以长久化,并且能立即生效,但是弊端在上一节已经提到,控制器需要关心Open Flow 规则的格式,维护的负担过重,理解起来也比较困难,数据传输效率也不高。OVN控制器使用的就是这种方式。
via rpc
基于RPC的方式,控制器和每个数据面节点建立一对一的RPC连接。RPC通信模式下,一般有个服务端和客户端,控制器和数据面都可以作为服务端。一般在数据面节点上会部署一个agent,用于和控制器之间建立RPC连接,由agent接收数据之后再写入虚拟交换机中。
使用RPC,控制器和数据面agent之间的通信是同步的,控制器可以实时推送数据到数据面agent并确认数据面已经接收到数据。RPC的实现较为方便,只要定义好服务的接口和通信协议,控制器和数据面之间容易实现解耦,方便双方独立升级维护。
RPC一般是有通信方向的,例如客户端主动访问服务器端的服务,此时如果服务器想主动推送数据给客户端,就很麻烦。grpc支持stream模式,但是也需要客户端主动连接上来之后,以responce的形式再推送数据给客户端,导致此时控制器无法基于具体的接口提供服务。
使用RPC的方式,Agent没法很好的持久化保存转发数据,因为控制器和数据面agent是通过网络通信的,所以在一些数据消息丢失的情况下,Agent的状态比较难排查。而且数据面agent重启之后,为了快速恢复转发状态,必须做一次全量的数据同步。如果大量的agent在同一时刻重启会对控制器会造成服务攻击。解决办法是可以在本地存储对应的消息。但是这个消息需要有分布式算法来保证一致性。
agent需要负责转发面Table中的数据正确性,必须确保所有数据正确的写入转发面的Table中。如果出现异常将导致网络流量的中断这对agent的设计要求比较高,尽量简单和稳定,最好做到无状态的。
via asynchronous message system
控制器和数据面节点之间,可以使用消息队列作为转发数据的传输通道。消息队列有生产者和消费者的角色。控制器作为生产者,往一个topic写数据,数据面节点上的agent订阅该topic,消息队列会负责往所有订阅该topic的数据面节点推送数据。控制器需要将转发数据的类型划分成不同的topic,并按照topic去发送数据。
消息队列具备一对一和一对多通信的能力,容易实现控制器和数据面之间的解耦。控制器只需要将转发数据写入消息队列后就不用管了,消息队列自己会完成数据的传输工作。控制器可以方便的实现将同一份转发数据,多播给多个数据面节点。
有些消息队列支持消息的按序发送,但是转发数据的顺序只能在一个topic上保证,多个topic之间无法保证。消息队列还支持消息的重传。有些消息队列支持消息的持久化保存,但是不能和数据库比较,只是实现了有限的持久化功能。消息队列支持消息的削峰功能,当转发数据太多时,可以临时缓存下来,避免系统过载。
消息队列支持异步通信,消息队列主动将消息或者事件及时的推送给数据转发面。但是有一个问题,控制器将转发数据写入消息队列之后,无法知道什么时候数据面收到了数据。解决办法之一是数据面agent可以注册一个topic,作为生产者将结果作为消息写入消息队列,控制器作为消费者来读取结果。
消息总线是一种增量通信的机制,也就是说新转发数据,总是以新消息的形式被追加到系统的消息流中,消息流也可以解读为事件流。
目前VPC控制器一般以VPC和ENI作为topic,这样每个虚拟交换机只需要订阅自己关心的VPC topic,每次这个VPC的数据有更新,它都会收到新的消息,而不用关心别的VPC数据是否有更新,这样可以减少重复数据的传输,减轻虚拟交换机的负担。
via log
基于log的方式,结合了基于数据库的数据可持久化功能,和rpc机制的实现。其实现方式可以抽象为,控制器将数据以递增的方式追加log文件中,并附带编号和数据的动作指令,例如是添加还是删除一条数据。控制器负责将log文件同步到所有的数据面节点,并记录每个数据面节点当前同步的位置,根据这个位置决定下一次同步的数据。如果数据面节点崩溃了,数据面节点可以使用本地快照恢复状态,再根据log文件更新到最新状态,并且再通过RPC和控制器同步自己最新数据的位置。控制器再同步最新的数据到数据面节点。所以控制器还需要定期和数据面节点sync本地快照。
转发数据一致性
前面介绍了转发数据的传输格式和传输方式,不同传输方式下实现数据一致性的方式和难度不一样。
基于数据库的实现方式,因为控制器将转发数据直接写入了数据库中,所以数据转发面节点可以直接读取同样最新的数据,这个数据一致性是由数据库来保证的。关系型数据库可以实现强一致性。这个场景下需要解决的问题主要是,控制器需要及时通知数据面节点来读取数据,另外就是数据库要承担所有节点的读写请求,需要评估其性能。OVN控制器,使用基于数据库的方式。
基于RPC的方式,控制器和数据面节点之间的状态同步难以保证。需要依赖一些机制来实现数据的一致性。这个时候可以使用分布式共识算法,来保障控制器和数据面节点的状态一致性,如下图所示。控制器作为leader,agent作为follower。控制器控制保存每个数据面节点的同步状态,控制数据面节点的同步,这个有点类似于via log的方式,每次同步的数据都有对应的编号。另外一种较为简单的方式是使用版本号,但是这一般用于控制器和数据面节点之间同步全量数据。
基于消息队列的方式,控制器和数据面节点之间的状态同步依赖于消息队列的消息持久化和重传机制。这种事件驱动机制下,数据节点接收到的是增量数据,控制器无法直接知道数据面节点是否接收到数据。所以还依赖额外的机制来确保数据面节点和控制器之间数据的最终一致性,例如建立旁路的对账检测机制,定期检查每个数据面节点的转发数据是否和控制器的数据一致。为了做到数据面节点重启快速恢复,数据面节点必须保存全量的转发数据,否则重启之后就只能接收新数据了。
解决方案探讨
一个解决方案,是基于数据库的改进模式,直接将一个虚拟交换机当成一个转发设备,在控制器中对应每个转发设备都有一个映射。控制器根据转发数据模型和网络事件,分别计算出每个转发设备当前最新状态,以及与历史状态比较的变更,然后再将变更增量写入转发设备的转发表中。如果类比传统路由器,控制器中的转发设备数据可以类比CPU中的RIB和ARP Cache,而虚拟软件交换机中的转发设备数据,可以类比硬件交换芯片的转发表项,在CPU中存在单独的进程和交换芯片SDK来处理RIB和硬件交换芯片转发表之间的同步。交换芯片SDK提供读写交换芯片的接口和通道,将CPU的读写格式翻译成硬件交换芯片支持的格式,在各家交换芯片SDK之上通常还会有一个SDK适配层用来屏蔽各家SDK的差异。在SDN网络中,Openflow协议起到的作用和交换芯片SDK类似,各种软件交换机需要自己对Openflow协议做兼容。P4 Runtime是通过RPC的方式直接读写虚拟软件交换机的转发表,作用类似,区别在于P4的重点是想随时可以改变交换机的解析和转发行为,真正做到自定义交换机。传输通道和协议有了,控制器中的转发设备数据有了,那么现在需要的就是在控制器这一侧为每个转发设备起一个单独的线程,通过传输通道和协议将转发数据写入虚拟交换机的转发表中。为了避免控制器维护过多连接,可以引入proxy。
在控制器中为每个虚拟交换机创建单独的实例,该实例使用传输通道和传输协议和虚拟软件交换机通信。虚拟交换机会发送一些网络事件给控制器实例,例如虚拟交换机连接、添加一个虚拟机端口等。控制器综合这些虚拟交换机上报的事件,以及来自上层的网络配置信息,计算出每个虚拟交换机的当前转发数据,然后和历史数据比较得出差异数据。这个差异数据格式是控制器能够识别的,再通过传输通道以及Openflow等传输协议转换成虚拟机交换机支持的格式,写入到虚拟交换机的转发表中。由控制器实例来确认每次传输是否成功,如果失败,需要重试来确保两边的一致性。为了支持控制器失联时虚拟交换机仍然保持正常转发,虚拟交换机支持fail-static模式。
另一个解决方案,是基于rpc的改进模式。在控制器中对应每个转发设备都有一个逻辑映射,控制器维护一份该转发设备的逻辑数据。和上述模式的差别在于,控制器不再写虚拟交换机的转发表,而是在控制器和数据面Agent之间通过rpc同步逻辑数据,然后由Agent将逻辑数据翻译成虚拟交换机支持的格式写入转发表中。在控制器和数据面Agent之间需要依赖分布式共识算法,来保证逻辑数据的同步。为了避免控制器维护过多连接,也可以引入proxy。这种方式和上面的方式对比,主要在于增加了一层Agent的缓存,相对复杂一些,带来的好处是控制器不再关心底层虚拟交换机具体支持的格式。
原文链接:https://zhuanlan.zhihu.com/p/565588734
(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂
更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! !