KVM虚拟化
KVM虚拟化基础
虚拟化技术两种实现
Type-I
hypervisor ---> vm
Xen、RHEV、ESXi
Type-II
host vmm ---> vms
KVM、VMware Workstation、Virtual Box
依赖底层操作系统
Kernel-based Virtual Machine
It's linux kernel module
if load this module , the kernel changed to hypervisor
他没有访问硬件IO的能力,只能将请求交往用户空间进程,用户空间进程在将发出系统调用,内核处理完才将信息返回
guest user program ---> guest OS kernel ---> host user program (qume) ---> host kernel ---> IO hardware
依赖于底层虚拟化指令集
Intel VT-x, AMD AMD-V;
直接使用使用系统的
安全子系统、网络协议栈、硬件IO功能 ...
KVM模块载入后系统的运行模式
内核模式
GuestOS执行I/O类操作,或其他特殊的指令
用户模式
代表guestOS请求IO类操作
来宾模式
运行虚拟机中的进程
kvm hypervisor
KVM组件
/dev/kvm
工作在内核空间,在用户空间,可通过ioctl()系统调用来完成VM创建、启动、管理虚拟机功能
它是一个字符设备
创建VM、为VM分配内存、读写VCPU的寄存器、向VCPU注入中断、运行VCPU等等
qemu进程
工作于用户空间,主要用于实现模拟PC的IO设备
KVM特性
内存管理
将分配给VM的内存交换至SWAP
支持使用Huge Page
支持使用Intel EPT或AMD RVI技术完成内存地址映射
GVA ---> GPA ---> HPA
GVA ---> HPA (EPT、RVI技术)
支持KSM (Kernel Same-page Merging)
硬件支持
取决于Linux内核
存储
DAS
NAS
SAN
Redistribute Storage (GlustFS)
实时迁移
支持
支持的GuestOS
Linux
Window
FreeBSD
OpenBSD
OpenSolaris
设备驱动
IO设备的完全虚拟化 模拟硬件
IO设备的半虚拟化 在GuestOS中安装驱动 in DOM0
virtio
virtio-blk 块设备虚拟化
virtio-net 网络设备的虚拟化
virtio-pci pci虚拟化
virtio-console 控制台虚拟化
virtio-ballon 内存空间动态扩展或缩进的虚拟化
KVM局限性
一般局限性
overcommit
单台物理机节点上的虚拟机使用核心数最好不要超过物理机上的核心数
因为CPU被分割给虚拟机独享占用,导致系统时间总是不太精确(根据CPUHz,机器周期决定)
vmtool 能同步系统时钟和虚拟机时钟
MAC地址
VM数量特别大时,存在冲突的可能性
实时迁移限制
如果使用本地磁盘当做虚拟机磁盘,那么就不能实时迁移虚拟机
两台物理机的时间必须同步
两台物理主机必须有相同的网络配置
性能局限性
全虚拟化技术对于CPU、网络IO、磁盘IO、GPU损耗最大
半虚拟技术对于、、、损耗次与全虚拟化
透传、、、损耗最低
KVM管理工具栈
Qemu qemu-kvm 通过/dev/kvm api调用,创建、开启、管理虚拟机 qemu-img 管理虚拟机磁盘镜像 qemu-io 管理磁盘IO、网络IO libvirt GUI Virtual Machine Manager virt-manager GUI方式创建、安装管理虚拟机 virt-viewer 登录查看管理虚拟机 CLI virtinst virt-install 存命令行模式下,完成虚拟机的创建、安装 virsh 命令行管理工具,能管理整个虚拟机生命周期,需要xmi文件 virt-image 对镜像进行管理的 virt-convent 转换技术,调用qemu-img实现 virt-clone
QEMU简介
qemu是一个广泛使用的开源计算机仿真器和虚拟机。当作为仿真器时,可以在一种架构上(如PC机)下运行另一种架构(如ARM)下的操作系统和程序
而通过动态转化,其可以获得很高的运行效率。当作为一个虚拟机时,qemu可以通过直接使用真机的系统资源,让虚拟机系统能够获得接近于物理机的性能表现
qemu支持xen或kvm模式下的虚拟化。当用kvm时,qemu可以虚拟x86、服务器和嵌入式powerpc,以及s390的系统
qemu当运行与主机架构相同的目标架构时可以使用KVM。例如,当在一个x86兼容处理器上运行qemu-system-x86时,可以利用KVM加速,为宿主机和客户机提供更好的性能
QEMU主要提供了以下几个部分
处理器模拟器
仿真IO设备
关联模拟的设备至真实的设备
调试器
与模拟器交互的用户接口
PowerPC专用选项
Sparc32专用选项
启用KVM虚拟化
grep -E --colors=auto "(vmx|svm)" /proc/cpuinfo # 如果有显示,则表示支持硬件虚拟化 # 装载内核模块 modprobe kvm modprobe kvm-intel lsmod modinfo kvm ls /dev/kvm # 如存在模块说明,kernel已经被kvm寄居成为hypervisor # 安装虚拟化管理工具 yum grouplist | grep -i "virtualization" virtualization 提供qemu-kvm virtualization Client python-virtinst virt-manager virt-viewer virtualization Platform libvirt libvirt-client virtualization Tool libguestfs
VMM
对IO的驱动有三种模式
自主VMM:VMM自行提供驱动和控制台
混合VMM:借助于OS提供驱动
依赖于外部OS实现权威
自我提供权威
寄宿式VMM
IO虚拟化模型
模拟
半虚拟化
透传
查看系统信息
lspci ls /sys/block ls /sys/bus/ ls /sys/bus/virtio/devices
管理KVM虚拟机
qemu-kvm使用
安装
1 yum install -y qemu-kvm
核心工具
# 不依赖管理员权限也能使用,需要使用-net user
/usr/libexec/qemu-kvm
链接
ln -sv /usr/libexec/qemu-kvm /usr/bin
官方文档
https://qemu.weilnetz.de/doc/qemu-doc.html
使用格式
# usage: qemu-kvm [options] [disk_image]
qemu-kvm标准选项
-name name 设定虚拟机名称 -M machine 指定要模拟的主机类型 如Standard PC、ISA-only PC或Inter-Mac等,可以使用“qemu-kvm -M ?”获取所支持的所有类型 -m megs 设定虚拟机的内存大小M -cpu model 设定CPU类型 如coreduo、qemu64等,可以使用“qemu-kvm -cpu ?” -smp n[,cores=cores][,threads=threads][,sockets=sockets][,maxcpus=maxcpus] 设定模拟的SMP架构中CPU的个数、每个CPU的核心数以及CPU的socket数目等 PC机上最多可以模拟255颗CPU maxcpus用于指定热插入的CPU个数上限 n = core * thread * socket -numa opts 指定模拟多节点的numa设备 非一致内存访问: -fda file -fdb file 使用指定文件file作为软盘镜像,file为/dev/fd0表示使用物理软驱 -hda file -hdb file -hdc file -hdd file -cdrom file 使用指定file作为CD-ROM镜像 注意-cdrom不能和-hdc同时使用 将file指定为/dev/cdrom可以直接使用物理光驱 -drive option[,option[,option]] 定义一个硬盘设备 file=/path/to/somefile 硬盘映像文件路径 if=interface 指定硬盘设备所链接的接口类型 如ide、scsi、sd、mtu、floppy、pflash及virtio等 index=index 设定同一种控制器类型中不同设备的索引号,即标识号 media=media 定义介质类型为硬盘(disk)或光盘(cdrom) snapshot=snapshot writethrough 在缓存中写完数据,立即在内存中刷新数据 writeback 在缓存中写玩数据,不立即同步好缓存,但缓存中更该一定量的数据后,在一并写到内存 unsaf 性能最好 none 不打开缓存功能 format=format 指定映像文件的格式 具体格式可参见qemu-img命令 -boot [order=drives][,once=drives][,menu=no|off] 定义启动设备的引导次序 每种设备使用一个字符表示:不同的架构所支持的设备及其表示字符不尽相同 在x86架构上,a、b表示软驱、c表示第一块硬盘、d表示第一个光驱设备,n-p表示网络适配器,默认为硬盘设备 -boot order=dc,once=d
qemu-kvm显示选项
# 显示选项用于定义虚拟机启动后的显示接口相关类型及属性等 SDL C语言开发,跨平台且开源多媒体程序库文件,提供图形化界面底层库文件 在qemu中使用"-sdl"调用即可,当然操作系统需要先装上sdl的相关显示库 -curses 禁止图形化接口,并使用curses/ncurses作为交互接口 -alt-grab 使用Ctrl + Alt + Shift组合释放鼠标 -sdl 启动SDL -spice option[,option[,...]] 启用spice远程桌面协议,其有许多子选项。 -vga type 指定要仿真的VGA接口类型 # 常见类型 cirrus Cirrus Logic GD5446显示卡 std 带有Bochs VBI扩展的标准VGA显示器卡 vmware VMware SVGA-II兼容的显示适配器 qxl QXL半虚拟化显示卡,在使用spice协议时推荐使用次类型 none 禁用VGA卡 -vnc display[,option[,...]] 默认情况下,qemu使用SDL显示VGA输出 使用VNC选项,可以让qemu监听在VNC上,并将VNC输出重定向至VNC回话 使用VNC选项,必须使用 -k 选项指定键盘布局类型 显示方式 1. host: N 监听于xxxx:5900+N的端口上 2. unix:/path/to/socket_file 3. none options password 连接时需要验证密码密码,设定密码通过monitor接口使用change reverse “反向”连接至某处监听状态的vncviewer上 -monitor stdio 表示在标准输入输出上显示monitor界面 -nographic 默认情况下,qemu使用SDL来显示VGA输出,而此选项用于禁用图形接口,此时qemu类似一个简单的命令行程序,其仿真串口设备将被重定向到控制台 使用Ctrl + ac 在Console和Monitor之间切换 Ctrl + ah 显示帮助信息 设置VNC密码 change vnc password
qemu-kvm网络属性选项
参数使用
-net nic[,vlan=n][,macaddr=mac][,model=type][,name=name][,addr=addr][,vectors=v] 创建一个新的网卡设备并连接至vlan中,PC架构上默认的NIC为e1000,macaddr用于为其指定MAC地址 ,name用于指定一个在监控时显示的网上设备名称,qemu可以模拟多个类型的网卡设备,如 ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio,smc91c111,lance及mcf_fec等 不过,不同的平台架构上,其支持的类型可能只包含前述列表的一部分,可以使用命令来获取当前平台支持的类型 qemu-kvm -net nic,model=? -net tap[,vlan][,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可分别用来禁止执行脚本 vim /etc/qemu-ifup #! /bin/bash # bridge=br0 if [ -n "$1" ];then ip link set $1 up sleep 1 brctl addif $bridge $1 [ $? -eq 0 ] && exit 0 || exit 1 else echo "Error: no interface scpecified." exit 1 fi # ifdown是自动实现的,可以不用写 vim /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 scpecified." exit 1 fi -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
Nat网络模式脚本文件
KVM网络模型
隔离模型 只允许虚拟机之间相互通信 各虚拟机之间通过虚拟网桥实现通信 实现 1. 创建虚拟网桥 2. 虚拟机的tap设备都添加到虚拟网桥上 路由模型 各位虚拟机网关指向物理网卡虚拟的出来的虚拟网卡,并且该虚拟网卡连接虚拟网桥 物理主机打开核心转发功能 实现 1. 虚拟机的tap设备都添加到虚拟网桥上 2. 在虚拟机里配置默认网关,指向物理网卡 NAT模型 在物理主机开启nat功能,内部虚拟机访问外网时,转换成物理主机上的外网接口地址去访问公网 需要添加定义netfilter规则 实现 1. 虚拟机的tap设备都添加到虚拟网桥上 2. 虚拟网桥上配置虚拟机的网关 3. 在POSTROUTING上配置SNAT 桥接模式 物理网卡被虚拟成网桥设备,开启混杂模式,监听所有mac地址 真实的物理网卡被虚拟成一块虚拟网卡,该虚拟网卡使用原物理网卡上的mac地址 网络包进来后,再根据mac地址转发 实现 1. 虚拟机的tap设备都添加到虚拟网桥上 2. 虚拟网桥开启混杂模式监听网络中所有的流量 ip link set dev br0 promisc on ip addr del x.x.x.x dev ens33; brctl addif br0 ens33; ip addr add x.x.x.x/x dev br0
管理桥设备
yum list all | grep -i bridge modinfo bridge # nmtui图形化管理网桥 brctl addbr br0 brctl stp br0 off # 激活网桥 ip link set dev br0 down brctl add brctl show brctl delbr br0
管理网卡对
ip link add veth1.0 type veth peer veth1.1
ip link set veth1.0 up
ip link set veth1.1 up
qemu-kvm其它选项
块设备选项
i386平台专用选项
字符设备选项
蓝牙设备选项
Linux启动器专用选项
调试/专家模式选项
qemu-img使用
# 支持多种虚拟化镜像文件格式 vmdk VMware vdi VirtualBox raw dd命令,很多高级功能不支持 qcow2 现在KVM、Xen广泛支持的格式 ... # 无损格式转换 convert # 显示磁盘映像信息 qemu-img info cirros-* # 制作光盘映像文件 qemu-img create -o ? -f qcow2 /images/windows/winxp.qcow2 qemu-img create -o size=20G,preallocation=metadata -f qcow2 /images/windows/winxp.qcow2 du -sh /images/windows/winxp.qcow2
安装使用一个kvm虚拟机
下载公共映像文件
为cloud环境测试vm提供的微缩版的Linux
1 wget https://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img
启动第一个虚拟机工作在后台
qemu-kvm -m 128 -smp 2 -name test -daemonize -hda /images/kvm/cirros-0.3.4-i386.disk.img
用-drive指定磁盘映像文件高级功能
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
通过cdrom启动winxp,内外鼠标会不一致,没有加载USB驱动(-usbdevice tablet)
qemu-kvm -name winxp -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
使用PXE安装虚拟机系统
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=x:x:x:x:x:x \ -net tap,ifname=rhel5.8,script=/etc/ifup \ -boot order=nc,once=n \ -vga cirrus -balloon virtio
其它安装linux虚拟机方式
# 下面的命令创建了一个名为rhel5.8的虚拟机,其RAM大小为512MB,有两颗CPU的SMP架构,默认引导设备为硬盘,有一个硬盘设备和一个光驱, # 网络接口类型为virto,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/rhel5.8.iso,index=1,media=cdrom \ -net nic,model=virtio,macaddr=x:x:x:x:x:x \ -vga cirrus -balloon virtio
# 需要注意的是,上述命令中使用的硬盘映像文件/VM/images/rhel5.8/hda需要事先使用qemu-kvm命令创建 # 在虚拟机创建并安装GuestOS完成之后,可以免去光驱设备直接启动 qemu-img create -o size=20G,preallocation=metadata -f qcow2 file=/VM/images/rhel5.8/hda 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=x:x:x:x:x:x \ -vga cirrus -balloon virtio
# 指定使用桥网络接口 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
使用vnc登录虚拟机
# 为可以登录使用、管理虚拟机,我们需要下载一个远程桌面登录工具VNC yum install -y tigervnc # 连接我本创建好的虚拟机 vncviewer :5900 # 启动qemu-kvm时,额外使用-monitor stdio选项,并使用 change vnc password # 管理虚拟机命令 root@localhost#info
虚拟机迁移 VM Migration
static migtation live migration 整体迁移时间 服务器停机时间 对服务的性能的影响 在待迁入主机使用 qemu-kvm -vnc :N -incoming tcp:0:7777 # N桌面号,tcp指定接收端口 vncviewer :590N 在源主机使用 monitor接口 migrate tcp:DEST_IP:DEST:PORT # migrate tcp:DEST:PORT
virtio半虚拟化
HVM 虚拟化CPU
需要底层硬件支持
I/O半虚拟化分成两段
前端驱动(virtio前半段) virtio-blk, virtio-net, virtio-balloon, virtio-console Linux CentOS支持 4.8+, 5.3+, 6.0+, 7.0+ virtio 虚拟队列-virt-ring transport 后端处理程序(virt backend drivers),在QEMU中实现
virt-balloon
balloon 让VM中运行的GuestOS运行时动态调整其内存大小 # qemu-kvm -balloon virtio 开启虚拟机内存动态调整 手动查看GuestOS的内存大小 info balloon balloon N
virt-net
其依赖于GuestOS中的驱动,及Qemu中的后端驱动 GuestOS virtio_net.ko # 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