一.  了解Virtio

virtio是通用虚拟化框架,在Qemu-kvm中的I/O是用qemu 来模拟的,性能比较差,用virtio来模拟I/O可以进一步提升I/O虚拟化的性能

传统的qemu-kvm 工作模式:

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_启动盘

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_处理程序_02

前端:是存在于客户机中的驱动模块。

后端:是存在于Qemu中的处理程序。

中间层:在前端和后端之间,还定义了一层来支持客户机与Qemu之间的通信。Virtio和virtio-ring可以看成是一层,Virtio是虚拟队列接口,就是将前端驱动程序附加到后端处理程序,算是前后端通信的桥梁,主要实现控制面,virtio-ring实现了两个环形缓冲,分别保存前后端的信息,实现具体的通讯机制和通讯流是偏向数据面,是桥梁的具体实现。

**注意:virtio设备都是pci设备

 

二.安装和使用virtio

现在linux里面一般会自带virtio的相关模块,当我们去使用的时候会自动加载相对应的模块。

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_处理程序_03

例如在一个正在使用virtio-net的guest中,可以看到自动加载的模块:

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_处理程序_04

 

 

 

对于客户机时windows的,因为windows默认没有提供virtio相关的驱动,所以可以去网上下载Windows virtio驱动到guest里去安装,也可以通过host来安装,方法:

1.host中安装virtio-win

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_启动盘_05

2.启动win7客户机,将virttio-win.iso作为客户机的光驱

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_处理程序_06

这里用了三个virtio驱动,-net,nic,model=virtio;-balloon virtio;-device virtio-serial-pci,启动后在win7的光驱里面可以看到

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_qemu安装虚拟机软件安装崩溃_07

 

 

然后去设备管理器里安装对应设备的驱动即可。

*注意:安装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中查看和设置客户机内存的大小

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_qemu安装虚拟机软件安装崩溃_08

 

 

 

2.使用virtio_net

1)检查Qemu是否支持virtio类型的网卡

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_启动盘_09

 

 

2)启动客户机时候的命令

-net nic,model=virtio,macaddr=xx:xx:xx:xx:xx:xx         –net tap

                              前端                                                   后端

 

*注意:若果在使用virtio_net的时候依然得到较低的性能,可以检查并关闭Host的GSO,TSO可以提升性能

 

检查GSO,TSO:

 

qemu安装虚拟机软件安装崩溃 qemu安装virtio_启动盘_10

关闭GSO,TSO:

qemu安装虚拟机软件安装崩溃 qemu安装virtio_ci_11

 

 

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`