KVM中的网络IO设备虚拟化方式

在KVM虚拟化的架构里,对CPU的虚拟化采用的是硬件辅助的方式(Intel VT-x,AMD-V),效率比较高,内存的虚拟化有Intel EPT技术的支持,效率也没有问题;那么对于像磁盘驱动器,网卡等io设备来说,KVM提供两种虚拟化方式:采用全虚拟化纯软件实现的QEMU/KVM方式,采用半虚拟化的virtio方式。



如上图,在一些桌面虚拟化产品里,默认采用的是QEMU/KVM方式对磁盘,网卡设备进行虚拟化



对于大多数采用开源KVM方案的桌面虚拟化产品来说,通过在客户机操作系统里安装增强工具,可以将io设备的虚拟化方式改成virtio,从而增强性能

下面分别介绍下这两种虚拟化方式的实现原理:

(一)利用QEMU来模拟IO设备

QEMU以纯软件的方式来模拟IO设备的运行


当客户机的设备驱动程序发起IO请求时,内核KVM模块会截获这次请求,然后经过翻译将本次请求放到内存里的IO共享页面,并通知客户机QEMU模拟进程(客户虚拟机也是底层Linux系统里的一个用户空间进程QEMU-KVM,这是KVM里很重要的一个概念)来处理本次请求,这里KVM模块起的是一个传达的作用,传统的在物理机上运行的程序好比你在餐厅里吃饭,你直接通过服务员(驱动)告诉厨师(硬件)你要吃什么菜,而虚拟化环境里就像在网上叫外卖,你无需知道餐厅在哪,你(客户虚拟机)只需要通知外卖平台(KVM模块)你要吃某个菜(执行一次IO操作),剩下的事情就是由外卖平台去与具体的餐厅协调,保证按时将外卖送到你手上。

从技术的角度来说,内核KVM模块是一个进程,QEMU模拟程序也是一个进程,IO请求的翻译和传达实际上是进行了一次进程间通信(IPC),而实现方式是由KVM模块将拦截的请求放到内存里的IO共享页,共享内存(shared memory)正是IPC最快的实现方式,当一个进程写共享内存,其他进程都立即知道写入的内容,而且可以访问。

QEMU模拟程序获知了本次IO操作的具体信息后,交由硬件模拟代码(Emulation Code)来执行本次IO操作,通过Linux内核里的物理硬件驱动,来调用物理IO设备完成IO操作,并返回所期望得到的值,再将这个值放回IO共享页,通知KVM模块读取这个值,并转交给客户虚拟机上的IO设备驱动。

通过QEMU模拟IO设备,优点是可以模拟出各种各样的硬件,包括一些老的,不常用的设备,兼容性比较广泛,而且不用修改客户机操作系统,就可以让模拟设备在客户机上正常工作。但缺点也很大,每次IO路径太长,大量进程间通信有可能带来的阻塞(虽然阻塞不分配CPU时间片,但也要进行线程的挂起和唤醒),而且所有的IO指令都是敏感指令也是特权指令(Ring1),也会带来VMExit,VMEntry的开销,且IO返还值的传递也要进行多次数据复制,故性能较差。


(二)VirtIO半虚拟化IO设备

VirtIO是运行在Hypervisor上的一个抽象的API接口,通过让客户机知道自己运行在虚拟化环境里,进而根据virtio标准与Hypervisor进行协作,从而获得更好的IO性能。

其基本结构如下图


其前端驱动frontend是运行在客户虚拟机上的驱动程序模块(也就是我们在桌面上安装的虚拟机增强工具,里面包含了如virtio-blk,virtio-net等驱动),而后端处理程序backend是在QEMU里实现的,这种类似于C/S架构的方式屏蔽了底层设备驱动之间的差异,虚拟机中的virtio驱动与QEMU之间通过标准化接口进行通信,不需要经过复杂的翻译转换(而是类似一个中国人和一个日本人,都用对方能懂的语言比如英语沟通,大家一起去完成某个任务),所以效率较高。

在前后端驱动之间,还定义了两层数据结构来对通信进行处理,其中virtio这一层是虚拟队列接口(队列最大的特点是FIFO,先提交的请求先执行),每个虚拟机都有自己的虚拟队列,这也是IO虚拟化和CPU虚拟化之间的区别,没有时间片的分配,所有虚拟机的io请求抢占现有资源,至于怎么对IO做Qos控制,还在学习中,不敢妄言,各个厂家的实现方式似乎并不相同,以后有机会再总结。从逻辑上看,虚拟队列接口就是连接前端驱动和后端处理程序的通道,一个前端驱动可以同时使用若干个虚拟队列,比如对virtio-net网络驱动同时使用2个虚拟队列(一个用于发送,一个用于接受),而virtio-blk块设备驱动只需要使用一个虚拟队列。virtio的下层是virtio-ring的数据结构,这是一个环形缓冲区(又叫循环队列,也是队列的一种),作用是保存前端驱动的多次请求,再批量交给后端驱动处理,同时防止队列溢出(循环队列的特点),通过这种设计约定实现批量处理而不用对客户机的每个io请求进行一次处理,大大提高了客户机与Hypervisor层的协作效率。

virtio的半虚拟化驱动方式,有很高的io性能,几乎和直接跑在硬件上一样,因此只要可能,使用virtio是高效的选择,不过其缺点是需要更改客户机的操作系统,使之知道自己跑在虚拟化环境里(在一些桌面虚拟化产品里,是通过在客户机系统里安装虚拟化增强工具来实现的),同时要求客户虚拟机和宿主机的Linux内核都支持virtio(好比之前的例子里,中国人和日本人都得懂英文,不然还是得等翻译),目前在比较新的Linux(内核版本2.6.24及以上)都支持virtio,所以长远看通过virtio进行io设备的虚拟化是必然。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值