KVM&Libvirt基本概念及开发杂谈

导读 你们好,本次肖力分享的主题是KVM&Libvirt基本概念及开发杂谈,内容有些凌乱松散,主要基于本身早期整理的笔记内容和实践感悟,有些内容不免有失偏颇,望见谅。前面先介绍下须要了解的基本知识,大部份内容在肖力著做中都有更详细的解释,可阅读参考。

KVM包含:php

1.内核模块kvm.ko,用于核心虚拟框架。
2.包含与处理器相关的模块kvm-intel.ko,kvm-amd.ko
3.kvm须要使用通过修改定制的qemu软件提供用户空间工具
*内核组件已经包含在Linux内核2.6.20中了
*部分操做系统在kvm中运行仍然存在某些问题,能够查看KVM官网提供的操做系统运行兼容性状态列表

使用KVM的前提条件:java

1.qemu-kvm-release.tar.gz
2.kvm-kmod-release.tar.bz2,本身编译内核模块的须要这个东东
3.支持VT技术的Intel处理器或支持SVM技术的AMD处理器

使用qemu前提条件:node

1.zlib库及头文件
2.sdl库及头文件
3.alsa库及头文件,这个是用来提供虚拟化音频相关功能,默认是禁用的,如今不知道什么状态了,可使用--enable-alsa来启用
4.gnutls库及头文件,可选的VNC TLS支持,默认此功能是开启的,能够用--disable-vnc-tls关闭
5.kernel头文件

*建立,安装,运行KVM虚机,须要使用QEMU提供的用户空间工具,之前是分开发布的,如今分支已经合并,成为qemu-kvm。
*libvirt为用户提供了同不一样虚拟化技术交互的抽象接口。

libvirt基本理念:python

1.同linux虚拟化技术进行交互
2.免费,自由
3.稳定的C语言API
4.其余通用语言的绑定开发接口(java,python,perl,php。。。)
5.针对DMTF虚拟风格
6.QMF代理,用于AMQP、QPID信息系统

libivrt支持度:linux

虚拟技术:kvm/qemu,  XEN, LXC, OpenVZ, UserModeLinux, VB, ESX, HyperV, PowerVM, Parallels, Bhyreios

虚拟网络:桥接,NAT,VEPA,VNLINKc++

存储:IDE、SCSI,USB,FC,LVMISCSINFS,FS算法

libvirt对各类开发语言的支持:数据库

1.直接支持c和c++,其余经过绑定支持 
2.C#,JAVA,OCAML,Perl,PHP,Python 
3.libvirt直接支持python,若是是经过安装包安装而不是源码编译的,须要确保安装合适的包,在RHEL中,叫libvirt-python,在ubuntu中叫python-libvirt,其余平台可能有不一样的名字。

URI:用于链接或远程链接到宿主机的libvirt虚拟环境,相似数据库的链接字符串ubuntu

1.指定URI链接到libvirt:经过把name参数传递到virConnectOpen或virConnectOpenReadOnly方法: virConnectPtr conn = virConnectOpenReadOnly("xxx:///default"); 
2.为节省管理员时间,能够在libvirt客户端配置文件中配置URI别名,
配置文件位置/etc/libvirt/libvirt.conf(针对root用户)或$XDG_CONFIG_HOME/libvirt/libvirt.conf(针对非特权用户),可用下面语法设置别名 uri_aliases = [ "miaomiao=xxx://xxx@www.xxx.com.cn/system", "wangwang=xxx://xxx@www.xxx.com/system" ] 别名由a-z,0-9,_等字符组成,URI别名会应用到任何打开libvirt链接的应用中,除非把参数VIR_CONNECT_NO_ALIASES传给virConnectOpenAuth,
若是别名中包含非法字符,则不作任何别名查找。 
若是URI传递给virConnectOpen参数为NULL,则libvirt会用下面规则肯定URI: 
  1.环境变量:LIBVIRT_DEFAULT_URI 
  2.客户端配置文件:uri_default参数
  3.探测每一个虚机管理器知道找到一个可用的

libvirt基本概念:

node:节点,宿主机,一个node是一个单独的物理机,用于运行虚机

hypervisor:一个软件层,能够把一个物理机用不一样的配置虚拟化为多个虚机的集合

domain:虚拟机,在容器级虚拟化状况中,是一个子系统,运行在由hypervisor提供的机器上

libvirt:提供一个通用的软件层,安全高效的管理node上的domain,同时实现远程管理功能。

*在windows系统中使用libvirt java绑定,须要使用libvirt java库,jna.jar库及对应平台的dll文件,若是报错:找不到dll或找不到相关模块时,须要安装virtviewer 在java代码中加入: System.setProperty("jna.library.path", "c:\\program files\\VirtViewer\\bin"); 并须要在上面路径放置一份virt-0.dll文件副本,命名为virt.dll

SPICE:

SPICE服务端是一个用libspice实现的VDI库,VDI定义了一系列接口来发布虚拟设备。(如:显示设备,键盘,鼠标)而且能让不一样的 spice组件和这些设备交互,从一方面来讲,服务端使用spice协议同客户端通讯,从另外一方面来讲,服务端同VDI主机应用进行交互如QEMU。 SPICE客户端是最终用户所面对的接口。

QXL设备和驱动

当libspice与qemu结合使用时,QEMU QXL PCI设备能够用来提高远端显示性能,加强客户机的图形系统。QXL设备须要客户机QXL驱动支持。 SPICE协议支持一种通讯信道,此通道链接客户和服务端的代理,当使用QEMU时,SPICE代理位于客户机,VDI端口是一个QEMUPCI设备,可 以与此代理进行通讯。

SPICE有六大通道:

主通道:控制与配置

显示通道:图形命令,图形,视频流

输入通道:键盘和鼠标输入

光标通道:定位设备的位置与光标形状

回放通道:服务端的声音在客户端播放

录制通道:从客户端进行音频捕获

SPICE图像压缩功能:

SPICE自己提供了多种图像压缩算法,能够在服务器初始化时进行选择,也能够在运行期动态选择. QUIC是SPICE专有的图像压缩算法,此技术基于SFALIC算法,Lempel_zip(LZ)算法一样也是SPICE支持的算法。QUIC和LZ 都是本地算法,独立编码每个图像。全局LZ(GLZ)是另外一个SPICE专有算法,与LZ同基于历史的全局字典表共同使用,GLZ能够在大量图像之间使 用重复表达式来下降流量消耗,从而保存带宽。特别适合在低带宽的广域网环境中使用。 SPICE一样提供了一个针对每个图像自动选择压缩算法的工做模式,经过图像属性启发式的选择LZ,GLZ,QUIC算法。 从理论上讲,LZ、GLZ更适合压缩合成图像,QUIC更适合压缩真实图像.

视频压缩:

SPICE使用低损压缩算法压缩发送到客户端的图像,可是视频流倒是使用不一样的方法来处理。SPICE服务端使用自启发方式标记动态视频区域并把他 们做为视频流发送出去,编码使用mjpeg,这种处理方法在某种程度上节约了流量,提升了spice性能,尤为在广域网环境中。但是在某些状况下,这种启 发行为可能会致使低质量的图像效果,好比把不断更新的文本区域识别为视频区域,从而致使部分区域图像效果质量低下。

从源代码编译,须要如下组件:

*qpixman:一个控制像素区域的通用库,包括低级别像素控制程序,同时也被cairo库使用,cairo是一个用于支持多输出设备的2D图形库,qpixman是pixman的轻量级修改版

*qcairo:cairo是一个矢量图形设备无关库,qcairo是cairo的轻量级修改版 *celt:CELT是一种音频压缩算法,以高质量传输音乐,信号会有很是小的延迟 *ffmpeg:是一个用于音频和视频重编码,转换,流传输的库。包括libarcodec音频视频编码库 *log4cpp是一个灵活的日志记录库,能够针对文件,syslog等,继log4j以后成型

*关于windows虚机安装virtio硬盘驱动的问题,一种方式是在安装系统的过程当中加在virtio驱动光盘或软盘(winxp),若是系统 已经装完,能够先建立一个小磁盘镜像, qemu-img create -f qcow2 xxx.img 1G 编辑虚机配置文件,加入此硬盘镜像,设置参数dev='vdc' bus='virtio'启动系统后会发现新硬件,选ISO镜像中对应的virtiosto驱动选virtioscsi驱动关闭vm,修改虚机配置,删除 小硬盘镜像,把原磁盘改成dev='vda' bus='virtio'并删除地址部分,启动系统查看驱动状况。

*关于已有libvirt时本身编译libvirt时致使libvirt-sock不存在状况,该位置在/run/user/1000 /libvirt/libvirt-sock或/usr/local/var/run/libvirt/libvirt-sock,编译后加在 libvirtd守护进程,用netstat查看libvirt-sock是否在配置文件制定位置侦听。

使用java的libvirt开发API时注意:

* 在使用java程序编写libvirt应用时,当虚机处于pmsuspended状态时是没法获取domainInfo信息,会出现数组越界的错误提示。

* 使用attachDevice方法添加设备时要注意,flag=0时,表示执行结果影响当前状态,当前状态为运行状态,则只有运行时存在,当前状态为关闭 状态则影响关机配置文件。flag=1时,表示影响运行时状态,执行此方法时,虚机必须处于Active状态。flag=2时,表示影响虚机持久配置文 件,可是在qemu环境中flag=1会不支持,程序会爆出不支持热插拔,可使用domainUpdateDeviceFlags进行换盘操做。 更新持久配置文件后,须要关机从新启动以使新配置生效。domain.getXMLDesc()方法获取的是虚机的运行时配置,而不是持久化配置,因此会 看到被删除的设备仍然还在。

* 使用DomainUpdateDeviceFlags()方法更新虚机配置时,使用updateFlags 0或1都会更新处于Active状态的虚机运行时配置,在虚机重启后会保持这种更新,由于重启虚机不会从新加载持久化配置,关机以后从新开机,配置会还原 为原先配置。 当使用updateFlags为2时,会出现没法更新的状况,虽然方法会执行成功,但没法更新持久配置文件。在关机状态下,使用 updateFlags=1时,会报错,由于更新Live状态只能在domain的active状态下执行。

* 须要注意的是Libvirt不支持cdrom、floppydisk驱动器的热插拔,使用attachDevice()方法时,制定flags为0或1 时,某些设备类型如CDROM对运行时修改可能会返回失败,缘由是hypervisor底层驱动不支持。若是对正在进行块复制的设备进行detach() 方法操做,hypervisor可能会阻止detach()的操做,在这种状况下,须要先使用domainBlockJobAbort()方法先中止该复 制操做便可。

* 根据hypervisor和设备类型的不一样,在一个处于active状态的domain中去除一个设备的操做多是异步执行的,也就是说,当你执行 detach()方法时,仅仅是请求去除一个设备,实际去掉此设备的时间多是以后的一段时间,这是根据虚拟层与客户os配合完成的。这每每容易被忽略, 由于有时会看到在配置文件中此设备已经被删除了,但hypervisor可能尚未真正删除这个设备,这可能会致使某些后续操做的失败。想要检查设备是否 真的被成功删除了,要么从新使用domainGetXMLDesc()方法,要么为DOMAIN_EVENT_ID_DEVICE_REMOVED增长一 个事件处理器,若是当detachDeviceFlags()方法返回时,设备已经被删除,事件会在API CALL结束以前触发。为了帮助现有的客户端在大多数状况下更好的工做,这个API会尝试把在请求以后过了一段时间才完成的异步删除操做转变为同步删除操 做,换句话说,API在异步操做的状况下会等待一下子来让删除操做得以完成。 注意,热插拔设备不会保持,一旦domain进入S4状态即hibernation状态,除非一样修改了domain的持久配置文件。

* 使用setMaxMemory()方法设置虚机最大内存时,默认使用的是AFFECT_CURRENT,也就是说当domain关闭时,修改持久化配置文 件,当domain处于active状态时,修改运行时配置或运行时持久化配置都修改,这个要看hypervisor的行为而定。例如,在libvirt 中当domain处于active状态时,修改最大内存时会报错,必须关闭domain再修改持久化配置。

在使用API开发虚机快照功能时,须要注意以下几点:

若是某虚机建立快照时使用的是内部快照或系统检查点,则该虚机全部硬盘都必须建立内部快照,qemu不支持建立混合快照,即一部分硬盘建立内部快照,一部分建立外部快照,固然只读盘如光驱默认是不建立快照的。
系统检查点默认全部可读写硬盘使用内部快照(关机状态下,会忽略disks标签内容)。

若是在建立快照方法中指定了flags为16(disk-only),则没有明确指定快照方式的硬盘默认使用外部快照,qemu目前不支持内外部混合快照。
使用系统检查点快照时,对cpu特性集有要求,当domain配置中cpu特性集有invtsc特性时,在domain运行时执行系统检查点快照会报错,解决办法,去掉invtsc特性或将cpu model改成custom。
当执行系统级快照时(开机状态下),若是配置文件标签制定snapshot=internal则硬盘快照默认也会使用internal方式执行,反之若是 标签制定为external则硬盘默认也会使用external方式执行。这是由于qemu快照机制目前不支持内外部快照混合模式,libvirt内部机 制会自动把硬盘快照方式调整为与内存相同方式。
使用外部快照要注意,执行外部快照文件是指向原硬盘快照(base 盘)的从镜像,执行完外部快照后,libvirt会将domain配置文件中的硬盘镜像改成新建立的外部快照文件,这样此文件能够用来存储执行快照后全部 差别化内容,因此,libvirt不容许直接删除外部快照。 外部快照会与以前建立的外部快照造成一个差别存储链,内部快照不会与外部快照造成一个差别存储连。建立快照以后,快照配置文件会包含虚机配置文件的所有内 容用于还原。

外部快照                               内部快照

win7------------------------->win7_snap-------------------->win7_snap2(包含在win7_snap文件内部)

vm                                     外部                          vm

                                 |--------------------->win7_snap3

                                                                     vm

win7是win7_snap的backingstore,win7_snap2 快照存在于win7_snap文件中,win7_snap是win7_snap3的backingstore,内存外部快照可重复覆盖。 * 在关机状态下,执行任何快照,不能包含有内存状态,须要把内存snapshot设置为no,由于关机状态下没有内存运行状态,内存都清空了。 *建立系统检查点时,在关机状态下,默认建立内部快照,并且必须使用内部快照,建立外部快照会报错,可是使用disk-only模式快照,则在关机状态下 容许建立外部快照同时也容许建立内部快照。外部快照声称的默认文件名称为原始硬盘镜像.快照名称 * 使用disk-only方式针对正在运行的虚机建立快照,必须使用external方式,而且标签的snapshot必须为no,使用内部快照会报错,内 部快照和系统检查点快照要求全部硬盘都必须参与执行快照,使用disk-only和external方式并用执行快照才能针对不一样硬盘单独执行快照策略。 * 使用系统检查点快照方式对处于active状态的虚机执行快照,快照生成的是内部仍是外部取决于memory标签的snapshot值。 * 使用diskonly模式或关机状态下建立快照,标签snapshot必须为no,由于以上两种快照都没法保存内存状态。

各类快照模式及虚机状态的匹配状况:

1.虚机关机状态,diskonly模式:memory=no(必须),disk可使用内部或外部快照,而且外部快照能够对每一个盘分别定制建立策略,默认建立external快照。

2.虚机运行状态,diskonly模式:memory=no(必须),disk快照只能使用external模式建立,不支持建立内部快照。

3.系统检查点,虚机关闭状态:memory=no(必须),disk快照只能使用内部快照,并且是真对全部硬盘,没法针对每一个盘定制快照建立策略。

4.系统检查点,虚机运行状态:memory=internal或external,disk快照的建立模式根据内存快照建立方式而定,无论内部仍是外部快照都只能对全部硬盘建立快照,不支持对每一个硬盘定制建立策略。

为何快照机制这么混乱,由于libvirt和qemu对快照机制持有不一样观点,可是那种观点更好,这是见仁见智的,咱们能够根据状况选择使用。

ps:内部快照优势:不单独声称额外文件,没有存储连(实际上是内部元数据,机制相似),下降了文件管理复杂度,libvirt对内部快照有良好支持。

ps:内部快照缺点:建立速度较慢,qemu上游较少维护,必须使用qcow2之类支持级联快照功能的文件格式。运行时建立快照虚机有明显停顿感。

ps:外部快照优势:建立速度较快,支持各类源文件格式(后续快照需使用qcow2之类),在运行时建立客户机几乎没有停顿时间,上游qemu在外部快照开发方面较积极

ps:外部快照缺点:快照多了后会造成大量存储文件及存储连,每一层级都使用cow方式读写,严重影响性能,文件管理复杂,libvirt对外部快照支持不太积极。

问答

内存快照,互斥特性不少,怎么在各阶段进行特性间的互斥?快照失败会回退吗?内存复用场景能够作快照吗?大规格内存快照时间规格大约多久?

答:快照建议根据我列出的特性进行选择,不建议把快照功能作得太多太复杂,快照多了会影响性能,若是必需要作外部快照,由于文件使用 backingstore方式存储,最好对不用的快照进行commit,内存复用能够作快照,大规格内存作快照须要定制源码作优化,其实kvm虚拟化只是 给咱们一个基本功能,不少功能若是要知足客户需求须要对qemu和kvm源码进行定制开发。

SPICE有探测识别USB设备的功能吗?就是在宿主机的USB接口上插上USB设备以后,KVM虚拟机可以探测到吗?

答:spice的usb设备识别指的是将终端机上链接的设备识别为虚机上设备的功能,这是有spice的一个子功能usb redirect实现,至于宿主机外设,这是对qemu配置的问题。

相关文章
相关标签/搜索