在上期《云计算与虚拟化硬核技术内幕 (14) —— 不忘初心,删繁就简》中,我们介绍了Linux网桥,也遗留了一些问题:
1. 对Linux网桥的二次开发需要修改内核模块;
2. 无法应用DPDK对Linux网桥进行加速;
3. 无法支持来自SDN控制器的统一控制和监测;
熟悉方老师公众号的同学可能会记得,早在两年以前,方老师就为大家介绍过一个概念——OVS(Open Vswitch),它是一个运行在虚拟机宿主机上的虚拟交换机,用以连接宿主机上所有的虚拟机。
正如交换机(switch)是网桥(bridge)的下一代产品那样,OVS也是取代Linux Bridge的不二之选。
学习过方老师关于交换机的专题的同学可能会回忆起,交换机分为控制平面和转发平面。控制平面定义转发平面的转发行为,而转发平面负责提取进入交换机的数据包的关键信息,以此为依据在交换机中查找转发表项,找到出接口,并将数据包发送出去。控制面与转发面采用分离设计,二者通过一定的接口进行交互。
类似地,OVS也是这种控制面与转发面分离设计的架构。
如图,OVS的数据平面由ovs-vswitchd和kernel datapath构成。当一条网络连接的第一个数据包送到kernel datapath,由于kernel datapath找不到转发表项,是不知道如何处理这个数据包的。kernel datapath会把这个数据包送到ovs-vswitchd进行分析和学习,ovs-vswitchd根据ovsdb-server中的配置,或根据SDN控制器通过openflow下发的流表进行匹配后,会将数据包送回到kernel datapath,同时将快速转发表项也下发到kernel datapath,完成首包转发。后续的数据包在kernel datapath进行查表即可。
OVS的控制平面可以是ovsdb-server,也可以切换到openflow模式,绕开ovsdb-server,由统一的Openflow SDN控制器直接向ovs-vswitchd下发流表并作为数据平面转发的依据。
我们发现,由于OVS的数据平面是纯软件实现的,我们可以很方便地对其扩展功能。迄今为止,OVS在各项功能方面都持续领先于基于ASIC的硬件交换机,如对VXLAN,NVGRE,GENEVE等overlay隧道的支持方面,可领先硬件交换机1年以上。特别地,大部分硬件交换机难以支持的NetStream/Netflow采样特性,OVS早在2014年的版本中就能够支持。
再让我们把视角放大到整个宿主机:
图中,虚拟机向OVS发送数据包的时候,在虚拟机的视角看来,是调用ens33一类虚拟网卡的驱动发送数据包,而在宿主机的视角看来,是前端驱动通过virtio向后端驱动传递了一个事件通知KVM,KVM在vhost-net中把这个事件描述的数据包送去TAP。OVS从TAP收包,开始进入内核的kernel datapath。接下来,就是前文中介绍的OVS工作流程。
当OVS确定了数据包转发到哪个VM的时候,vhost-net也会通过virtio向VM的vNIC前端驱动传输网络数据包事件,并通过中断通知到VM所在的线程接收数据包——这也就是GuestOS视角的网卡中断。GuestOS会在中断处理中实现对数据包的上送协议栈和应用程序。
我们发现,在这样的一个处理流程中,每个VM在收发数据包的时候都会有中断产生,会涉及到内核态与用户态的切换,以及cacheline miss,这也会造成不小的开销。同时,由于OVS的kernel datapath实际上是在操作系统的几个进程中完成转发,VM发送数据包的时候并不意味着数据包能够在确定的时间内得到OVS的处理,而是有可能由于进程阻塞在其他事件上,而一直没有处理来自OVS的数据包。这样可能导致网络抖动的恶化,甚至导致机器学习等业务无法正常运行。
因此,我们需要想办法解决这一问题——
亚当斯密在《国富论》中提出,社会的进步,在于将专业的事交给专业的人。对于网络数据平面工作而言,这种专业的事交给专业的人有两个思路:
A:利用DPDK,占用若干个硬件线程,在用户态搞定数据包的收发和转发;
B:在宿主机的NIC上做改造,将SR-IOV虚拟出的网卡VF通到可编程转发单元,顶替vSwitch的功能;
在下期,我们将为大家讲解这两种思路的利弊。