kvm virtio使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kvm virtio使用相关的知识,希望对你有一定的参考价值。
参考:
《kvm虚拟化技术 实战解析与原理》
http://tec.5lulu.com/detail/107mwn4e6aaa684c1.html
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=7934175&id=5679365
1.balloon技术简介:
通常来说,要改变客户机的内存大小,我们需要关闭客户机,用qemu-system-x86_64重新分配。这个是很不方便的,于是balloon技术出现了。
ballooning(气球)技术可以在客户机运行时动态地调整内存大小,而不需要关闭客户机。它是客户机的balloon driver通过virtio虚拟队列接口和宿主机协同工作来完成的。
balloonDriver的作用在于它既可以膨胀自己使用内存大小也可以缩减内存使用量(可以缩减至几近于无),而且被balloon里面的内存客户机是不可以使用,balloonDriver本身并不直接管理balloon,它的扩容与缩减都是通过virtio队列由宿主机发送信号管理。宿主机可以把balloon的内存取消映射,拿来给其他客户机使用,也可以映射回去,并让balloon缩减,用来增加客户机内存。因为不能使用balloon里面的内存,所以当客户机的内存不足以满足自身应用时,它要么使用swap,要么开启OOM-killer选择性杀死一些进程。
简单地说,类似于,你(客户机)会装货和卸货,但是至于要装还是卸,取决于你的老板(宿主机)。而这些货是干嘛的怎么用,那也是老板的事。你只有这么多货,不够用怎么办?要么造假(swap)要么不卖..
ballooning工作过程主要有以下几步:
(1)hypervisor发送请求到客户机操作系统让其缩减一定数量内存
(2)客户机操作系统收到请求
(3)客户机操作系统利用balloon驱动,缩减内存气球,并发送结果给hypervisor
(4)vmm收到后,取消对balloon内存的映射,从而回收内存
(5)vmm把这些内存自由分配到任何需要的地方
(6)vmm也可以按相反的动作,扩充客户机内存
事实上,kvm balloon技术并不完全是你想的那种动态分配,它是有内存上限的,它是这样子的:
kvm hypervisor给客户机指定一个最大内存(MAXmemory),这个就是客户机最多能使用的内存大小
客户机利用balloon驱动生成内存气球
客户机当前能使用的真实内存(currentMemory)的值就是最大内存减去气球内存的结果
currentMemory=MaxMemory-ballooning
2.ballooning的使用
balloon需要客户机virtio驱动的支持,关于怎么安装驱动,上篇kvm virtio已有说明,这里不重复
kvm 下balloon的启动,是利用-balloon virtio参数来指定,也可以使用-device来分配,如:
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
我们可以用类似以下命令来启动客户机:
qemu-system-x86_64 -m 4096 -smp 6 -balloon virtio -net nic -net tap,script=/etc/qemu-ifup redhat6.qcow2
其中 -m 指明了MAXmemory的值,我们可以ctrl+alt+2切换到qemu monitor 模式利用info balloon 查看当前客户机可用的内存大小。利用balloon num设置balloon 可用内存大小,比如:
(qemu) info balloon
balloon: actual=4096
(qemu):balloon 2048 #这里虽然使用的是balloon命令,但是设置的值是currentMemory,而不是内存气球的值
在linux下,可以利用free -m 等命令查看到内存明显变化。
在windows下,可以利用任务管理器查看内存变化,与linux不同的是,windows下,改变currentMemory的值,任务管理器显示的内存总量并不会减少,而是把已使用量变高。比如:
我们window的内存是4G,当前已经用掉213MB,如果此时我们balloon 2048,那么看到的内存总数依然是4G,但是已使用量会从213MB-->2303MB
值得一提的是balloon设定的值不能超过-m指定的MAXMemory的值,一旦超过,则默认设置为MAXMemory的值
3.所谓的balloon内存过载使用:
kvm下内存过载(能使用超过真实内存数量)使用有三种方式:
swapping:就是把硬盘做成虚拟内存,这样能使用的内存就额外多了虚拟内存部分,大于真实内存
page sharing:把各个进程访问到的相同数据块共享,这样内存只需要一份数据,从而各个进程所需要的内存数量加起来大于真实内存
ballooning:利用每个主机不同时段负载不同这个特点实现,具体如下:
我们知道,很多不同功能的主机不同时段负载不一样,比如提供OA高的主机白天负载比较高,提供娱乐的主机晚上负载比较高,所以一般平均负载不会太高。假设我们有A、B、C、D、E 5台客户机,工作在8G内存的宿主机上,他们的高峰期都需要2G的内存,而低峰期只需要512M不到的内存,假设A、B、C白天很忙,晚上很闲,而E、F白天很闲,晚上很忙,那么我们可以利用balloon技术,每台设置MAXMemory 2G,然后:
白天:A、B、C的balloon设置为2G,EF 512M
总共:2Gx3+512Mx2=7G
晚上:A、B、C 各512M EF 1G
总共:512Mx3+2Gx2=5632M
这样,我们使用8G内存完成了看起来要10G才能运行的客户机,而且还有富余内存,很好地实现了内存过载使用
4.virtio_net的使用
1.查看kvm是否支持virtio
[[email protected] kvm_vhost]# qemu-system-x86_64 -net nic,model=?
qemu: Supported NIC models: ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio
2.启动客户机,(客户机没驱动的参考上一篇,kvm virtio功能配置)
qemu-system-x86_64 -m 4096 -smp 6 -balloon virtio -net nic,model=virtio -net tap,script=/etc/qemu-ifup xp.qcow2 -usb -usbdevice tablet
3.宿主机中TSO和GSO的设置
根据Redhat文档的接受,关闭GSO和TSO可以使半虚拟化网络驱动的性能更加优化,操作如下:
(1)利用brctl show找出供客户机使用的真实网络接口,这里是em1
[[email protected] ~]# brctl show
bridge name bridge id STP enabled interfaces
br08 000.02046d 871562 yes em1
tap0
(2)ethtool -k eth0查看GSO和TSO状态
[[email protected] ~]# ethtool -k em1
...
tcp-segmentation-offload: on#这个是TSO状态
...
generic-segmentation-offload: on#这个是GSO状态
(3)关闭gso和tso
[[email protected] ~]# ethtool -K em1 gso off
[[email protected] ~]# ethtool -K em1 tso off
[[email protected] ~]# ethtool -k em1
...
tcp-segmentation-offload: off#这个是TSO状态
...
generic-segmentation-offload: off#这个是GSO状态
5.使用vhost_net后端驱动
前面所提到virtio在宿主机中的后端处理程序(backend)一般是由用户空间的qemu提供的,如果能把对网络i/o请求的后端处理能够在内核空间完成,那么效率会提高很多。在比较新的内核中有一个叫做“vhost-net”的驱动模块,它工作在内核中,利用它可以让virtio的后端处理程序的内容在内核中完成,从而提高效率。
与vhost_net相关的选项是-net tap ,它的几个参数说明如下
-net tap,[vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostforce=on|off]
vnet_hdr=on|off :是否打开tap设备的iff_vnet_hdr标识。这个标识表示允许发送或接受大数据包仅做部分的检查和校验,开启的话可以提高virtio_net驱动的吞吐量
vhost=on|off :是否开启vhost-net这个内核空间的后端驱动,只对MIS-X中断的virtio客户机有效
vhostforce=on|off :是否强制vhost作为非MIS-X中断的客户机后端处理程序
vhostfs=h:设置去链接已经打开vhost的网络设备
vhost_net需要宿主机的支持,所以可以lsmod |grep vhost_net查看有没有加载这个模块,没有的话modprobe vhost_net,如果内核不这个模块,那么需要重新编译内核
使用vhost_net驱动的客户机启动命令如下:
qemu-system-x86_64 /home/kvm_vhost/xp.qcow2 -net nic,model=virtio -net tap,vhost=on -usb -usbdevice tablet
需要额外说明的是,如果使用libvirt时,xml配置指定的后端驱动名为qemu而不是vhost(这个我还没用过,存疑..没特殊声明的都是自己测试过的,请放心使用)
6.使用virtio_blk
virtio_blk启动没什么好说的,利用-drive file=xx.img,if=virtio即可,命令如下:
qemu-system-x86_64 -drive file=/home/kvm_vhost/redhat6.qcow2,if=virtio -net nic,model=virtio -net tap,vhost=on -curses
有一点需要注意的是:使用virtio_blk后,设备会被识别为vda的形式,这可能会使原来fstab上的交换分区失效,比如:
原来的fstab 交换分区配置:
/dev/hda2 swap swap defaults 0 0
解决方法:
改为: /dev/vda2 swap swap defaults 0 0
7.kvm_clock配置
之所以有这个配置是因为客户机的中断并非真正的中断,而是通过宿主机向客户机注入的虚拟中断,因此中断有可能不能立即传递给一个客户机的所有vcpu,这就可能导致中断需要的时间精确性得不到保证,这对一些应用来说是不行的。
kvm通过kvm_clock向客户机提供精确的system time和wall time来解决这个问题,这个需要较新的硬件平台支持,默认是启动的。可以通过查看宿主机中的CPU信息的contabt_tsc标识来查看硬件是否支持,通过查看内核编译配置文件来了解是否支持kvm_clock
grep constant_tsc /proc/cpuinfo
grep -i paravirt_guest /boot/config-2.6.32-431.el6.x86_64
grep -i kvm_clock /boot/config-2.6.32-431.el6.x86_64
如果结果为y的话,就代表支持,默认qemu-system会让客户机使用kvm_clock作为时钟来源,可以在客户机中使用: dmesg |grep -i kvm_clock 查看是否有对应结果
本文出自 “单季稻” 博客,请务必保留此出处http://linzb.blog.51cto.com/5192423/1878953
以上是关于kvm virtio使用的主要内容,如果未能解决你的问题,请参考以下文章