KVM: Kernel-based Virtual Machine,基于内核的虚拟机
KVM是由以色列的Qumranet公司所研发,Qumranet公司在2006年10月份完成了KVM的基本功能以后,正式向外宣布KVM诞生。KVM一诞生就立即受到linux维护者的青睐,很快就被收录进了内核。2008年RedHat公司以一亿多美元收购了Qumranet公司,正式拥有了KVM代码。从RHEL5.4开始,KVM就直接被支持了。RHEL5.8开始,Xen被抛弃了。RHEL6.0开始,Xen已经不见踪影,而且很多程序中跟Xen有关的功能都被剥离并移除了。
KVM依赖于硬件辅助的虚拟化(HVM),比如Intel的 VT-x技术,AMD的AMD-v技术。所以如果你的CPU不支持这两种技术中的一种的话,你的主机将无法装载KVM模块并将Linux内核转换成KVM的hypervisor。
在虚拟化的实践中,要想实现一款hypervisor,除了让hypervisor具有虚拟化CPU和内存的能力之外,还需要为其提供众多组件,比如内存管理器、进程调度取、IO栈、设备驱动、安全管理子系统、网络栈等等。所以从根本上来说,hypervisor就是一个完整的操作系统,只不过其主要目的是用来运行多个虚拟机,而非主要运行进程而已。hypervisor与Linux内核的区别仅在此处。所以说Xen本身就实现了一个操作系统应该具备的基本功能, 尤其是CPU、内存、中断处理的基本功能。Xen将IO的能力托付给“Dom0”来实现。而KVM是直接将自己寄宿在Linux内核上,并直接利用Linux内核中本身就提供了的内存管理、进程调度、IO栈、设备驱动、安全子系统等功能。KVM充分的利用Linux内核中的所有功能,自己仅负责虚拟化的功能。
KVM是怎么实现的呢?
kvm其实是一个Linux内核模块,如果kvm这个模块不被装载,那么当前的Linux就是一个Linux主机。
一旦向linux内核把kvm这个模块装载进来,那么整个内核就会成为hypervisor。它甚至于不用自己运行于硬件上,而仅仅是将内核转变成hypervisor。在其之上运行的用户空间转而就成为hypervisor控制台管理接口的运行位置。所以,在此之上就可以创建虚拟机了。只要利用kvm模块所提供的功能,我们就可以创建其他虚拟机。而这些创建出来的虚拟机就像直接运行在hypervisor上一样。这每一个虚拟机事实上就是运行在linux内核之上的进程。在原来的用户空间内,使用ps命令可以看到这些进程,要想关闭虚拟机,只要使用kill命令就能实现。
KVM模块载入后的系统的运行模式:
内核模式:GuestOS执行的I/O类操作,或其他的特殊指令的操作。称作“来宾-内核”模式
用户模式:代表GuestOS请求执行I/O类操作。
来宾模式:GuestOS的非I/O类操作;事实上,它被称作虚拟机的用户模式更贴切。它被称作“来宾-用户”模式。
kvm hypervisor:
用户空间的程序被调度至CPU上运行,当需要执行特权指令时,程序就会向内核发起系统调用,这个时候内核中的某些代码片段将会被装载到CPU上运行。执行完以后,这个代码片段将退场,并告诉调用者请求已完成,你可以继续向后执行。于是代码从中断处继续执行。
在虚拟机当中,某一个进程要想执行的话,它的指令是直接运行在CPU上的还是经由KVM Driver转换后执行?对于x86系列的CPU架构来说,如果支持HVM的话,它是从环-1到环3的,环-1是hypervisor运行的位置。它负责执行各种特权指令。环3上执行用户空间的指令。每一个虚拟机的CPU,其实是被转换成Linux内核上所运行的线程直接被调度至物理核心上运行。
当虚拟机中的应用程序被虚拟机的内核调度至虚拟CPU上运行,而这个虚拟CPU是映射到某个物理核心上的。如果说这个进程发起特权调用的话,就会触发一个软中断,这个软中断会发起系统调用,它的系统调用是发给虚拟机的内核,而虚拟机的内核也不能执行任何特权指令,所以它对于虚拟内核的调用最终还要被再次转换成由KVM Driver去负责响应特权指令的执行。所以,它的整个执行就变成这样:
app这个应用程序在执行非特权指令时就直接交给CPU运行。而对于特权指令的调用,先经由GuestOS Kernel,再转换为对VMM的调用,VMM可能仅仅在自己完成一种状态转换就告诉你OK了,VMM是在CPU上运行的,但VMM未必会允许这段代码在CPU上运行。VMM会假装告诉app这个指令完成了。
如果上层架构和底层物理架构不是同一种架构的话,这段代码即便是运行在用户空间的指令,它也得VMM转换以后在CPU上执行。如果是虚拟的话,即便是运行在虚拟机中的用户空间的指令,也一样可以直接在CPU上执行。所以说,如果在虚拟机中有大量的application运行的模式中,有百分之八十在用户空间,意味着百分之八十其实都在CPU上运行的。只有百分之二十是需要虚拟机转换以后再运行。
KVM的组件:
/dev/kvm:工作于hypervisor,在用户空间可通过直接发出ioctl()系统调用来完成VM创建、启动等管理功能。它是一个字符设备。其所能够实现的主要功能包括:创建VM、为VM分配内存、读写VCPU的寄存器、向VCPU注入中断、运行VCPU等等。
qemu进程:工作于用户空间,主要用于实现仿真PC机的IO设备。
KVM特性:
内存管理:
支持将分配给VM的内存交换至SWAP;
支持使用Huge Page;
支持使用Intel EPT或AMD RVI技术完成内存地址映射;GVA-->GPA-->HPA
支持KSM(Kernel Same-page Merging)
硬件支持:
取决于Linux内核;
存储:
支持使用本地存储;
支持网络附加存储;
支持使用存储区域网络;
支持分布式存储,例如GlusterFS
实时迁移:
支持的GuestOS:
Linux, Windows, OpenBSD, FreeBSD, OpenSolaris;
设备驱动:
IO设备的完全虚拟化:模拟硬件
IO设备的半虚拟化:在GuestOS中安装驱动:virtio
virtio-blk, virtio-net, virtio-pci, virtio-console, virtio-ballon
KVM局限性:
一般局限性:
CPU overcommit: 允许过载使用CPU,但过载能力有限,并不会提升性能。一般不建议所有虚拟机的CPU数量大于物理CPU的数量
时间记录难以精确,依赖于时间同步机制
VM量特别大时,MAC地址存在冲突的可能性;
KVM的工具栈:
qemu:
qemu-kvm
qemu-img
libvirt
GUI: virt-manager, virt-viewer
CLI: virt-install, virsh
virsh的本地模式与远程模式
安装KVM
(1) 确保CPU支持HVM
# grep -E --color=auto "(vmx|svm)" /proc/cpuinfo
(2) 装载模块
# modprobe kvm
# modprobe kvm-intel
(3) 验证:
ls /dev/kvm
管理工具栈:
# yum grouplist | grep -i "virtualiation"
Virtualization:
qemu-kvm
Virtualization Client
python-virtinst, virt-manager, virt-viewer
Virtualization Platform
libvirt, libvirt-client
Virtualization Tools
libguestfs
qemu-kvm使用:
# yum install qemu-kvm -y
# ln -sv /usr/libexec/qemu-kvm /usr/bin/
cirros project:为cloud环境测试vm提供的微缩版Linux;
cirros下载地址:http://download.cirros-cloud.net/
启动第一个虚拟:
# qemu-kvm -m 128 -smp 2 -name ”test“ -hda /images/kvm/cirros-0.3.4-i386-disk.img
测试:
安装vnc:
# yum install tigervnc -y
连接本机的vnc服务:
# vncviewer :5900 //如果启动多个虚拟机,那么端口号是5901,5902...
sudo su -
ctrl + alt +2 : 切换到监控接口, ctrl+alt+1再切换回去
help
info
info name
info status
ifconfig
关闭虚拟机:# kill 2949
用-drive指定磁盘映像文件:
# qemu-kvm -m 128 -name "test" -smp 2 -cpu host -drive file=/images/kvm/cirros-0.3.4-i386-disk.img,if=virtio,media=disk,cache=writeback,format=qcow2
测试:
vncviewer :5900
# sudo su -
# ls /sys/bus/virtio/devices/
virtio0
通过cdrom启动winxp的安装:
创建windows磁盘映像文件:# qemu-img create -o size=20G,preallocation=metadata -f qcow2 /images/kvm/winxp.img # qemu-kvm -name winxp -cpu host -smp 4,sockets=1,cores=2,threads=2 -m 512 -drive file=/images/kvm/winxp.img,
if=ide,media=disk,cache=writeback,format=qcow2 -drive file=/root/winxp_ghost.iso,media=cdrom -boot order=dc,once=d
指定使用桥接网络接口:
# qemu-kvm -m 128 -name test -smp 2 -drive file=/images/kvm/cirros-0.3.4-i386-disk.img,if=virtio,media=disk,cache=writeback,format=qcow2 -net nic
-net tap,script=/etc/if-up,downscript=no -nographic
指定以网络接口启动vm:
# qemu-img create /images/centos/centos6.img -o size=120G,preallocation=metadata -f qcow2
# qemu-kvm -m 512 -smp 2 -name centos -drive file=/images/centos/centos6.img,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:55:32:19
-net tap,ifname=centos6.0,script=/etc/qemu-ifup -boot order=nc,once=n
显示选项:
SDL: Simple DirectMedia Layer: C语言开发,跨平台且开源多媒体程序库文件;
在qemu中使用“-sdl”即可;
VNC: Virtual Network Computing,使用RFB(Remote FrameBuffer)协议远程控制另外的主机;
CentOS 6.6
(1)yum install tigervnc-server
(2)vncpasswd
(3)vncserver :N
qemu-kvm
-vnc display,option,option
示例: -vnc :N,password
启动qemu-kvm,额外使用-monitor stdio选项,并使用change vnc password命令设置密码;
补充资料:qemu-kum使用文档
使用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) 仿真设备(显卡、网卡、硬盘、鼠标等) 用于将仿真设备连接至主机设备(真实设备)的通用设备; 模拟机的描述信息; 调试器 与模拟器交互的用户接口 使用qemu-kvm安装Guest 基于libvirt的工具如virt-manager和virt-install提供了非常便捷的虚拟机管理接口,但它们事实上经二次开发后又封装了qemu-kvm的工具。因此,直接使用qemu-kvm命令也能够完成此前的任务。 qemu-kvm命令 在RHEL6上,qemu-kvm位于/usr/libexec目录中。由于此目录不属于PATH环境变量,故无法直接使用,这样也阻止了可以直接使用qemu作为创建并管理虚拟机。如若想使用qemu虚拟机,
可以通过将/usr/libexec/qemu-kvm链接为/usr/bin/qemu实现。 # ln -sv /usr/lib/exec/qemu-kvm /usr/bin/qemu-kvm qemu—kvm命令使用格式为"qemu-kvm [options] [disk_image]",其选项非常多,不过,大致可分为如下几类。 标准选项 USB选项 显示选项 i386平台专用选项 网络选项 字符设备选项 蓝牙相关选项 Linux系统引导专用选项 条数/专家模式选项 PowerPC专用选项 Sparc32专用选项 qemu-kvm的标准选项 qemu-kvm的标准选项主要涉及指定主机类型、CPU模式、NUMA、软驱设备、光驱设备及硬件设备等。 -name name: 设定虚拟机名称 -M machine: 指定要模拟的主机类型,如Standard PC、ISA-only PC或Intel-Mac等,可以使用“qemu-kvm -M ?”获取所支持的所有类型; -m megs: 设定虚拟机的RAM大小,单位为MB -cpu mode: 设定CPU模型,如coreduo、qemu64等,可以使用“qemu-kvm -cpu ?”获取所支持的所有模型 -smp n[,coes=cores][,threads=threads][,sockets=sockets][,maxcpus=maxcpus]:设定模拟的SMP架构中CPU的个数等、每个CPU的核心数及CPU的socket数目等;PC机上最多可以模拟255颗CPU;maxcpus用于指定热插入的CPU个数上限; -numa opts:指定模拟多节点numa设备 -fda file -fdb file:使用指定文件(file)作为软盘镜像,file为/dev/fd0表示使用物理软驱; -hda file -hdb file -hdc file -hdd file: 使用指定file作为硬盘镜像 -cdrom file: 使用指定file作为CD-ROM镜像,需要注意的是-cdrom和-hdc不能同时使用;将file指定为/dev/cdrom可以直接使用物理光驱 -drive option[,option[,option[,...]]]:定义一个硬盘设备;可用子选项有很多。 file=/path/to/somefile:硬盘映像文件路径 if=interface:指定硬盘设备所连接的接口类型,即控制器类型,如ide、scsi、sd、mtd、floppy、pflash及virtio等; index=index:设定同一种控制器类型中不同设备的索引号,即标识号 media=media:定义介质类型为硬盘(disk)还是光盘(cdrom) snapshot=snapshot:指定当前硬盘设备是否支持快照功能:on或of cache=cache:定义如何使用物理机缓存来访问块数据,其可用值有node、writeback、unsafe和writethrough四个 format=format:指定映像文件的格式,具体格式可参见qemu-img命令 -boot [order=drives][,once=dribes][,menu=on|off]:定义启动设备的引导次序。每种设备使用一个字符表示;不同的架构所支持的设备及其表示字符不尽相同,在x86 PC架构上,a、b表示软驱、c表示第一块硬盘,d表示第一个光驱设备,n-p表示网络适配器;默认为硬盘设备: -boot order=dc,once=d qemu-kvm的显示选项 显示选项用于定义虚拟机启动后的显示接口相关类型及其属性等。 -nographic:默认情况下,qemu使用SDL来显示VGA输出;而此选项用于禁止图形接口,此时,qemu类似一个简单的命令行程序,其仿真串口设备将被重定向至控制台。 -curses: 禁止图形接口,并使用curses/ncurses作为交互接口 -alt-grab: 使用Ctrl+Alt+Shift组合键释放鼠标 -ctrl-grab: 使用右Ctrl键释放鼠标 -sdl: 启用SDL,示例:# qemu-kvm -m 128 -cpu host -smp 2 -name "test" -drive file=cirros-no_cloud-0.3.0-i386-disk.img,if=virtio,media=disk,format=qcow2,cache=writeback -sdl -spice option[,option[,...]]:启用spice远程桌面协议;其有许多子选项,具体请参照qemu-kvm的手册 -vga type: 指定要仿真的VGA接口类型,常见类型有: cirrus: Cirrus Logic GD5446显示卡 std: 带有Bochs VBI扩展的标准VGA显示卡 vmware: VMWare SVGA-II兼容的显示适配器 qxl: QXL半虚拟化显示卡;与VGA兼容;在Guest中安装qxl驱动后能以很好的方式工作,在使用spice协议时推荐使用此类型 node: 禁用VGA卡 -vnc display[,option[,option[,...]]]:默认情况下,qemu使用SDL显示VGA输出;使用-vnc选项,可以让qemu监听在VNC上,并将VGA输出重定向至VNC会话;
使用此选项时,必须使用-k选项至此那个键盘布局类型;其有许多子选项,具体请参照qemu-kvm的手册; -vnc display: (1) host:N 172.16.100.7:1,监听于172.16.100.7主机的5900+N的端口上 (2) unix: /path/to/socket_file //只能用于127.0.0.1的通信 (3) none 示例:# qemu-kvm -m 128 -cpu host -smp 2 -name "test" -drive file=cirros-no_cloud-0.3.0-i386-disk.img,if=virtio,media=disk,format=qcow2,cache=writeback -vnc 172.16.100.67:0 //创建远程桌面号,便于远程连接 options: password: 连接时需要验证密码;设定密码通过monitor接口使用change reverse: “反向”连接至某处于监听状态的vncview上 -monitor stdio: 表示在标准输出上显示monitor界面 -nographic Ctrl-a, c: 在console和monitor之间切换 Ctrl-a, h: 显示帮助信息 示例:# qemu-kvm -m 128 -cpu host -smp 2 -name "test" -drive file=cirros-no_cloud-0.3.0-i386-disk.img,if=virtio,media=disk,format=qcow2,cache=writeback -vnc 172.16.100.67:0,password -monitor stdio monitor中设置vnc密码:# change vnc password,远程连接时输入密码即可登录 i386平台专用选项 -no-acpi:禁用ACPI功能,GuestOS与ACPI出现兼容问题时使用此选项 -balloon none:禁用balloon设备 -balloon virtio[,addr=addr]: 启用virtio balloon设备 网络属性相关选项 网络属性相关选项用于定义网络设备接口类型及其相关的各属性等信息。这里只介绍nic、tap和user三种类型网络接口的属性,其它类型请参照qemu-kvm手册。 -net nic[,vlan=n][,macaddr=mac][,model=type][,name=name][,addr=addr][,vectors=v]: 创建一个新的网卡设备并连接至vlan n中;PC架构上默认的NIC为e1000, macaddr用于为其指定的MAC地址,name用于指定一个在监控时显示的网卡设备名称;qemu可以模拟多个类型的网卡设备,如virtio、i82551、i82557b、i82559er、ne2k_isa、pcnet、 rtl8139、e1000、smc91c111、lance及mcf_fec等;不过,不同平台架构上,其支持的类型可能只包含前述列表的一部分,可以使用"qemu-kvm -net nic,model=?"来获取当前平台支持的类型; 注意:默认的mac地址均为52:54:00:12:34:56,使用中需要手动指定。 -net tap[,vlan=n][,name=name][,fd=h][,ifname=name][,script=file][,downscript=dfile]: 通过物理机的TAP网络接口连接至vlan n中,使用script=file指定的脚本(默认为/etc/qemu-ifup)来配置当前网络接口,并使用downscript=file指定的脚本(默认为/etc/qemu-ifdown)来撤销接口配置;使用script=no和downscript=no可分别用来禁止执行脚本; -net user[,option][,option][,...]: 在用户模式配置网络栈,其不依赖于管理权限;有效选项有: vlan=n: 连接至vlan n,默认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;如:qemu -hda linux.img -boot n -net user,tftp=/tftpserver/pub,bootfile=/pxelinux.0
网络模型:
隔离模型:
激活tap,并将其加入到指定的bridge
路由模型:
激活tap,并将其加入到指定的bridge
额外:给虚拟的bridge添加地址,打开核心转发
nat模型:
激活tap,并将其加入到指定的bridge
额外:打开核心转发,并添加nat规则
桥接模型:
激活tap,并将其加入到指定的bridge
隔离模型示例:
# qemu-kvm -m 128 -name test -smp 2 -drive file=/images/kvm/cirros-0.3.4-i386-disk.img,if=virtio,media=disk,cache=writeback,format=qcow2 -net nic,macaddr=52:54:00:12:34:57
-net tap,ifname=vif0.0,script=/etc/qemu-ifup
# qemu-kvm -m 128 -name test1 -smp 2 -drive file=/images/kvm/cirros-0.3.4-i386-disk.img,if=virtio,media=disk,cache=writeback,format=qcow2 -net nic
-net tap,ifname=vif1.0,script=/etc/qemu-ifup
# brctl show
这时候如果两个虚拟机是同一网段的IP地址,那么它们就能互相通信,这就是隔离模型的虚拟机网络。
nat模型示例:
物理机添加虚拟网卡:
# ip link add veth1.0 type veth peer veth1.1
# ip link set veth0 up //激活虚拟网卡
# ip link set veth1.0 up
# brctl addif br0 veth1.0
# brctl show
添加iptables规则:
# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 ! -d 192.168.2.0/24 -o eno16777736 -j SNAT --to-source 172.16.100.67
# tcpdump -i eno1677736 -nn icmp
桥接模型示例:
# ip addr del 172.16.100.67/16 dev eno16777736 # brctl addif br0 eno16777736 # ip addr add 172.16.100.67/16 dev br0
这时虚拟机和物理机IP地址在同一个网段就可以通信。
# cat /etc/qemu-ifup
#!/bin/bash
#
bridge=br0
if [ -n "$1" ]; then
ip link set $1 up
sleep 1
brcrl addif $bridge $1
[ $? -eq 0] && exit 0 || exit 1
else
echo "Error: no interface specified."
exit 1
fi
# cat /etc/qemu-ifdown
#!/bin/bash
#
bridge=br0
if [ -n "$1" ]; then
brctl delif $bridge $1
ip link set $1 down
exit 0
else
echo "Error: no interface specified."
exit 1
fi
一个使用示例:
下面的命令创建了一个名为rhel5.8的虚拟机,其RAM大小为512MB,有两颗CPU的SMP架构,默认引导设备为硬盘,有一个硬盘设备和一个光驱设备,网络接口类型为virtio,VGA模式为cirrus,并启用了balloon功能。
# qemu-kvm -name "rhel5.8" -m 512 -smp 2 -boot d -drive file=/VM/images/rhel5.8/hda,if=virtio,index=0,media=disk,format=qcow2
-drive file=/isos/rhel-5.8.iso,index=1,media=cdrom -net nic,model=virtio,macaddr=52:54:00:A5:41:1E -vga cirrus -balloon virtio
需要注意的是,上述命令中使用的硬盘映像文件/VM/images/rhel5.8/hda需要事先使用qemu-img命令创建
# qemu-img create -f qcow2 /VM/images/rhel5.8/hda 120G
在虚拟机创建并安装GuestOS完成之后,可以免去光驱设备直接启动之。命令如下所示:
# qemu-kvm -name "rhel5.8" -m 512 -smp 2 -boot d
-drive file=/VM/images/rhel5.8/hda,if=virtio,index=0,media=disk,format=qcow2 -net nic,model=virtio,macaddr=52:54:00:A5:41:1E -vga cirrus -balloon virtio
使用qemu-img管理磁盘映像
qemu-img是qemu用来实现磁盘映像管理的工具组件,其有许多子命令,分别用于实现不同的管理功能,而每一个子命令也都有一系列不同的线性。其使用的语法格式为”qemu-img subcommand [options]“。支持的子命令如下:
create: 创建一个新的磁盘映像文件
check: 检查磁盘映像文件中的错误
convert: 转换磁盘映像的格式
info: 显示指定磁盘映像的信息
snapshot:提交磁盘映像的所有改变
rbase: 基于某磁盘映像创建新的磁盘文件
resize: 增大或缩减磁盘映像文件的大小
使用create子命令创建磁盘映像的命令格式为”create [-f fmt] [-o options] filename [size]“.例如下面的命令创建了一个格式为qcow2的120G的稀疏磁盘映像文件。
# qemu-img create -f qcow2 /VM/images/rhel5.8/hda 120G
KVM中的半虚拟化设备:virtio
为了不能让每一个模拟的IO设备直接对应物理机的网卡设备,我们只能在物理机上为每一个虚拟机上的网卡设备提供一个对应的虚拟网卡,中间需要有一个层次让二者完成对接,所以,虚拟机的网卡对应的是中间的虚拟化层,虚拟机的网卡称为前端,物理机的虚拟网卡称为后端,虚拟机中的报文要想发送出去,需要经过自己的前端,再经过虚拟化层,再送给后端,后端跟物理网卡进行交互,打开核心转发功能,才能将报文发送出去。这样的性能肯定会很差,这是模拟的技术实现。
要想加速这个过程,可以使用半虚拟化技术。
如果是linux系统的话,一般Xen和KVM都能支持直接使用半虚拟技术。xen中的半虚拟化设备是前端、后端;kvm中的半虚拟化设备是virtio。
KVM半虚拟化
I/O半虚拟化分成两段:
前端驱动(virtio前半段): virtio-blk, virtio-net, virtio-pci, virtio-balloon, virtio-console
Linux: CentOS 4.8++, 5.3+, 6.0+. 7.0+
Windows:
virtio: 虚拟队列,virt_ring
transport: 传输层
后端处理程序(virt backend drivers): 在QEMU中实现;
virtio-balloon:
ballooning: 让VM运行的GuestOS中动态调整其内存大小
# qemu-kvm -balloon virtio
手动查看GuestOS的内存用量:
# info balloon
# balloon N
virtio-net:
其依赖于GuestOS中的驱动,及Qemu中的后端驱动
GuestOS: virtio_net.ko
# qemu-kvm -net nic,model=?
# qemu-kvm -net nic,model=virtio
Host中的GSO, TSO
关掉可能会提升性能:
ethtool -K $IF gso off
ethtool -K $IF tso off
ethtool -k $IF
vhost-net: 用于取代工作于用户空间的qemu中为virtio-net实现的后端驱动以实现性能提升的驱动;
-net tap[,vnet_hdr=on|off][,vhost=on|off]
# qemu-kvm -net tap,vnet_hdr=on,vhost=on
virtio-blk:
其依赖于GuestOS中的驱动,及Qemu中的后端驱动
-drive file=/path/to/some_image_file,if=virtio
kvm_clock:半虚拟化的时钟
# grep -i "paravirt" /boot/config-2.6.32-504.el6.x86_64
CONFIG_PARAVIRT_GUEST=y
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_CLOCK=y
VM Migration:
static migration
live migration
整体迁移时间
服务器停机时间
对服务的性能的影响
在待迁入主机使用
# qemu-kvm -vnc :N -incoming tcp:0:7777
# vncviewer :590N
在源主机使用:
monitor接口:
# migrate tcp:DEST_IP:DEST_PORT
libvrit工具栈
支持的虚拟化技术: KVM,XEN,LXC,WMWARE, Qemu, OpenVZ;
libvirt中的术语:
node: 指物理节点
hypervisor:
domain: vm instances
安装:
Centos 6: # yum install libvirt libvirt-client python-virtinst virt-manager
Centos 7: # yum install libvirt libvirt-client virt-install virt-manager
# yum install qemu-kvm virt-viewer
启动libvirtd服务:
# systemctl start libvirtd.service
libvirt和libvirtd的配置文件:
libvirt配置文件:/etc/libvirt/libvirt.conf
守护进程配置文件:/etc/libvirt/libvirtd.conf
域配置文件:xml格式
<vcpu placement=‘static‘>2</vcpu>
<features>
</features>
<domain>
</domain>
Hypervisor的访问路径:
本地URL: driver[+transport]:///[path][?extral-param] driver: 驱动名称,例如qemu, xen,lxc transport: 传输方式 kvm使用qemu驱动,使用格式qemu:///system, 例如qemu:///system 远程URL: driver[+transport]:///[user@][host][:port]/[path][?extral-param] 例如:
qemu:///172.16.100.6/system qemu+ssh://root@172.16.100.6/system qemu+tcp://172.16.100.6/system
补充资料:virt-install使用文档
使用virt-install创建虚拟机并安装GuestOS
virt-install是一个命令行工具,它能够为KVM、Xen或其他支持libvirt API的hypervisor创建虚拟机并完成GuestOS安装;此外,它能够基于串行控制台、VNC或SDL支持文本或图形安装界面。 安装过程可以使用本地的安装介质如CDROM,也可以通过网络方式如NFS、HTTP或FTP服务实现。对于通过网络安装的方式,virt-install可以自动加载必要的文件以启动安装过程而无须额外提供引导工具。 当然,virt-install也支持PXE方式的安装过程,也能够直接使用现有的磁盘映像直接启动安装过程。 virt-install命令有许多选项,这些选项大体可分为下面几大类,同时对每类中的常见选项也做成简单说明。 一般选项:指定虚拟机的名称、内存大小、VCPU个数及特性等; -n NAME, --nama=NAME: 虚拟机名称,需全局唯一; -r MEMORY, --ram=MEMORY: 虚拟机内存大小,单位为MB; --vcpus=VCPUS[,maxvcpus=MAX][,sockets=#][,cores=#][,threads=#]:VCPU个数及相关配置; --cpu=CPU:CPU模式及特性,如coreduo等;可以使用“qemu-kvm -cpu ?”来获取支持的cpu模式; 安装方法:指定安装方法、GuestOS类型等: -c CDROM, --cdrom=CDROM: 光盘安装介质; -l LOCATION,--location=LOCATION:安装源URL,支持FTP、HTTP及NFS等,如ftp://172.16.0.1/pub或http://172.16.100.6/cobbler/ks_mirror/CentOS-7-x86_64; --pxe:基于PXE完成安装; --livecd: 把光盘当做LiveCD; --os-type=DISTRO_TYPE:操作系统类型,如linux、unix或windows等; --os-variant-DISTRO_VARIANT:某类型操作系统的变体,如rhel5、fedora8等; -x EXTRA,--extra-args=EXTRA:根据--location指定的方式安装GuestOS时,用于传递给内核的额外选项,例如指定kickstart文件的位置,--extra-args "ks=http://172.16.0.1/class.cfg" -boot=BOOTOPTS: 指定安装过程完成后的配置选项,如指定引导设备次序、使用指定的而非安装的kernel/initrd来引导系统启动等;例如 --boot cdrom,hd,network:指定引导次序; --boot kernel=KERNEL,initrd=INITRD,kernel_args="console=/dev/ttyS0": 指定启动系统的内核及initrd文件; 存储配置:指定存储类型、位置及属性等; --disk=DISKOPTS: 指定存储设备及其属性:格式为--disk /some/storage/path,opt1=val1, opt2=val2等;常用的选项有: device: 设备类型,如cdrom、disk或floppy等,默认为disk; bus: 磁盘总线类型,其值可以为ide、scsi、usb、virtio或xen; perms: 访问权限,如rw、ro或sh(共享的可读写),默认为rw; size: 新建磁盘映像的大小,单位为GB; cache:缓存模型,其值有none、writethrough(缓存读)及writeback(缓存读写); format: 磁盘映像格式,如raw、qcow2、vmdk等; sparse: 磁盘映像使用稀疏格式,即不立即分配指定大小的空间; --nodisks: 不使用本地磁盘,在LiveCD模式中常用;
网络配置:指定网络接口的网络类型及接口属性如MAC地址、驱动模式等; -w NETWORK,--network=NETWORK,opt1=val1,opt2=val2: 将虚拟机连入宿主机的网络中,其中NETWORK可以为: bridge=BRIDGE:连接至名为“BRIDGE”的桥设备; network=NAME:连接至名为“NAME”的网络; 其他常用的选项还有: model: GuestOS中看到的网络设备型号,如e1000、rtl8139或virtio等; mac: 固定的MAC地址;省略此选项时将使用随机地址,但无论何种方式,对于KVM来说,其前三段必须为52:54:00; --nonetworks: 虚拟机不使用网络功能
图形配置: 定义虚拟机显示功能相关的配置,如VNC相关配置; --graphics TYPE,opt1=val1,opt2=val2: 指定图形显示相关的配置,此选项不会配置任何显示硬件(如显卡),而是仅指定虚拟机启动后对其进行访问的接口; TYPE: 指定显示类型,可以为vnc、sdl、spice或none等,默认为vnc; port: TYPE为vnc或spice时其监听的端口; listen:TYPE为vnc或spice时所监听的IP地址,默认为127.0。0.1,可以通过修改/etc/libvirt/qemu.conf定义新的默认值; password: TYPE为vnc或spice时,为远程访问监听的服务指定认证密码; --noautoconsole: 禁止自动连接至虚拟机的控制台;
设备选项:指定文本控制台、声音设备、串行接口、并行接口、显示接口等; --serial=CHAROPTS:附加一个串行设备至当前虚拟机,根据设备类型的不同,可以使用不同的选项,格式为“--serial type,opt1=val1,opt2=val2,...”,例如: --serial pty: 创建伪终端; --serial dev,path=HOSTPATH: 附加主机设备至此虚拟机; --video=VIDEO:指定显卡设备模型,可用取值为cirrus、vga、qxl或vmvga; 虚拟化平台:虚拟化模型(hvm或paravirt)、模拟的CPU平台类型、模拟的主机类型、hypervisor类型(如kvm、xen或qemu等)以及当前虚拟机的UUID等; -v, --hvm:当物理机同时支持完全虚拟化和半虚拟化时,指定使用完全虚拟化; -p, --paravirt: 指定使用半虚拟化; --virt-type: 使用的hypervisor,如kvm、qemu、xen等;所有可用值可以使用’virsh capabilities‘命令获取;
其他: --autostart: 指定虚拟机是否在物理启动后自动启动; --print-xml: 如果虚拟机不需要安装过程(--import、--boot),则显示生成的XML而不是创建次虚拟机;默认情况下,此选项仍会创建磁盘映像; --force: 禁止命令进入交互式模式,如果有需要回答yes或no选项,则自动回答为yes; --dry-run: 指定创建虚拟机的整个过程,但不真正创建虚拟机、改变主机上的设备配置信息及将其创建的需求通知给libvirt; -d, --debug:显示debug信息; 尽管virt-install命令有着类似上述的众多选项,但实际使用中,其必须提供的选项仅包括--name、--ram、--disk(也可是--nodisks)及安装过程相关的选项。 此外,有时还需要使用--connect=CONNECT选项来指定连接至一个非默认的hypervisor。
补充资料:nat模型网络脚本示例:
# cat /etc/qemu-natup
#!/bin/bash
#
bridge="isbr"
net="10.0.0.0/8"
ifaddr=10.0.10.1
checkbr(){
if brctl show | grep -i "^$1"; then
return 0
else
return 1
fi
}
initbr() {
brctl addbr $bridge
ip link set $bridge up
ip addr add $ifaddr dev $bridge
}
enable_ip_forward() {
sysctl -w net.ipv4.ip_forward=1
}
setup_nat() {
checkbr $bridge
if [ $? -eq 1 ]; then
initbr
enable_ip_forward
iptables -t nat -A POSTROUTING -s $net ! -d $net -j MASQUERADE
fi
}
if [ -n "$1" ]; then
setup_nat
ip link set $1 up
brctl addif $bridge $1
exit 0
else
echo "Error: no interface specified."
exit 1
fi
# cat /etc/qemu-natdown
#!/bin/bash
#
bridge="isbr"
remove_rule() {
iptables -t nat -D -F
}
isalone_bridge() {
if ! brctl show | awk "/^$bridge/{print \$4}" | grep "[^[:space:]]" &> /dev/null; then
ip link set $bridge down
brctl delbr $bridge
remove_rule
fi
}
if [ -n "$1" ]; then
ip link set $1 down
brctl delif $bridge $1
isalone_bridge
exit 0
else
echo "Error: no interface specified."
exit 1
fi
使用示例:
(1)# virt-install -n "centos6" -r 512 --vcpus=2 -l http://172.16.0.1/cobbler/ks_mirror/CentOS-6.6-x86_64/ -x "ks=http://172.16.0.1/centos6.x86_64.cfg"
--disk=/images/kvm/centos6.img,size=120,sparse --force -w bridge=br100,model=virtio
(2) 下面这个示例创建一个名为rhel5的虚拟机,其hypervisor为KVM,内存大小为512MB,磁盘为8G的映像文件/varlib/libvirt/images/rhel5.8.img,通过boot.iso光盘镜像来引导启动安装过程。
# virt-install --connect qemu:///system --virt-type kvm --name rhel5 --ram 512 --disk path=/var/lib/libvirt/images/rhel5.img,size=8 --graphics vnc --cdrom /tmp/boot.iso --os-variant rhel5
(3) 下面的示例将创建一个名为rhel6的虚拟机,其有两个虚拟CPU,安装方法为FTP,并制定了ks文件的位置,磁盘映像文件为稀疏格式,连接至物理主机上的名为brnet0的桥接网络;
# virt-install --connect qemu:///system --virt-type kvm --name rhel6 --ram 1024 --vcpus 2 --network bridge=brnet0 --disk path=/VMs/images/rhel6.img,size=120,sparse --location ftp://172.16.0.1/rhel6/dvd -os-variant rhel6 --force
(4) 下面的示例将创建一个名为rhel5.8的虚拟机,磁盘映像文件为系数模式的格式为qcow2且总线类型为virtio,安装过程不启动图形界面(--nographics),但会启动一个串行终端将安装过程以字符形式显示在当前文本模式下,
虚拟机显卡类型为cirrus;
# virt-install --connect qemu:///system --virt-type kvm --name rhel5.8 --vcpus 2,maxvcpus=4 --ram 512 --disk path=/VMs/images/rhel5.8.img,size=120,format=qcow2,bus=virtio,sparse --network bridge=brnet0,model=virtio
--nographics --location ftp://172.16.0.1/pub --extra-args "ks=http://172.16.0.1/class.cfg console=ttyS0 serial" --os-variant rhel5 --force --video=cirrus
(5) 下面的示例则利用已经存在的磁盘映像文件(已经安装好的系统)创建一个名为rhel5.8的虚拟机;
# virt-install --name rhel5.8
--ram 512
--disk /VMs/rhel5.8.img
--import
注意: 每个虚拟机创建后,其配置信息保存在/etc/libvirt/qemu目录中,文件名与虚拟机相同,格式为XML.
(6) # virt-install -n cirros -r 128 --vcpus=1,maxvcpus=4 --disk /images/cirros/cirros-no_cloud-0.3.0-i386-disk.img --network bridge=br0,model=virtio --import
--serial=pty --console=pty --nographics
测试:
显示所有虚拟机: # virsh list
连接虚拟机: # virsh console 15
切换: Ctrl + ]
删除域: # virsh destroy 8
删除关联的存储卷: # virsh undefine centos6.7 --remore-all-storage
不删除映像文件: # virsh undefine centos6.7
给虚拟机添加磁盘:
# qemu-img create -f qcow2 -o size=20G,preallocation=metadata /images/cirros/second.qcow2
# qemu-img info /images/cirros/second.qcow2
# virsh help attach-disk
# virsh attach-disk 15 /images/cirros/second.qcow2 vda --targetbus virtio
虚拟机拆除磁盘:
# virsh detach disk 15 vda
虚拟机添加网卡并附加在virbr0桥上:
# virsh help attach-interface
# virsh attach-interface 15 bridge virbr0
虚拟机拆除网卡:
# virsh detach-interface 15 bridge --mac 52:54:00:E5:C1:B7
virsh其他命令选项:# virsh help
virt-install:创建虚拟机,并安装OS;也可创建虚拟机并导入Image文件;
根据xml文件创建:
create: 创建并启动
define: 创建但不启动
关闭domain:
destroy
shutdown
reboot
删除domain:
undefine
连接至console:
console
列出所有的虚拟机:
list
附加或拆除disk:
attach-disk
detach-disk
附加或拆除网卡:
attach-interface
detach-interface
保存状态至磁盘文件或磁盘文件恢复:
save
restore
暂停于内存或继续运行:
suspend
resume
查看cirros的xml文件:
# virsh dumpxml cirros
cpu亲缘性:cpupin
# virsh vcpucount 15
# virsh vcpuinfo 15
# virsh help vcpupin
添加vcpu个数:
# virsh setvcpus 15 2
# virsh vcpucount 15
Host 和 Hypervisor:
sysinfo, uri, connect, nodeinfo, version
网络接口:
iface-list, iface-bridge
创建桥设备并将物理网卡附加在桥上: # virsh iface-bridge eno16777736 br0 --no-stp
virt-manager: GUI工具
KVM管理工具:
http://www.linux-kvm.org/page/Management_Tools
ovirt、OpenStack、openQRM、CloudStack
原文:https://www.cnblogs.com/ckh2014/p/14612452.html