note:这里主要记录我对IO虚拟化的理解,希望这篇文章对想了解虚拟化IO的同学有点帮助。这是我在看论文[vale,a switched ethernet for virtual machines]的时候总结的有关io虚拟化技术,概括性的和思考结果比较多,细节内容比较少。
我们假定现在大部份的计算机服务都迁移到了虚拟化环境中(实际上是事实),带来的主要好处是资源同享并减少开消。虚拟机也是需要访问外围装备的,比如磁盘和网络。即便在非虚拟化环境中访问网络也是很有挑战性的技术(利用程序使用系统调用),所以到了虚拟机这1层面,访问网络,要到达硬件的速度很困难。所以要怎样处理虚拟化I/O呢?主要有3种方法来虚拟化I/O,分别是全虚拟化,半虚拟化和Direct I/O accsss。他们在处理guest和hypervisor通讯和hypervisor和host架构上分别采取了不同的处理方式。
全虚拟化
最简单的方法就是给guest操作系统1个虚拟网络接口。然后由hypervisor拦截下虚拟机的Accesses (to critical resources),并且hypervisor中用1个模块来摹拟网卡硬件的功能(emulator)。这类方法很直观易懂,在历史上来讲,这也是第1种I/O虚拟化方式,最开始由VMware 和QEMU采用。
(这只是最基本的解释了,至于说怎样写1个摹拟器?我没写过,感兴趣的可以google~~)
当hypervisor截取到guest的packet以后,如果要发送到网络上(这里可以既包括内部网络也包括外部网络),就需要使用host的网络栈了,比如TCP/UDP sockets(封装)。
全虚拟化看起来直观易懂,很容易使用,环境配置简单。只是摹拟的开消会很大,1般来讲,那是1个非常庞大的系统(所以写个摹拟器工作量很大……)。
半虚拟化
上面讲了全虚拟化,和全虚拟化相对的就是半虚拟化,半虚拟化的意思就是说guest操作系统能够感知到自己是虚拟机。那末对I/O系统来讲,只要guest的驱动能够和hypervisor进行沟通,。不同的hypervisor使用不同的技术来实现半虚拟化。比如说xen,就是通过事件通道,授权表和同享内存的机制来使得虚拟机中的驱动(前端驱动)和host中的驱动(后端驱动)来通讯。最后由装备域的标准linux内核来处理IO。
另外kvm使用virtio,和xen的半虚拟化网络驱动原理差不多。还有就是比如VMware的Guest tools,和xen的半虚拟化机制应当也很相似,1通百通。
那末半虚拟化相对全虚拟化有甚么好处?虽然和全虚拟化1样,都是使用软件完成虚拟化工作,但是由于机制不1样,这类方式由于不像摹拟器那末复杂,软件处理起来不至于那末慢,所以有更高的带宽,更好的性能。但是还是存在性能问题,依然达不到硬件的速度。
break:到此为止,提1个问题,为何软件实现的性能不好?比如达不到有硬件支持(下面会提到)的速度?难道硬件支持就1定快,软件就1定慢?能不能设计出1种软件比有硬件支持的更快呢?(这个问题边想边继续看吧,到文章的结尾处我会给出我的认识)
Direct I/O Access
前面的两种方式,不管是摹拟还是沟通方式,都需要guest和hypervisor的交互,而这里要讲的这类方式是为了不guest和hypervisor的沟通,使得guest能够直接将流量发到硬件上面。看起来很奇怪是否是,但是这类方式应当怎样做?host或hypervisor怎样将网卡的控制权转移给host?有无1个网卡可以转移给多个虚拟机使用呢?(这只是1点提示问题,你可能还可以想出更多的问题来。)为了解决这些问题,需要1套机制支持,这里主要表现在硬件的支持。
首先斟酌1个简单的情形,将1个NIC分配给1个guest(host和其他guest都不能看到这个NIC),现在的方法是通过pci passthrough技术。现在1般1个网卡是1个pci装备,当系统辨认这个网卡后,在内存会分配1块对应的pci配置空间,为了支持pci passthrough,现代的cpu架构会提供1种机制将这块pci物理地址映照到guest操作系统的内存。比如intel的vt-d和amd的iommu(cpu对虚拟化的硬件支持)。然后通过软件比如,pci passthrough命令来使用1次这块硬件,实现映照的功能。但是是否是1定要用到CPU的虚拟化支持呢,我想只要你牛逼,写个有映照功能和隔离机制的软件也能够做到一样的功能吧。
另外如果要将1个NIC分配给多个guest,我想就是SR-IOV技术了。就是将1个网卡虚拟出多个VF,然后将每一个VF通过pci passthrough分配给不同的guest。这里除cpu的虚拟化支持,比如intel的vt-d,也还需要网卡本身的虚拟化技术,需要虚拟出多个vf功能,和邮箱机制等功能(我做不了硬件的虚拟化,只讲功能需求)。
关于这3种方式,我的了解程度都不1样。虽然3种我都用过。全虚拟化的方式采取摹拟器(写1个摹拟器的难度太大,没有尝试过写,也没有读过代码);xen的半虚拟化机制看过源码,调用它的api实现过1些功能。至于pci passthrough我曾使用82599网卡的SRIOV功能,将网卡虚拟化为多个vf,再将多个vf分配给多个虚拟机进行实验,这样虚拟机的带宽确切很高。
break:对那个问题,私以为软件运行的速度不1定比纯硬件慢。软件归根结柢也是表现在cpu上运行(推荐看看csapp《深入理解计算机系统》)。一样1个功能,软件的不同设计致使运行的速度极可能不同。有的快,有的慢。当软件的设计很完善的时候,这个时候影响软件运行的瓶颈就是CPU频率和内存带宽。对实现交换机功能这样的软件,如果这个交换机设计公道,基本上能到达cpu的频率,如果对应的物理网卡的带宽小于这个值,那末这个软件交换机相对物理网卡而言,设计很棒,我们会觉得虚拟机的网络IO性能真的是相当棒。
另外如果网卡带宽大于cpu主频或内存带宽的时候,此时如果交换机软件也设计相当棒的时候,瓶颈就表现在cpu主频上。
p.s.由于比较懒,没有画图,希望不影响理解,有些观点没有展开,细节讲的过少,有些没有重点。会渐渐修改补充,欢迎评论与建议:-I