在前两期,我们学习了虚拟机上的设备虚拟化,包括中断虚拟化、DMA虚拟化和PCIE设备直通。那么,如果在宿主机上有20个虚拟机,每个虚拟机上有一个网卡,我们应当如何实现呢?
最简单粗暴的是,为这20个虚拟机各准备一张物理网卡,一共20张。但是,实际上服务器上是没有这么多PCIE插槽的。
(坐在方老师旁边的一个同学插嘴:20张卡40个网口的不是服务器,是交换机)
另一个实现方案是,为每一个虚拟机增加一个通过Emulate方式虚拟的网卡。如Redhat Virtualization 4.2里面可以为虚拟机增加两种网卡:E1000或RTL8139,实际上这就是让VMM通过软件完整模拟这两种物理网卡的行为。可想而知,这种实现的性能将非常低下。
第三种方案就是我们今天的主题——SR-IOV。
SR-IOV是“Single-root input/output virtualization”的缩写。如果我们从字面上难以理解这个概念,那么,只需要记住结论:SR-IOV指的是让一个PCIE设备具有多个PCIE功能(function),并分配给不同的虚拟机使用的技术。
有了SR-IOV后,就可以把物理网卡虚拟化出多张虚拟网卡,并将虚拟网卡直通到宿主机上的各个虚拟机,如下图:
图中,物理网卡虚拟出了N个虚拟化实例,并被分配给了不同的虚拟机使用,并各自连接到虚拟网桥或OVS上,对外提供服务。由于SR-IOV虚拟出的网卡实例的数据包收发、DMA及中断操作是由真实的以太网控制器芯片完成,因而,应用了SR-IOV技术后,虚拟机的网络收发对CPU的占用大大减少,其时延也更加稳定。
SR-IOV是怎么样的一种高科技呢?原来,它实际上是在2007年由PCI-SIG提出的一种规范,只不过在虚拟化大行其道的2010年后才彰显出了独特的价值。
SR-IOV的架构图如下:
图中可见,在支持SR-IOV的物理NIC(Network Interface Card)中,不像传统的PCIe设备那样只有一个配置空间,而是有若干个配置空间,并可以分配给不同的虚拟机使用。每个配置空间实际上对应SR-IOV设备的一个VF(Virtual Function),通过对VF配置空间的操作,可以让SR-IOV设备进行数据的收发。
VF功能是对PCIE功能的虚拟化,每个网卡有一定的VF规格数,如Intel 的E810网卡支持256个VF,也就是可以给256个虚拟机使用。每个虚拟机的GuestOS会将虚拟出来的VF当成一个物理网卡使用,从而不需要Hypervisor的介入,就可以直接驱动硬件网卡,完成数据的收发过程。
阅读过《局域网SDN硬核技术内幕》的同学会发现,在《局域网SDN技术硬核内幕 5 ——虚拟化网络的实现》中,我们提到,在宿主机内部运行着一个虚拟交换机vswitch,各个虚拟机需要连接到vswitch才可以与宿主机外部的网络实现互通。但是,在有了SR-IOV以后,虚拟机实际上可以操纵着宿主机的网卡直接对外收发数据包,而不涉及vSwitch。这也大大减轻了宿主机的负担。
问(zhong)题(dian)来了:如果两个虚拟机的网卡,都是SR-IOV提供的虚拟化网卡,这两个虚拟机要互通,怎么办呢?
以HP为代表的早期数据中心网络厂商给出了一种叫做VPEA(Virtual Ethernet Port Aggregator)的方案。支持VEPA的网络交换机,收到来自虚拟机的数据包以后,依旧按照其MAC地址进行二层查表,如发现其目的MAC地址的端口,是数据包的入端口,会将这个数据包再转发回虚拟机所在的宿主机,如下图:
如图,数据包在交换机上的入接口和出接口在物理上是同一个,这需要对交换机的转发机制作一定的微调。由于数据流向在交换机上做了180度的转弯,VEPA又被称为“发卡弯”方案。
进一步地,也有部分支持SR-IOV的网卡支持内嵌的交换机,能够让网卡的VF连到内部的交换机上,以缩短宿主机内部虚拟机的数据交换路径。然而,由于OVS有可能支持VXLAN、Geneve或GRE等隧道,基于普通ASIC的内嵌交换机显然难以满足大规模虚拟化场景下的需求。
因而,工程师们又开始为Linux下的网络虚拟化殚精竭虑了。
征途漫漫,唯有奋斗。
请看下回分解。