一. 了解Virtio
virtio是通用虚拟化框架,在Qemu-kvm中的I/O是用qemu 来模拟的,性能比较差,用virtio来模拟I/O可以进一步提升I/O虚拟化的性能
传统的qemu-kvm 工作模式:
1.Guest产生I/O请求,被KVM 截获
2.Kvm 经过处理后将I/O请求存放在I/O共享页
3.通知Qemu,I/O已经存入I/O共享页
4.Qemu从I/O共享页拿到I/O请求
5.Qemu模拟代码来模拟本次的I/O,并发送给相应的设备驱动
6、7、8. 硬件去完成I/O操作并返回结果Qemu
9. Qemu将结果放回I/O共享页
10. Qemu通知Kvm去I/O共享页拿结果
11. Kvm去I/O共享页拿到结果
12 . Kvm将结果返回给Guest
**注意:
a) 在这个操作中,客户机作为一个qemu进程在等待I/O时有可能被阻塞
b) 当客户机通过DMA访问大块内存时候,Qemu不会把结果放回I/O共享页,而是直接通过内存映射的方式将结果直接写到客户机的内存中去,然后通过KVM模块告诉客户机DMA操作已经完成
Virtio 基本架构:
前端:是存在于客户机中的驱动模块。
后端:是存在于Qemu中的处理程序。
中间层:在前端和后端之间,还定义了一层来支持客户机与Qemu之间的通信。Virtio和virtio-ring可以看成是一层,Virtio是虚拟队列接口,就是将前端驱动程序附加到后端处理程序,算是前后端通信的桥梁,主要实现控制面,virtio-ring实现了两个环形缓冲,分别保存前后端的信息,实现具体的通讯机制和通讯流是偏向数据面,是桥梁的具体实现。
**注意:virtio设备都是pci设备
二.安装和使用virtio
现在linux里面一般会自带virtio的相关模块,当我们去使用的时候会自动加载相对应的模块。
例如在一个正在使用virtio-net的guest中,可以看到自动加载的模块:
对于客户机时windows的,因为windows默认没有提供virtio相关的驱动,所以可以去网上下载Windows virtio驱动到guest里去安装,也可以通过host来安装,方法:
1.host中安装virtio-win
2.启动win7客户机,将virttio-win.iso作为客户机的光驱
这里用了三个virtio驱动,-net,nic,model=virtio;-balloon virtio;-device virtio-serial-pci,启动后在win7的光驱里面可以看到
然后去设备管理器里安装对应设备的驱动即可。
*注意:安装virtio-scsi安装略有不同,因为当采用virtio-scsi设备的时候,然后去起guest的时候,这个时候guest是没有安装virtio_scsi驱动的,因此guest系统不能启动。解决办法:
a). 创建一个10M的img文件,当做guest的非启动盘
b). 先将guest的启动盘不要指定为virtio-scsi设备,将10M的img指定为virtio-scsi设备
c).quest起来后,由于存在一个virtio-scsi设备,所以在设备管理器里可以看到该设备驱动,并且没安装,然后安装一下即可
d).将guest重新启动,并指定启动盘为virtio-scsi,这时候由于guest已经安装了virtio-scsi驱动,可以正常启动了。那个10M的硬盘可以不需要了。
Virtio设备的使用
1.使用virtio_balloon
方式一:-balloon virtio[,addr=addr] #使用virtio balloon设备,addr可配置客户机中该设备的PCI地址
方式二:用较新的‘-device’的统一参数分配balloon设备,”-device virtio-ballon-pci,id=balloon0,bus=pci.o,addr=0x4”
在qemu monitor中查看和设置客户机内存的大小
2.使用virtio_net
1)检查Qemu是否支持virtio类型的网卡
2)启动客户机时候的命令
-net nic,model=virtio,macaddr=xx:xx:xx:xx:xx:xx –net tap
前端 后端
*注意:若果在使用virtio_net的时候依然得到较低的性能,可以检查并关闭Host的GSO,TSO可以提升性能
检查GSO,TSO:
关闭GSO,TSO:
vhost_net与virtio_net:
virtio_net驱动的后端处理是在用户空间的qemu中完成的
vhost_net驱动的后端处理是在内核中完成的
因此使用vhost_net的性能比virtio_net的性能更好
vhost_net command:
-net nic,model=virtio,macaddr=xx:xx:xx:xx:xx:xx –net tap,vnet_hdr=on,vhost=on
前端 后端
前端guest中采用virtio-net后端处理采用vhost-net(当然需要host支持vhost-net,即支持vhost-net模块)
vnet_hdr=on/off :是否打开tap设备的IFF_VNET_HDR标识,这是tun/tap的一个标识,打开这个标识则允许发送或接收大数据包时仅做部分校验和检查,还可以提高vritio_net驱动的吞吐量
vhost=on/off:是否开启vhost-net这个内核空间的后端处理驱动
vhostfs=h,设置去连接一个已经打开的vhost网络设备
*注意:一般使用vhost-net可以提高网络性能,但是当host的处理速度比guest慢的时候,特别是udp类型的流量,就会导致数据包的丢失,这种情况下,不要用vhost-net。
3.使用virtio_blk
virtio_blk可以提升qemu-kvm中对块设备的访问性能。
virtio_blk command:
-drive file=rhel6u3.img,if=virtio
*注意:使用了virtio_blk后,客户机中看到的磁盘设备的名称就变成了/dev/vda,因此需要修改下/etc/fstab,然后重启
qemu-system-x86_64 -cpu host -smp 56,sockets=1,cores=28,threads=2 -m 8G \
-machine pc,accel=kvm,usb=off \
-drive file=./centos-7.4.1708.qcow2,if=virtio,format=qcow2 \
-vnc 0.0.0.0:12 \
-nic user,model=virtio,hostfwd=tcp::2222-:22 \
-name cpx,process=cpx,debug-threads=on \
-monitor pty -serial stdio
#
Ps -T -p `pgrep cpx`