一、简介
KVM(Kernel-based Virtual Machine的英文缩写是内核内建的虚拟机。有点类似于 Xen ,但更追求更简便的运作,比如运行此虚拟机,仅需要加载相应的 kvm 模块即可后台待命。和 Xen 的完整模拟不同的是,KVM 需要芯片支持虚拟化技术(英特尔的 VT 扩展或者 AMD 的 AMD-V 扩展)。
在KVM中,可以运行各种未更改的GNU/Linux, Windows 或任何其他系统镜像。每个虚拟机都可提供独享的虚拟硬件:网卡,硬盘,显卡等
qemu 全称Quick Emulator。是独立虚拟软件,能独立运行虚拟机(根本不需要kvm)。kqemu是该软件的加速软件。kvm并不需要qemu进行虚拟处理,只是需要它的上层管理界面进行虚拟机控制。虚拟机依旧是由kvm驱动
VirtIO paravirtual 是 Linux 虚拟机平台上统一的虚拟 IO 接口驱动。通常主机为了让客户机像在真实环境中一样运行,需要为客户机创建各式各样的虚拟设备,如磁盘,网卡,显卡,时钟,USB 等。这些虚拟设备大大降低了客户机的性能。如果客户机不关注这些硬件设备,就可以用统一的虚拟设备代替他们,这样可以大大提高虚拟机的性能。这个统一的标准化接口在 Linux 上就是 VirtIO 。需要注意的是 VirtIO 运行在 kernel 2.6.24 以上的版本中才能发挥它的性能优势。另外 KVM 项目组也发布了 Windows 平台上的 VirtIO 驱动,这样 windows 客户机的网络性能也可以大大提高了。
二、关于x86平台的实现虚拟机的挑战
1974年,Popek和Glodberg在一篇论文中定于了“经典虚拟化(Classical virtualization)”的基本要求,他们认为,一款真正意义上的VMM至少要符合三个方面的标准
等价执行(Equibalient execution):处理资源的可用性及时间上的不同之外,程序在虚拟化环境中及时间上的不同之外,程序在虚拟机环境中级真实环境中的执行是完全相同的
性能(Performance):指令集中的大部分指令都能直接运行于CPU上
安全(Safety):VMM要能够完全控制系统资源
x86平台实现虚拟化技术的挑战
X86处理器有4个特权级别,Ring0-Ring3,只有运行在Ring0-2级时,处理器才可以访问特权资源或执行特权指令,运行在Ring0级时,处理器可以运行所有的特权指令。x86平台的操作系统一般只是用Ring0和Ring3这两个级别,其中,操作系统运行在Ring0上,用户进程运行在Ring3级
1.特权级压缩(Ring Compression)
为了满足上面所述的需求,VMM自身必须允许在Ring0级,同时为例避免GuestOS控制系统资源,GuestOS不得不降低自身的运行级别而运行于Ring3(Ring1、2不适用)
此外,VMM使用分页或端限制的方式物理内存的访问,但是64位模式下段限制不起作用,而分页又不区分Ring0、1、2。为了统一和简化VMM的设计,GuestOS只能和用户进程一样运行在Ring3。VMM必须监听GuestOS对GDT、IDT等特权资源的设置, 防止GuestOS运行在Ring 0级,同时又要保护降级后的GuestOS不受Guest进程的主动攻击或无意破坏
2.特权级别名(Ring Alias)
设计上的原因,操作系统假设自己运行于Ring0,然而虚拟化环境中的GuestOS实际上运行于Ring1或Ring3,由此,VMM必须保证各GuestOS不能得知其正运行于虚拟机中的这一事实,以免其打破前面的“等价执行”标准,例如,x86处理器中的特权级别存放在CS代码段寄存器内,GuestOS却可以使用非特权PUSH指令将CS寄存器压栈,然后POP处理检查该值。又如,GuestOS在地特权级别时读取特权寄存器GDT、LDT、IDT和TR时病不发生异常。这些行为都不同于GuestOS的正常期望
3.地址空间压缩(Address Space Compression)
地址空间压缩是指在VMM必须在GuestOS的地址空间中保留一段供自己使用,这是x86虚拟化技术面临的另一个挑战。VMM可以完全运行于自由的空间地址,也可以部分地运行于GuestOS的地址部分,前一种方式,需在VMM模式与GuestOS模式之间切换,这会带来较大的开销,此外,尽管运行于自己的地址空间,VMM仍需要在GuestOS的地址空间保留出一部分来保持空间结构,如IDT和GDT。无论是哪一种方式,VMM必须保证自己用到地址空间不会受到GuestOS访问或修改
4.非特权敏感指令
x86使用的敏感指令并不完全隶属于特权指令集,VMM将无法正确捕获此类指令并作出处理。例如,非特权指令SMSW在寄存器中存储的机器状态就能够GuestOS所读取,这违法了经典虚拟化理论的需求
5.静默特权失败(Silent Privilege Failures)
x86的某些特权指令在失败时并不返回错误,因此,其错误将无法被VMM捕获,这将导致其违反经典虚拟机心跳中的“等价执行”法则
6.中断虚拟化(Interrupt Virtualization)
虚拟化环境中,屏蔽中断及非屏蔽中断的管理都应该由VMM运行,然而,GuestOS对特权资源的每次访问都会触发处理器异常,这必然会频繁屏蔽或启用中断,如果这些请求均由VMM处理,势必会极大影响整体系统性能
三、KVM组件和内存管理
1.kvm组件
kvm主要两类组件组成
/dev/kvm:管理虚拟机的设备节点,用户空间的程序可通过其ioctl()系统调用集来完成虚拟机的创建启动等管理工作,它是一个字符设备,其主要完成的操作包括:创建虚拟机、为虚拟机分配内存、读写VCPU的寄存器、向VCPU注入中断、运行VCPU
qemu进程:工作于用户空间的组件,用于仿真pc及的I/O类硬件设备
2.kvm内存管理
KVM继承了Linux系统管理内存的诸多特性,比如,分配给虚拟使用的内存可以被交换至交换空间、能够使用大内存页以实现更好的性能,以及对NUMA的支持能够让虚拟机高效访问更大的内存空间等
KVM基于Intel的EPT(Extended Page Table)或AMD的RVI(Rapid Virtualization Indexing)技术可以实现更新的内存虚拟功能,这可以降低CPU的占用率,并提供较好的吞吐量
此外,KVM还借助于KSM(Kernel Same-page Merging)这个内核特性实现了内存页面共享。KSM通过扫描每个虚拟机的内存查找各虚拟机间相同的内存页,并将这些年内存合并为一个被各相关虚拟机共享的单独页面。在虚拟机试图修改此页面中的数据时,KSM会重新为其提供一个新的页面副本。实践中,运行于同一台物理主机上的具有相同的GuestOS的虚拟机之间出现相同内存页面的概率是很大的,比如共享库、内核或其他内存对象等都有可能表现出相同的内存页,因此,KSM技术可以降低内存占用进而提升整体系能
四、使用qemu-kvm管理kvm虚拟机
Qemu是一个广泛使用的开源计算机仿真器或虚拟机,当作为仿真器时,可以在一种架构(如PC机)下运行另一种架构(如ARM)下的操作系统和程序,而通过动态转化,其可以获得很高的运行效率。当作为一个虚拟机时,qemu可以通过直接使用真机的系统资源,让虚拟系统能够获得接近于物理机的性能表现。qemu支持xen或者kvm模式下的虚拟化,当用kvm时,qemu可以虚拟x86、服务器和嵌入式powerPC,以及s390的系统
Qemu当运行于主机架构相同的目标架构时可以使用KVM,例如,当在一个x86兼容处理器上运行qemu-system-x86时,可以利用KVM加速--为主机和客户机提供更好的性能
Qemu有如下几个部分组成
处理器模拟器(x86、PowerPC和Sparc)
仿真设备(显卡、网卡、硬盘、鼠标等)
用于将仿真设备连接至主机设备(真实设备)的通用设备
模拟机的描述信息
调试器
与模拟器交互的用户接口
1.查看硬件是否支持虚拟化
[root@node1 ~]# grep --color -Ei "(vmx|svm)" /proc/cpuinfo
2.加载kvm模块并安装qemu-kvm
[root@node1 ~]# modprobe kvm_intel //我的机器为intel的,如果是AMD的cpu则使用kvm_amd [root@node1 ~]# lsmod |grep kvm kvm_intel 54285 0 kvm 333172 1 kvm_intel [root@node1 ~]# yum install -y qemu-kvm qemu-kvm-tools
3.qemu-kvm命令
在RHEL6上,qemu-kvm默认安装于/usr/libexec/目录中。由于此目录中部署与PATH环境变量,故无法直接使用,这样也阻止了可以直接使用qemu作为创建并管理虚拟机,如若想使用qemu虚拟机,可以通过做链接的方式
[root@node1 ~]# ln -s /usr/libexec/qemu-kvm /usr/sbin/
qumu-kvm命令格式为“qemu-kvm [options] [disk_image]”,其选项非常多,不过,大致可分为如下几类:标准选项、USB选项、显示选项、i386平台专用选项、网络选项、字符设备选型、蓝牙相关选项、Linux系统引导专用选项、调试/专家模式选项、PowerPC专用选项、Sparc32专用选项
本处只介绍标准选项、i386平台专用选项、显示选项及Linux系统引导专用选项等相关的选项
1)qemu-kvm的标准选项
qemu-kvm的标准选项主要涉及指定主机类型、CPU模式、NUMA、软驱设备、光驱设备及设备等
-name name:设定虚拟机名称
-M machine:指定要模拟的主机类型,如Standard PC、ISA-only PC或Intel-Mac等,可以使用“qemu-kvm -M ?”获取所支持的所有类型
-m megs:设定虚拟机的RAM大小
-cpu model:设定CPU模拟的类型,如coreduo、qemu64等,可以使用“qemu-kvm -cpu ?”获取所支持的所有类型
-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]:设定模拟的SMP架构中CPU的个数等、每个CPU的核心数及CPU的socket数目等;默认为1个。PC机上最多可以模拟255颗CPU;maxcpus用于指定热插拔的CPU个数上限
-numa opts:指定模拟多节点的numa设备
-fda file:使用指定文件(file)作为软盘镜像,file为/dev/fd0表示的物理软驱
-fdb file:使用指定文件(file)作为软盘镜像,file为/dev/fd1表示的物理软驱
-hda file:使用指定文件(file)作为硬盘镜像,模拟的为第一个IDE插槽上的主硬盘
-hdb file:使用指定文件(file)作为硬盘镜像,模拟的为第一个IDE插槽上的从硬盘
-hdc file:使用指定文件(file)作为硬盘镜像,模拟的为第二个IDE插槽上的主硬盘
-hdd file:使用指定文件(file)作为硬盘镜像,模拟的为第二个IDE插槽上的从硬盘
-cdrom:使用指定文件file作为CD-ROM镜像,需要注意的是-cdrom和-hdc不能同时使用,使用file指定为/dev/cdrom/可以直接使用物理光驱
-deive option[,option[,otion]....]: 定义一个新的硬盘设备,可以子选项如下
file=/path/to/somefile:硬盘映像文件路径
if=interface:指定硬盘设备所连接的接口类型,即控制器类型,如ide、scsi、sd、mtd、floppy、pflash及virtio等
index=index:设定同一种控制器类型中不同设备的索引号,即标识号
media=media:定义介质类型为硬盘(disk)还是光盘(cdrom)
snapshot=snapshot:指定硬盘设备是否指定快照功能:on或off
cache=cache:定义如何使用物理机缓存来访问块数据,其可用指有none、writeback、unsafe和writethrough四个
format=format:指定映像文件的格式,具体格式可参见qemu-img命令
-boot [order=drives][,once=drives][,menu=on|off]:定义启动设备的引导次序,每种设备使用一个字符表示,不同的架构所支持的设备及其表示字符不就相同,在x86架构上,a、b表示软驱、c表示第一块硬盘、d表示第一个光驱设备,n表示第一个网络适配器,once表示只在第一次加载使用
2)qemu-kvm的显示选项
显示选项用于定义虚拟机启动后的显示接口相关类型及属性等
-nographic:默认情况下,qemu使用SDL来显示显示VGA输出;而此选项用于禁止图形接口,此时,qemu雷氏一个简单的命令行程序,其仿真串口设备将被重定向到控制台
-curses:禁止图形接口,并使用curses/ncurses作为交互接口
-alt-grab: 使用Ctrl+Alt+Shift组合释放鼠标
-ctrl-grab:使用右Ctrl键是否鼠标
-sdl:启用SDL
-spice option[,option[,option]...]:启用spice远程桌面协议,具体请参考qemu-kvm的手册或使用qemu-kvm --help查看
-vga type:指定要仿真的VGA接口类型,常见的类型有:
cirrus:Cirrus Logic GD5446显示卡
std:带有Bochs VBI扩展的标准VGS显示卡
vmware:VMWare SVGA-II兼容的显示适配器
qxl:QXL半虚拟化显示卡,与VGA兼容,在Guest中安装qxl驱动后能以很好的方式工作,在使用spice协议时推荐使用此类型
none:禁用VGA卡
-vnc dispaly option[,option[,option]...]:默认情况下,qemu使用SDL显示VGA输出;使用-vnc选项,可以让qemu监听在VNC上,并将VGA输出重定向至VNC会话:使用此选项,必须使用-k指定键盘类型,红帽将vnc设定为默认的输出
3)i386平台专用选项
-no-acpi:禁用ACPI功能,GuestOS与ACPI出现兼容问题时使用此选项
-balloon none:禁用balloon设备
-ballon virtio[,addr=addr]:启用virtio ballon设备
4)网络属性相关选项
网络属性相关选项用于定义网络设备接口类型及其相关的各属性等信息。这里只介绍nic、tap和user三种类型网络接口的属性,其他类型请参考qemu-kvm的手册或使用qemu-kvm --help查看
-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]:创建一个新的网卡设备并连接至vlan n中;PC架构上默认的NIC为e1000,macdder用于为其指定MAC地址,name用于指定在一个监控是显示的网络设备名称:emu可以模拟多个类型的网卡设备,如virtio、i82557b、i82559er、ne2k_isa、pcnet、rt18139、e1000、smc91c111、lance及mcf_fec等,不过,不同平台架构上,其支持的类型可能只包含签署列表中的一部分,可以用“qemu-kvm -net nic,mode=?”来获取当前平台支持的类型
-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile]:通常物理机的TAP网络接口连接至vlan n中,使用script=file指定的脚本(默认为/etc/qemu-ifup)来配置当前网络接口,并使用downscript=dfile指定的脚本(默认为/etc/qemu-ifdown)来撤销接口配置,使用script=no和downscript=no来分别禁止执行脚本
-net user option[,option[,option]...]:在用户模式配置网络栈,其不依赖于管理权限:有效选项有:
vlan=n:连接至vlan,默认n=0
name=name: 指定接口的现实名称,常用于监控模式中
net=addr[/mask]: 设定GuestOS可见的IP网络,掩码可选,默认为10.0.2.0/8
host=addr:指定GuestOS中看到的物理机的IP地址,默认为指定的网络的第二个,及x.x.x.2
dhcpstart=addr:指定DHCP服务地址池中16个地址的起始IP,默认为第16个至第31个,即x.x.x.16-x.x.x.31
dns=addr: 指定GuestOS可见的dns服务器地址,默认为GuestOS网络的第三个地址,及x.x.x.3
tftp=dir:激活内置的tftp服务器,并使用指定的dir作为tftp服务器的默认根路径
bootfile=file:BOOTP文件名称,用于实现网络引导GuestOS
4.使用qemu-img管理磁盘映像
qemu-img是qemu用来实现磁盘映像管理的工具组件,其有很多子命令,分别用于实现不同的管理功能,而每一个子命令也都有一系列不同的选项。语法格式为“qemu-img subcommand [options]”,其支持的子命令如下
create:创建一个新的磁盘映像文件
check:检查磁盘映像文件中的错误
convert:转换磁盘映像的格式
info:显示指定磁盘映像的信息
snapshot:管理磁盘映像的快照
commit:提交磁盘映像的所有改变
rbase:基于某磁盘映像创建新的映像文件
resize:增大或缩减磁盘映像文件的大小
5.创建一个虚拟机实例
创建磁盘映像 [root@node1 ~]# qemu-img create -f qcow2 -o size=100G,preallocation="metadata" /kvm/img/centos6.img 准备配置网络接口的脚本 #!/bin/bash switch=br0 if [ -n "$1" ];then ifconfig $1 up sleep 1 brctl addif $switch $1 exit 0 else echo "Error" exit 1 fi 安装VNC [root@node1 ~]# yum install -y tigervnc 准备桥接设备 关于准备桥接设备的步骤,请移步本人博文http://wangfeng7399.blog.51cto.com/3518031/1414999 安装虚拟机 [root@node1 ~]# qemu-kvm -name "centos6.5" -m 512 -smp 2 -drive file=/kvm/img/centos6.img,media=disk -drive file=/root/centos6.5-x86_64-bin-DVD1.iso,media=cdrom -boot order=dc,once=d -net nic -net tap,ifname=vnet0,downscript=no VNC server running on `::1:5900'
6.使用vnc连接
[root@node1 ~]# vncviewer :5900
可以看到系统可以开始安装了
后期将推出KVM的高级应用,敬请等待