初识kvm虚拟化

什么是虚拟化
  • 虚拟化是资源的逻辑表示,不会受物理限制的约束。
  • 运行环境不是在真实的服务器上,而是虚拟的环境中。
  • 虚拟化是以某种用户和应用程序都可以容易从中获益的方式来表示计算机资源的过程,而不是根据这些资源的实现、地理位置或物理包装的专有方式来表示的。换句话说,它为数据、计算能力、存储资源以及其他资源提供了一个逻辑视图,而不是物理视图。
(概念有点类似于云计算,这也就表明了为什么虚拟化是云计算发展的源动力,以上概念和理解虚拟化的使用没有半毛关系,只是为了当别人问你是做什么的时候,可以不用说“呃,我是装虚拟机的”)
虚拟化带来的好处:大幅度降低了IT支出成本、减少能源浪费,而且还能极大的增强系统整体安全性和可靠性。(这也是为什么虚拟化能够飞速发展的重要原因。)
虚拟化必须满足的三个条件:同质、高效、资源受控
1.        同质(Equivalence)
即VM的运行环境和物理机的环境在本质上市相同的,表现上可以有一些差异。如CPU的ISA必须一致,CPU core的个数可以不同。
2.        高效(Efficiency)
即VM的性能必须接近物理机。因此,常见的模拟器(boches,simics……)就不能成为VM。为达此目的,软件在VM上运行时,大多数指令要直接运行在硬件上执行,只有少量指令需要VMM的模拟或处理。
3.        资源受控(Resource control)
即VMM对物理机的所有资源有绝对的控制力。虚拟机不允许直接执行敏感指令。(什么是敏感指令?)首先说下什么是特权指令和敏感指令。
        多数计算机体系结构都有2个或以上的特权级,用来分隔系统软件(操作系统)和应用软件。而我们x86的架构中提供了4个运行级别——Linux内核运行在ring0,应用程序运行在ring3 。
系统中有一些操作和管理关键系统资源的指令会被定义为特权指令。
特权指令只有在最高特权级别上才能够正确执行。
如果再非最高特权级上运行,特权指令会引发异常,处理器会陷入到最高特权级别。
在虚拟化后,操作特权资源的指令叫做敏感指令。
其实这个就像在家里,钱是重要的资源,花钱这种敏感指令是需要经过老婆的特权审批的,老婆给才能花,老婆不给就花不了。(连个对象没有的谈到这里不禁泪两行啊)
有了上边三个条件和两种特权级别的认识,我们自己假想的设计一个虚拟机执行代码的结构流程:
        虚拟机内部执行代码的时候,如果是非特权访问的指令,则直接通过进程在用户模式执行,如果是特权的指令,陷入到内核模式模拟执行。这也是CPU虚拟化一个基本方式“陷入模式”。如此,既可以保证同质(本质上还是有物理CPU执行)、高效(技术不同,效率不同)、和资源受控(特权访问都需要VMM模拟执行)。
但理想在现实面前总是那么不堪一击,因为x86在虚拟化天然的短板——有少部分指令不能在以前的虚拟化环节进行正常VMM陷入,导致指令执行失败,使得x86架构的服务器很难正常的完成虚拟化。这就是所谓的虚拟化漏洞。(想绕过老婆的审批就花钱,岂不是乱了套了)


全虚拟化实现的几种典型的方式(虽然XenServer最近开源了,但是这只能是我加快对KVM研究的脚步,动摇不了我对KVM的忠心, )
        因为我们主要是介绍KVM虚拟化解决方案,其他的几种只是简单说下(复杂的内容我也不是很懂)
解释执行
                 取一条执行,模拟出这条指令执行的效果,再去一条指令,周而复始。
二进制翻译(BT)(VMWare不愧是老大,即使出了第一代VT以后,性能还是略微领先。)
(1)        主要思想是在执行时将VM上执行的Guest OS的命令
(2)        翻译成X86 ISA的一个子集,其中的敏感指令被替换成陷入指令
(3)        翻译过程与指令执行交叉进行。不含敏感指令的用户态程序可以不经翻译直接执行。
(4)        该技术为VMWare workstation, VMWare ESX Server早起版本,Virtual PC以及QEMU所采用。
扫描与修补(Scan)SUN的Virtualbox即采用的该技术
(1)        VMM会在VM运行每块指令之前对其扫描,查找敏感指令
(2)        补丁指令块会在VMM中动态生成,通常每一个需要修补的指令会对应一块补丁指令
(3)        敏感指令被替换成一个外跳转,从VM跳转到VMM,在VMM中执行动态生成的补丁指令块。
(4)        当补丁指令块执行完后,执行流在跳转回VM的下一条指令处继续执行
下边就是今天的主角KVM。
VT-x的实现原理:感兴趣的朋友可以直接看下:Intel VT-x的技术手册
VMCS是Intel VT-x中的一个很重要的数据结构,占用一个page大小(4k),由VMM分配,但是硬件是需要读写的,与页表类似。在VMCS有很多域,但每个域在VMCS中的具体位置是不知道的,程序员也不需要关心,只需要使用相应的VMWRITE和VMREAD指令去访问。简单介绍下VMCS中一些重要的域。


其中比较重要的是vm-exit信息域


VMX操作模式


在OS没有虚拟化时,VMX操作模式默认是关闭的
VMXON:打开VMX操作模式
VMXOFF:关闭VMX操作模式
VM-Entry:CPU由根模式切换到非根模式,从虚拟机的角度将,CPU从VMM切换到客户机执行。一般有VMM主动发起。
VM-entry提供了两条指令:VMLANUCH和VMRESUME。
VMLANUCH:用于刚执行过VMCLEAR的VMCS的第一次VM-Entry
VMRESUME: 用于执行过VMLANUCH的VMCS的后续VM-Entry
下图是一个VM-Exit与VM-Entry切换的图,画了好久,还是想不到一个比较直观的表达方式。(尽量之后补一张靠谱点的)


主要流程是,虚拟机执行敏感指令,保存当前的虚拟机状态域,VM-Exit到Host模式,加载VMCS中的宿主机状态域,然后根据VM-Exit信息域去处理中断的内容。
VM-Exit信息域中有中断的条件和中断的原因……会读取中断原因,如果是IO,则交给User模式的Qemu去处理,将结果返回给Host;如果是缺页异常,则会去判断是具体原因(之后内存虚拟化会多说一些);如果是执行指令,则由VMM执行,将结果返回,然后再有VMM执行VM-Entry,加载虚拟机状态域,进入到Guest模式,继续重复之前的流程。
KVM架构(COPY IBM的文档)


在KVM上你可能看到一个叫做QEMU的东西,即使是你在使用KVM虚拟机的时候也很难逃脱qemu的魔掌,我在刚开始学习KVM的时候,一直纠结,KVM到底是什么( Kernel-based Virtual Machine),和qemu有啥关系,为什么有KVM的地方总会有qemu的出现,难道真是基情燃烧的岁月?
 
怎么除了qemu,还有一个kqemu的小伙伴?
kqemu是通过kqemu模块实现内核态的加速,在用户态的qemu通过访问/dev/kqemu设备文件接口调用改进加速。不过,此类模式主要针对Guest与Host运行属于统一架构的虚拟化。
Qemu看起来就比较寒酸了,只有一个用户空间的进程,通过TCG(Tiny Code Generator)动态翻译。很明显的缺点:慢。
KVM说起来并不能算是一个完整的虚拟化解决方案,只是Linux标准内核加载了一个据说有几万行代码的模块。也就是说KVM仅可以在VT技术的基础上,提供一个虚拟的处理器?然后向内核申请点内存的工作?说起来觉得KVM也挺寒酸的。。。不过让KVM遇上QEMU合体成qemu-kvm后,就开始了幸福的生活。。。
下面我们八卦一下qemu和kvm两个小伙伴的幸福生活。
创建虚拟机流程


1)        标准的Linux内核中加入KVM的模块kvm.ko变身成为一个VMM(VMM Virtual MachineMonitor)
2)        在原有的用户模式(工作在ring3)和内核模式(工作在ring0)两种模式的基础上增加了新的客户模式。客户模式存在的特权级别与ring0-3正交。(也就是说客户模式也存在4个特权级别)
3)        用户创建虚拟机,通过调用用户模式的qemu程序,qemu与kvm提供的libkvm库为接口,传递创建指令。
4)        打开/dev/kvm文件并获得文件描述符fd后,通过ioctl指令写入KVM_CREATE_KVM,即可创建一个虚拟机,并返回一个fd_vm的虚拟机文件描述符。
5)        获得fd_vm后,通过ioctl调用KVM_CREATE_VCPU指令,可以对fd_vm所对应的虚拟机创建vCPU,并对vCPU做初始化操作。
6)        然后通过KVM_RUN指令对fd_vcpus操作,启动运行虚拟机。
注:        其实在整个过程中所谓的初始化操作基本上就是一个工作——定义初始化结构体。整个虚拟机在Linux上只是User Mode的一个qemu的进程,而内部则是一堆结构体。
下边是Copy的一段话,觉得挺靠谱的……
一般来说:我们会就3个方面来评断hypervisor的好坏
1:hypervisor 的架构实现如何?"我的hypervisor比你薄...."
2:  硬件辅助(Intel-VT, Amd-V)如何?“我的CPU虚拟化是借助的硬件,肯定比你用软件来的快。”
3 : 半虚拟化的噱头。"我的hypervisor可以支持修改过的guest,因此肯定比你快。"
展开阅读全文

没有更多推荐了,返回首页