在上期,我们为大家介绍了AWS的Nitro架构。Nitro架构实质上是利用Nitro Card和Nitro Hypervisor,创建一个资源池,Nitro Hypervisor向Nitro Card下发指令,Nitro Card实现虚拟机在宿主机上的创建,调度和销毁,从而实现宿主机上几乎所有的CPU和内存资源都可以用于售卖给租户。
这样的架构也存在一定的局限性。
第一个问题是,如果部分宿主机不具备SmartNIC,而另一部分宿主机带有SmartNIC,二者之间的虚拟机如何迁移呢?
由于Nitro Card等SmartNIC,本身以SR-IOV的方式虚拟出了多个VF,并直通给了各个虚拟机,那么,运行在带有SmartNIC的宿主机上的所有虚拟机都可以看到至少2个设备——网络相关的VF和存储相关的VF。而在不具备SmartNIC的宿主机上,虚拟机的网卡为VirtIO-net网卡,存储盘为VirtIO-blk存储,由宿主机上的virtio后端驱动来实现。如果虚拟机从带有SmartNIC的宿主机迁移到不带SmartNIC的宿主机,会找不到原有的虚拟化网卡和存储设备,从而无法正常运行!
显然,这不是工程师们想要的。
在地球的另一面,熟读《倚天屠龙记》的工程师们受到了乾坤大挪移的启发,想出了一个解决方案:
乾坤大挪移分七层,每一层之间互相解耦,又互相依赖,高层次可以屏蔽低层次的差异。
计算机系统也像乾坤大挪移一样分为七层:
应用层
中间件与框架层
操作系统层
驱动程序层
硬件模块层
集成电路层
晶体管与触发器层
如果在虚拟机驱动程序层屏蔽SmartNIC和软件VirtIO的差异,对于虚拟机而言,就可以不感知自己的网卡和硬盘究竟是SmartNIC还是VirtIO!
答案是肯定的。我们可以让SmartNIC实现真正的Virtio透明卸载,也就是,无论宿主机是不是带有Smart NIC,宿主机上运行的虚拟机CVM看到的都是Virtio-net和Virtio-blk的驱动。在宿主机上安装有SmartNIC的场景,宿主机操作系统上Virtio后端驱动实际上就是SmartNIC的驱动,SmartNIC的VF会执行真正的网络与存储的功能。
当旧的不带SmartNIC的宿主机逐步淘汰下线,需要将虚拟机迁移到带有SmartNIC的宿主机时,虚拟机操作系统看到的依然是virtio-net和virtio-blk的前端驱动,只是具体执行者从宿主机上的虚拟网卡和软件vhost块存储驱动变成了SmartNIC的VF。
以存储为例:
如图,当宿主机上的VM发起一个IO,假设其大小为32K (8个4K IO)。
由于云上的块存储一般为分布式存储,需要将IO打散到多个节点来提升性能,宿主机上的VirtIO会将大IO拆分为多个4K的小IO,然后分发到各个分布式存储节点,并由分布式存储节点实现三副本写入操作。
在不带SmartNIC的宿主机上,需要由宿主机的CPU执行VirtIO后端,完成以下工作:
- 将大IO拆分为4K IO;
- 计算各个4K IO的crc;
- 为各个4K IO生成IO头部;
- 将IO体,IO头部,CRC内容拼装成IO体;
- 通过DMA将IO体通过网络发送到目的存储节点;
而在SmartNIC中,这些工作本身都可以通过硬件实现。与宿主机CPU实现唯一的区别是,在第1步开始之前,需要让SmartNIC发起一次DMA,从宿主机内存中把IO头和IO体读入SmartNIC的缓存。
对于Virtio网络,二者实现的区别与存储类似,区别是SmartNIC除了实现VirtIO-net的后端驱动之外,还实现了vSwitch,特别是vSwitch作为VPC边界的网络overlay隧道封装和解封装功能。
我们注意到,是否关心网络与存储实现究竟是SmartNIC实现,还是宿主机VirtIO驱动实现的,其实是宿主机操作系统层面,而宿主机操作系统对虚拟机操作系统提供的驱动没有任何差异。
这样,我们就可以比较容易地实现虚拟机在普通宿主机和具备SmartNIC的宿主机之间迁移了。
这正是:
他强由他强,清风拂山岗,
他横由他横,明月照大江。
然而,这种透明迁移技术依然有解决不了的问题——
请看下回分解。