虚拟化技术之KVM

                     虚拟化技术之KVM

                                         作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.什么是虚拟化
  其实虚拟化技术已经不是一个新技术了,上个世纪六十年代IBM公司已经在使用,只不过后来(上个世纪八十年代)随着PC机的出现,虚拟化为最初的应用目的已经可用武之地了,但是随着X86系统的增多以及PC机性能的提升以及现在业务模式的需要,所以使得虚拟化技术再一次蓬勃发展起来。在上个世纪的1974年有2位很著名的教授Popek和Glodberg在一篇论文中定义了经典虚拟化应该至少满足三个需求:
    1>.等价执行(除了资源可用性以及时间上可能存在不同之外,程序在虚拟化环境中和在真实物理机中的运行结果和运行机制应该是一模一样的。);
       2>.性能良好(一般而已虚拟机【guest】和底层的hypervisor或者它的基本硬件或者它的架构要保持一致【可以说是直接在cpu上运行的】,否则的话我们称之为模拟器。);
    3>.安全隔离(在同个hypervisor上运行的多个虚拟机彼此之间必须要安全隔离,任何一台虚拟机的操作一定不能影响到其他虚拟机,任何一台虚拟机都不能关闭物理机【除了特权指令】)  
 
二.早期虚拟化
  大家知道KVM(kernel-based virtual Machine)是基于内核的虚拟机。事实上早期的虚拟化技术实现主要是trap(捕获),emulate(模拟)而不是虚拟。
    1>.trap:当虚拟机某一用户要执行某一条指令时,我们的宿主机【hypervisor】能够捕获到Guest虚拟机这种执行指令的请求,将捕获到的指令翻译成它可以执行的指令。
    2>.emulate:大多数的硬件都是通过软件的方式提供给虚拟机的,虚拟机再利用这个软件真正去执行指令时,我们硬件能看到它的hypervisor通过自身的监护程序方能看到所谓的指令执行;
 
三.CPU虚拟化
1.完全虚拟化(full-virtulization)
  我们知道在VMM是运行在环0上的,用于监督虚拟机的特权指令的使用,Guest Kernel运行在环1上,环2是空闲的,环3运行的是应用程序,而环1和环0之间的交互也就是Guest Kernel于VMM他们之间采用BT技术。我们知道如果环3运行的是非特权指令,那么这个指令会直接被调度到CPU上去运行的,如果是特权指令就会交个Guest内核,但是由于Guest内核也无权限执行特权指令,于是通过二进制翻译技术(即BT技术)向VMM发起特权指令请求。
  VMware Workstation就是这种工作机制,无论你的CPU是否支持硬件虚拟化(硬件辅助加速技术),事实上它都能实现完全虚拟化,各个Guest在安装时无需做出任何修改都能运行。因此VMware Workstation必须保证每个虚拟机是内核都认为自己是直接运行在内核上的。
虚拟化技术之KVM
  我们称之完全虚拟化。但是由于VMM需要给每个运行在HOST上的虚拟机都给其模拟出来一个内核,在性能上有损失是无可厚非的事情,为了降低这种损失,又出现了2中技术,即半虚拟化和硬件辅助虚拟化。
 
2.半虚拟化(para-virtulization)
  半虚拟化也叫准虚拟化,有别于完全虚拟化,VMM和Guest Kernel都运行在环0,环1和环2都是空闲的,环三还是运行着应用程序。Guest Kernel是明确知道自己运行在虚拟化环境中的,你可以理解这个Guest Kernel是被经过修改处理的。当GuestOS接收到非特权模式依然还是直接在CPU中运行,当其接收到特权指令调用时,它不会直接去执行,而是向VMM中调用“hypercall”来执行。
虚拟化技术之KVM
  半虚拟化的方式虽然比完全虚拟化跟你讲硬件的使用性能提升但是也是有缺陷的(使用半虚拟化的时候必须要修改GUSET内核)。使得那些商业性的,内核非公开的操作系统(如微软公司的windows系列)无法再实例中运行,所以半虚拟化不是各个场景都能使用的。
 
3.硬件辅助虚拟化(HVM)
  完全虚拟化缺点就是服务器性能的使用率不能得以提升,但是半虚拟化有不适合所有场景,2中虚拟化方式各有利弊,这个时候又兴起了一种硬件辅助虚拟化的技术。
  HVM的运行机制我们可以理解成5个环的运行机子,Hypervisor运行在环-1,Guest Kerne运行在环0上,环1和环2还是空闲,环3运行的是应用程序。当虚拟机的应用程序调用非特权指令的时候还是可以直接调用CPU进行处理,如果是特权指令,就会被环-1所捕获到,然后在被CPU去执行。这种方式需要CPU支持硬件辅助虚拟化。
虚拟化技术之KVM
  我们知道完全虚拟化是不需要修改Guest内核的,硬件辅助虚拟化(HVM)也是不需要修改内核的,但是相比而言,后者是硬件支持虚拟化,比软件模拟出来的完全虚拟化明显是有提升的,虽然说完全虚拟化和硬件辅助虚拟化比半虚拟化是弱了点,但是确实目前的主流。
  因此,我们可以总结三种虚拟化的性能做一个对比:完全虚拟化 > 硬件辅助虚拟化 > 半虚拟化
 
四.内存虚拟化
  在没有虚拟化时,MMU的工作是:当cpu运行指令是,首先会将指令加载到寄存器中,这个寄存指令可能包括寻址指令,要求去获取某一个内存地址的数据。但是我们知道任何进程它能看到的地址空间只是线性地址空间(或者叫虚拟地址空间),换句话说,这个地址是在物理内存上是找不到的。因此需要将这个线性地址转换成物理内存地址,这个对应关系是放在页表(page table)当中的。
 
1.用软件的方式实现内存虚拟化
  这个转换过程事实上就是将进程的页表加载到MMU中,由cpu将线性地址发送给MMU,MMU查找所谓的Page table转换成物理地址的方式。MMU的另外的一个作用就是实现了内存保护,任何时候一个进程发送一个给MMU中并没有的地址时是访问不到的。
虚拟化技术之KVM
  VMM将物理地址空间中可能不是连续的物理内存地址整合成一个虚拟机实例的内存地址,这个虚拟机实例它看到自己的内存地址以为是连续的并且以为就是物理内存地址空间,事实上它已经被VMM虚拟过一次了。所以当美国运行在这个虚拟机的实例在实现地址转换时,它必然要经过虚拟机线性地址转换成Guest的物理内存,再由VMM将虚拟机的物理内存转换成宿主机的内存地址。
 
2.硬件辅助虚拟化
  我们知道了软件虚拟化在实现内存能转换的时候需要经历三个步骤,即:虚拟机线性地址--->虚拟机的物理内存--->宿主机的内存地址。这个过程是相当的复杂的,通过软件模拟的方式实现内存虚拟化,这也就意味着VMM需要监控每一台虚拟内存转换的问题,性能上自然也好不到哪去,这个时候出现了硬件辅助虚拟化技术。
  A.需要对MMU做虚拟化(MMU Virtulization):虚拟机将GVA转换成GPA的同时,MMU虚拟化会自动将GVA转换成HPA的,省略了GPA到HPA转换的过程。如:Intel的EPT(Extended Page Table);AMD的NTP(Nested Page Table)。
  B.也需要对TLB做虚拟化(TLB virtulization):操作系统将TLB进行打标签处理,表明是哪个虚拟机主机的线性地址对应着真正物理内存地址。如:tagged TLB。

虚拟化技术之KVM

 
五.I/O虚拟化
  I/O虚拟化的方式依赖于VMM的实现方式。
1.VMM:对IO的驱动有三种模式
  自主的VMM:vmm自行提供驱动和控制台
  混合的VMM:借助于OS提供驱动
        依赖于外部OS
        自我提供特权域
  寄宿式VMM
 
2.I/O虚拟化模型
    模拟
    半虚拟化
    透传
 
六.KVM(kernel-based virtual Machine)
1.KVM介绍
  KVM的作者是以色列的一个叫Qumranet公司,这个公司大概在2008年9月4号被红帽以一亿七百万美金收购。因此,红帽公司从2008年开始就有了自己的虚拟化解决方案,这也就是它为什么舍弃Xen全心全意投入到KVM的研发的原因之一。
  KVM在2006年10月份才基本功能完成,它是一个很新的虚拟化软件,它在开发时就直接依赖于某些硬件的特性。比方说KVM要支持硬件虚拟化,在飞硬件虚拟化环境中,KVM是运行不了的。另外,KVM在CentOs和RedHat的Linux发行版中貌似只支持64位的操作系统。
 
扩展小知识:
  从某种意义上来讲,kvm的性能利用是远远不如xen的,这就是半虚拟化和完全虚拟化的区别。但是他们都不如基于系统虚拟化的openvz和lxc。kvm ----> xen ----> openvz,lxc。
虚拟化技术之KVM
  通过上面的对比图,我们就会发现完全虚拟化和半虚拟化的区别,尤其是在性能上的体现。不过此处我要强调的是不是性能,而是时间。事实上,我们的Linux系统计时其实是有2套方案的,一种是基于系统的,一种是基于硬件的。是由内核自行根据内核的时钟工作频率来维持的,这个前提是我们的内核必须是在运行在CPU上的,一旦基于虚拟化模式工作,每一个虚拟机实例的CPU拿到的时间本来就是被分割分秒的时间,这并非是真正墙上挂钟走过的时间,但我们的虚拟机可能会认为这是在CPU上真正走过的时间。所以虚拟机的即使一定会存在误差的,为了使得时间不存在误差,我们得使用kvm-clock模块,这个模块会不断从硬件去探测宿主机的时间,但是最好使用NTP服务,可以通过自定义定时任务以保证时间的准确性,
 
2.KVM的基本架构
  一旦引入了KVM之后,就存在三种模式:
    a>.内核模式:宿主机内核,即内核空间
    b>.用户模式:宿主机用户空间
    c>.来宾模式:就是运行在宿主机的用户空间的虚拟机实例。

虚拟化技术之KVM

3.KVM主要有两类组件组成:
a>./dev/kvm:
  管理虚拟机的设备文件,用户空间的程序可通过其ioctl()系统调用集来完成虚拟机的创建启动等管理工作,它是一个字符设备,其主要完成操作包括以下几点:
    1>.创建虚拟机;
    2>.为虚拟机分配内存;
    3>.读,写虚拟机CPU的寄存器;
    4>.向虚拟机CPU注入中断;
    5>.运行虚拟机CPU
 
b>.qemu进程:
  工作于用户空间的组件,用于仿真PC机的I/O类硬件设备;

虚拟化技术之KVM

  qemu是模拟I/O设备给虚拟机的,所以虚拟机在使用I/O设备使用的性能会很差,因此,红帽联合IBM公司研发了一个通用的半虚拟化设备,即virtio,通过virtio的框架,能够虚拟化块设备,网络设备,PCI设备,基于ballon技术来实现内存的动态空战和收缩,还能虚拟化控制台。而对于底层后端设备以上的技术实现都是透明的,是通过transport技术来完成的。
  KVM在实现CPU,硬件平台架构实现虚拟化有引入了半虚拟化通用框架,来提升I/O性能的。KVM的发展是相当的快的,现在很多企业已经在使用KVM技术了。
 
4.KVM内存管理
  KVM继承了Linux系统管理内存的诸多特性,比如,分配给虚拟使用的内存可以被交换至交换空间,能够使用大内存页以实现更好的性能,以及对NUMA的支持能够让虚拟机高效访问更大的内存空间等。
  KVM基于Intel的EPT(Extended Page Table)或AMD的RVI(Rapid Virtualization Indexing)技术可以支持更新的内存虚拟功能,这可以降低CPU的占用率,并提供较好的吞吐量。
 
 
5.KVM的工作机制
  KVM自身不是一个完全意义上的虚拟化软件,它仅仅是内核中的一个模块。如果你将操作系统安装KVM之后,那么这个操作系统的内核立马就变成了hypervisor。也就是你直接创建虚拟机了。它和Xen不同的是,KVM没有Dom0,而是直接拿到了最大权限,因为它直接取得了宿主机的权限,可以直接操作底层硬件。我们也可以说KVM就是一种寄生虫,当他被宿主机安装之后,宿主机的内核就会被改变,从此KVM就可以偷天换日,想干嘛就干嘛,如直接操作底层硬件。因为安装KVM之后,此时的内核的所有权限都被KVM抢了过去。
  一个宿主机在没有安装KVM的时候它的内核是运行在环0上的,当安装上KVM之后,其内核就被移位到环-1去了,因此就把环0,环1,环2,和环3腾出来给各个虚拟机实例来使用。KVM就实现了这样的一个功能。
  KVM可以驱动I/O设备,但是无法虚拟出来I/O,那虚拟机需要用到I/O设备时咋办呢?借助第三方软件QEMU软件实现模拟I/O设备。QEMU就是一个可以创建并管理虚拟机的工具。QEMU也是个模拟器,它模拟CPU时有两种方式工作:
    a>.模拟器:即底层CPU和虚拟机的CPU的指令集可以不一样(假如底层的CPU是X86的,虚拟机的CPU是PDC的),只不过这种方式的性能会非常差,但是不管怎么样,它是可以模拟的。
    b>.虚拟化:底层CPU和虚拟机的CPU的指令集是一样的,于是使得虚拟机中发非特权指令可以在宿主机的CPU上可以直接运行的。
 
6.QEMU与KVM的关系。
  在虚拟化的方式下,未引入KVM之前,所有的虚拟机实例都运行在qemu上,qemu有一个补充工具叫kqemu,它类似于BT技术(实现二进制翻译)。我们也可以说kqemu是qemu的加速器。kqemu据说BUG很多,不是特别稳定,所以运维人员使用的相对较少。这时又兴起了一门技术叫做KVM,它取代了kqemu,实现对qemu的加速功能。
  在引入KVM之后,qemu其实就是一个管理虚拟机的工具,并且也负责模拟I/O设备的工作。也就是说,由KVM实现CPU和内存的管理,让qemu模拟I/O设备和管理虚拟机。所以我们平时使用KVM时是借助于qemu来实现的。不过我们要清楚的知道,这个时候虚拟机实例并不运行在qemu上,而是运行在装载着KVM的内核上。
  KVM是要求硬件必须支持虚拟化的。否则你就只能通过qemu的模拟来实现,其效率相比KVM明显是要低的。换句话说,就是没有KVM支持的话,qemu照样是可以虚拟出来虚拟机的,服务照样可以跑的,但是性能上明显会很低。
 
上一篇:【poj2960】 S-Nim


下一篇:基于axios创建的实例使用axios.all,报错:this.$http is not a function,但请求成功