【写在前面】飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力,聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域,包含了应用使能套件、软件仓库、软件支持、软件适配认证四大板块,旨在共享尖端技术,为开发者提供一个涵盖多领域的开发平台和工具套件。点击这里开始你的技术升级之旅吧

image.png

本文分享至飞腾开发者平台《FT-2000+/64 KVM虚拟化系统解决方案--QEMU/KVM的高级功能和用法》

1 介绍

  本文主要以基于arm平台的FT-2000+/64服务器为例介绍qemu/kvm的高级功能和用法。

2 半虚拟化驱动

  在之前的文档中《FT-2000+/64KVM虚拟化系统解决方案--虚拟化介绍v1.03》我们对半虚拟化有过简单的介绍,其中virtio技术是最成熟、最广泛的应用。在既要考虑性能又要考虑可迁移性的情况下,使用virtio无疑是一个很好的选择。

2.1 virtio基本原理介绍

  virtio最初是由澳大利亚的一个天才程序员Rusty Russell编写,是一个在Hypervisor之上的抽象API接口,让客户机知道自己运行在虚拟化环境中,进而根据virtio标准与Hypervisor协作,从而在客户机中达到更好的性能(特别是I/O性能)。目前有很多虚拟机都使用了virtio半虚拟化驱动来提高性能。
  在QEMU/KVM中,virtio的基本结构如下图所示:

image.png

  关于virtio的具体功能以及实现请参考如下链接:https://hhdx.xyz/post/virtio-intro/

2.2 virtio驱动的具体使用

  在《FT-2000+/64KVM虚拟化系统解决方案--KVM虚拟化v1.03》文档里面的虚拟化内核配置章节,我们已经有说明,宿主机内核必须要支持相关的virtio驱动才可以在QEMU/KVM框架中使用。下面我们将一一列举一些常见的可以使用virtio来提高性能的设备。参考地址:https://hhb584520.github.io/kvm_blog/2017/02/17/kvm-virtio.html。

  1) virtio-scsi

  下面是scsi设备使用virtio方式,在libvirt域的配置文件示例:

<controller type='scsi' index='0' model='virtio-scsi'>
    <address type='pci' domain='0x0000' bus='0x03' slot='0x00'function='0x0'/>
</controller>

  2) virtio-net

  下面是网卡设备使用virtio方式,在libvirt域的配置文件示例:

<interface type='bridge'>
    <mac address='52:54:00:3e:ea:a6'/>
    <source bridge='br0'/>
    <model type='virtio'/>
    <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>

  3) virtio-gpu

  下面是显卡设备使用virtio方式,在libvirt域的配置文件示例:

<video>
    <model type='virtio' heads='1' primary='yes'/>
    <address type='pci' domain='0x0000' bus='0x05' slot='0x00'function='0x0'/>
</video>

  4) virtio-ballon

  下面是mem-balloon使用virtio方式,在libvirt域的配置文件示例:

<memballoon model='virtio'>
    <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</memballoon>

  以上几个就是主要需要使用virtio的地方,更详细的用法可以查阅libvirt官方文档。

  在客户机系统中lspci查看,可以看到virtio设备如下,带有virtio的就是virtio设备:

image.png

3 内存气球mem-balloon

  KVM的内存气球技术使得可以在虚拟机中按照需要调整的内存大小,提升内存的利用率。参考地址:https://www.jianshu.com/p/ce746f327424。

image.png

3.1KVM中ballooning的优劣势

  KVM中的ballooning在节约和灵活分配内存方面有着明显的优势,主要有以下三点:

  1) 节约内存

  2) ballooning对内存的调节很灵活,既可以精细地请求少量内存,也可以粗犷滴请求大量内存。

  3) Hypervisor使用ballooning让客户机归还部分内存,从而缓解其内存压力。而且从气球中回收的内存也不要求一定要分配给另外的进程。

  另一方面,kvm中ballooning使用不方便,不完善也是存在的:

  1) ballooning需要客户机操作系统加载virtio-balloon驱动。

  2) 如果有大量内存需要从客户机系统中回收,那么ballooning可能会降低客户机的操作系统性能。

  一方面,内存的减少可能会让客户机中作为磁盘数据缓存的内存放到气球中,从而使客户机的磁盘IO访问增加;另一方面,如果机制处理的不好,也可能让客户机中正在运行的进程由于内存不足而执行失败。

  3) 目前还没有比较自动化、方便的机制来管理ballooning。

  没有对客户机的有效监控,这可能会不便于在生产环境中大规模自动化部署。

  4) 内存的动态增加或者减少可能会使内存过度碎片化,从而降低内存使用时的性能。另外内存的变化会影响客户机内核对内存的优化。

3.2 ballooning的使用

  在上面virtio驱动章节中,我们介绍了域的libvirt配置文件中关于virtio-memballoon的修改。在做了这一步操作后其实就可以直接使用了。

  查看域的配置文件,客户机中最大内存为4194304KB,也就是4GB。

  下面演示如图:

image.png

  可以看到客户机中内存:

image.png

  使用setmem命令设置内存,注意这个内存的值只能小于或等于最大内存值。

image.png

  可以看到客户机中内存已经变小了,这时释放出来的内存又可以被宿主机中其他进程使用了。

4 vhost和 vhost-user

4.1 核态的vhost-net后端以及网卡多队列

  virtio-net的后端处理程序可以提高网络吞吐量和降低网络延迟。

  要想内核支持vhost-net,需要在内核配置中选上相关配置:

image.png

  在虚拟化配置中选上virtio net的支持、virtio-vsock支持以及要想在arm上使用选上cross-endian支持。

  在使用libvirt管理虚拟机时,网络中的vhost是默认打开的。我们可以用命令查看如下:

image.png

  我们可以看到有一个vhost后端线程正在运行,我们在没有配置的情况下只有一个vhost队列用于收发客户机的数据包。其中vhost-2693中的2693是前面启动客户机的QEMU进程ID。

  假如我们想更改vhost的收发队列数,可以进行如下操作,修改域的配置文件:

image.png

  只需要添加vhost一行,设置队列数即可。再次查看,我们可以发下vhost队列数变为2了,这表明有两个vhost后端线程在处理客户机网络数据。

image.png

  进入客户机中,可以用ethtool查看队列数,可以看到当前虚拟eth0使用的是2个队列:

image.png

  一般来说,使用vhost-net作为后端处理驱动可以提高网络性能。不过,对于一些使用vhost-net作为后端的网络负载类型,可能使其性能不升反降。特别是从宿主机到其客户机之间的UDP流量,如果客户机处理接收数据速度比宿主机发送数据要慢,这时就容易出现性能下降。在这种情况下,使用vhost-net会使UDP的接收缓冲区数据更快地溢出,从而导致更多的数据包丢失。这时我们需要手动在配置文件中关闭vhost,指定后端驱动名称为"qemu"而不是"vhost"。

image.png

  可以看到已经没有vhost线程了。

image.png

4.2 用户态的vhost-user作为后端驱动

  vhost-user可以用来解决采用 vhost 的方案时guest 和 host 之间又存在多次的上下文切换和数据拷贝的问题,为了避免这种情况,业界就想出将 vhost 从内核态移到用户态。这就是 vhost-user 的实现。参考地址:https://blog.csdn.net/qq_15437629/article/details/81226901。

5 进程的处理器亲和性和vCPU的绑定

  进程的处理器亲和性(Processor Affinity),即是 CPU 的绑定设置,是指将进程绑定到特定的一个或多个 CPU上去执行,而不允许调度到其他的 CPU 上。设置进程的处理器亲和性带来的好处是可以减少进程在多个 CPU 之间交换运行带来的缓存命中失效(cache missing),从该进程运行的角度来看,可能带来一定程度上的性能提升。换个角度来看,对进程亲和性的设置也可能带来一定的问题,如破坏了原有 SMP 系统中各个 CPU 的负载均衡(load balance),这可能会导致整个系统的进程调度变得低效。尽管 Linux 内核的进程调度算法已经非常高效了,在多数情况下不需要对进程的调度进行干预,不过,在虚拟化环境中有时却有必要对客户机的 QEMU 进程或线程绑定到固定的逻辑 CPU 上。在libvirt域xml配置中,我们已经简单介绍怎样配置vcpu的绑定,下面是在libvirt域中设置cpu绑定的例子,参考地址:https://z.itpub.net/article/detail/442A7C85D11718C195851FBDAF036E4。

image.png

  将vcpu 0\~3分别绑定到宿主机中cpu 4\~7上。

  在宿主机中查看,top -H后,按f键,然后选择Last Used Cpu和Number of Threads,退出,就可以看到正在运行的线程所占的CPU了。

image.png

  其中CPU 0/KVM就是vCPU0线程,可以看到P那一项,一直都是4,说明vCPU0线程已经绑定了CPU4,一直在CPU4上运行,其他几个CPU 1/KVM、CPU 2/KVM、CPU 3/KVM也可以看出分别一直绑定在CPU 5 、6、7上。

  总的来说,在KVM环境中,一般不推荐手动设置QEMU进程的处理器亲和性来绑定vCPU,但是,在非常了解系统硬件架构的基础上,根据实际应用需求,可以将其绑定在特定CPU上,从而提高客户机的CPU执行效率或者实现CPU资源独享的隔离性。

6 设备的热插拔

6.1 磁盘的热插拔

  首先,需要说明的是,磁盘的热插拔是指的虚拟磁盘文件的热插拔,并非指宿主机上的物理磁盘添加到宿主中的热插拔。

  磁盘的热插拔可以用attach-disk和detach-disk进行热插拔的添加和删除。

  下面我们演示一下,我们先看kvm1中的域xml配置:

image.png

通过以下命令也可以看到只有一块磁盘:

virsh domblklist kvm1

image.png

6.1.1 在线添加磁盘

  1) 创建一块新的磁盘:

   qemu-img create -f qcow2 -o lazy_refcounts=on
   /var/lib/libvirt/images/kvm1_add.qcow2 30G

image.png

  2) 启动虚拟机kvm1:

virsh start kvm1

  3) 进入kvm1客户机中,fdisk -l查看,可以看到只有一块磁盘。

virsh console kvm1

  4) 退出到宿主机上,添加磁盘:

virsh attach-disk kvm1 /var/lib/libvirt/image/kvm1_add.qcow2 sdb --cache=none --subdriver=qcow2

  如果想永久添加磁盘或者永久删除磁盘,可以再在后面添加--config即可。

image.png

  5) 再进入kvm1客户机中fdisk -l查看,可以看到已经成功添加了磁盘:

image.png

  这时我们就可以对/dev/sdb进行格式化分区和挂载了。

6.1.2 在线卸载磁盘

  1) 下面我们再进行在线卸载磁盘:

virsh detach-disk kvm1 sdb:

image.png

  2) 通过下面命令可以看到,已经成功卸载掉一块磁盘了。

virsh domblklist kvm1

  我们可以进入客户机fdisk -l中进一步确认,可以看到/dev/sdb也成功卸载了。

6.2 网卡的热插拔

  网卡的热插拔是指,使用模拟的网卡热插拔,非宿主机上的物理网卡透传热插拔。

  下面是我们验证步骤:

image.png我们先查看kvm1的网卡。

virsh domiflist kvm1:

image.png

  可以看到只有一个虚拟网卡,桥接在br0上,进入客户机中ifconfig -a查看也只有一块网卡:

image.png

6.2.1 在线添加网卡

  1) 添加网卡。

virsh attach-interface kvm1 --type bridge --source br0:

  2) 查看是否添加成功:

virsh domiflist kvm1

image.png

  可以看到已经新加了一个虚拟网卡vnet1。我们再进入客户机中查看,可以看到已经多一个网卡:

image.png

6.2.2 在线卸载网卡

  1) 下面我们进行卸载网卡操作:

virsh detach-interface kvm1 --type bridge --mac 52:54:00:6d:7b:a3

其中mac后面跟的mac地址是我们新加的网卡mac地址,virsh domiflist kvm1可以看到。

  2) virsh domiflist kvm1再次查看只有一个网卡了:

image.png

  进入客户机中ifconfig -a查看,同样可以看到网卡已经卸载成功。

  如果想永久添加或者永久卸载网卡,在命令后面添加--config即可。


推荐阅读

欢迎广大开发者来飞腾开发者平台获取更多前沿技术文档及资料

如开发者在使用飞腾产品有任何问题可通过在线工单联系我们



版权所有。飞腾信息技术有限公司 2023。保留所有权利。

未经本公司同意,任何单位、公司或个人不得擅自复制,翻译,摘抄本文档内容的部分或全部,不得以任何方式或途径进行传播和宣传。

商标声明

Phytium和其他飞腾商标均为飞腾信息技术有限公司的商标。

本文档提及的其他所有商标或注册商标,由各自的所有人拥有。

注意

本文档的内容视为飞腾的保密信息,您应当严格遵守保密任务;未经飞腾事先书面同意,您不得向任何第三方披露本文档内容或提供给任何第三方使用。

由于产品版本升级或其他原因,本文档内容会不定期进行更新。除非另有约定,本文档仅作为使用指导,飞腾在现有技术的基础上尽最大努力提供相应的介绍及操作指引,但飞腾在此明确声明对本文档内容的准确性、完整性、适用性、可靠性的等不作任何明示或暗示的保证。

本文档中所有内容,包括但不限于图片、架构设计、页面布局、文字描述,均由飞腾和/或其关联公司依法拥有其知识产权,包括但不限于商标权、专利权、著作权等。非经飞腾和/或其关联公司书面同意,任何人不得擅自使用、修改,复制上述内容。


飞腾开发者
6 声望3 粉丝

飞腾开发者技术小助手,定期分享飞腾技术文档,助力开发者打怪升级。更多材料获取:[链接]