KVM虚拟化技术
1、KVM发展历史Kernel Virtual Machine,内核虚拟机。最初由一个以色列的公司在2006年开发的一个开源项目,这个公司已经于2008年被RedHat所收购。在RHEL5时代,Xen是RedHat公司集成和支持的虚拟机,而在2010年发布RHEL6开始至今,RedHat 公司使用KVM作为默认集成和支持的虚拟机工具。目前的虚拟机技术阵营分成两个阵营,一类是
·
1、KVM发展历史
Kernel Virtual Machine,内核虚拟机。
最初由一个以色列的公司在2006年开发的一个开源项目,这个公司已经于2008年被RedHat所收购。
在RHEL5时代,Xen是RedHat公司集成和支持的虚拟机,而在2010年发布RHEL6开始至今,RedHat 公司使用KVM作为默认集成和支持的虚拟机工具。
目前的虚拟机技术阵营分成两个阵营,一类是以Xen,ESX/ESXi,Hyper-V为代表的微内核架构,系统上电之后首先加载的是虚拟机监控程序,虚拟机监控程序直接负责系统的初始化和物理资源的管理,创建、调度和管理虚拟机;另一类是以KVM,VMware Workstation, VirtualBox为代表,系统上电之后仍然首先加载运行的是一般意义上的操作系统,虚拟机监控程序只是这个操作系统之上的一个应用功能扩展。
- KVM:是Linux完全原生的全虚拟化解决方案,就是在Linux内核中添加的一个虚拟机模块,直接使用Linux内核中已经完善的进程调度、内存管理与硬件设备交互等部分,使Linux成为一个可以支持运行虚拟机的Hypervisor。因此,KVM并不是一个完善的模拟器,而只是一个提供虚拟化功能的内核插件,它的具体的模拟器工作是借助工具(QEMU)来完成。
- Xen:同时支持虚拟化与半虚拟化,需要在Linux系统内核之上再运行一个由Xen提供的微内核,由微内核控制虚拟化计算和内存资源的分配与使用 。因为诞生时间很早,那时硬件和系统内核层面根本没有支持虚拟化的,所以Xen被设计为不依赖也不使用硬件的虚拟化支持,通过对操作系统进行显式地修改(“移植”)以使其可以在Xen上作为虚机运行。
KVM需要CPU中虚拟化功能的支持,只可在具有虚拟化支持的CPU上运行,即具有VT功能的Intel CPU和具有AMD-V功能的AMD CPU。它包含一个为处理器提供底层虚拟化可加载的核心模块KVM.ko(KVM-intel.ko或KVM-AMD.ko)。KVM还需要一个经过修改的QEMU软件(qemu-KVM),作为虚拟机上层控制和界面。
KVM从Linux 2.6.20开始就已经被集成进入了Linux内核,可以说是与Linux内核一直在共同发展。而另一个明显有内核”不友好、不兼容“特点的Xen虚拟化方案一直无法得到Linux内核维护小组的支持。
2、KVM的架构原理
KVM是一个可以按需加载运行的Linux内核模块,仅支持硬件虚拟化,且KVM本身不做任何设备模拟,它是使用QEMU程序通过/dev/kvm接口进行I/O设备模拟。
KVM虚拟机的创建和运行就是一个用户空间的应用程序(QEMU)和KVM模块相互配合的过程。
QEMU,是一个独立发展的著名的开源虚拟机软件,并不是KVM的一部分。在QEMU中已经提供了虚拟机所需的整套技术实现,包括处理器虚拟化、内存虚拟化以及各类虚拟设备的模拟。但因为QEMU是一种纯软件解决方案,所以性能低下。
KVM定制了一个适合自己使用的QEMU版本,将用户空间程序负责的工作,例如虚拟机的创建、配置,虚拟机运行所依赖的虚拟设备,虚拟机运行时的用户操作环境和交互,甚至于虚机的动态迁移技术等,都交给QEMU所实现的。KVM自己仅作硬件虚拟化功能的实现。
命令方式创建KVM虚拟机:
#virt-install --name centos6-test1 --ram 2048 --vcpus=2 --disk path=/data/images/centos6-test1.img,size=100 --network bridge=br0,model=virtio
--accelerate --force --graphics vnc --autostart --noautoconsole --os-type=linux --os-variant=rhel6 --cdrom /root/CentOS-6.7-x86_64-minimal.iso
#virt-install -n win2008s -r 4096 --vcpus=2 --os-type=windows --accelerate -c /data/iso/Win2008R2Server_64bit.iso
--disk path=/data/iso/virtio-win-0.1-100.iso,device=cdrom --disk path=/data/images/win2008x64.img,bus=virtio,size=60
--network bridge=br0 --vnc --force --autostart
每个kvm虚拟机都是宿主机上的一个qemu进程:
[bjxtb@MJQ_130_3 ~]$ ps -ef|grep kvm
root 2692 2 0 2016 ? 00:00:00 [kvm-irqfd-clean]
qemu 29478 1 99 2016 ? 479-15:25:54 /usr/libexec/qemu-kvm -name vm2 -S -M rhel6.6.0 -enable-kvm -m 48000
-realtime mlock=off -smp 12,sockets=12,cores=1,threads=1 -uuid 61b7963d-477e-56b4-341a-0b86344cc04f -nodefconfig -nodefaults
-chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/vm2.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control
-rtc base=utc -no-shutdown -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,
bus=pci.0,multifunction=on,addr=0x5 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 -device ich9-usb-uhci3
,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 -drive file=/var/lib/libvirt/images/vm2.img,if=none,id=drive-ide0-0-0,format=raw
,cache=none -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -netdev tap,fd=19,id=hostnet0 -device rtl8139,
netdev=hostnet0,id=net0,mac=52:54:00:24:8a:8c,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,
id=serial0 -vnc 127.0.0.1:1 -k en-us -vga cirrus -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0
,bus=sound0.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 -msg timestamp=on
root 29493 2 0 2016 ? 00:00:00 [kvm-pit-wq]
qemu 52222 1 14 2016 ? 34-07:57:55 /usr/libexec/qemu-kvm -name s3-vm1 -S -M rhel6.6.0 -enable-kvm -m 8192 -realtime mlock=off -smp 4,
sockets=4,cores=1,threads=1 -uuid a147b00b-cf4c-45e8-737b-5ad1066dc31b -nodefconfig -nodefaults -chardev socket,id=charmonitor,
path=/var/lib/libvirt/qemu/s3-vm1.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown
-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,
addr=0x5 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,
addr=0x5.0x2 -drive file=/var/lib/libvirt/images/vm1.img,if=none,id=drive-ide0-0-0,format=raw,cache=none -device ide-drive,bus=ide.0,unit=0,
drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -netdev tap,fd=23,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:62:f9:71,
bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -vnc 127.0.0.1:0 -k en-us -vga cirrus
-device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device virtio-balloon-pci,
id=balloon0,bus=pci.0,addr=0x6 -msg timestamp=on
3、KVM的网络配置
3.1 网桥的使用
配置:
virsh iface-bridge eth0 br0
more ifcfg-br0
DEVICE=br0
ONBOOT=yes
BOOTPROTO=static
TYPE="Bridge"
IPADDR="172.17.90.15"
NETMASK="255.255.255.0"
GATEWAY="172.17.90.1"
DNS1="114.114.114.114"
STP="on"
DELAY="0"
调优:
STP="on" #打开生成树协议,避免出现环路
service NetworkManager stop
chkconfig NetworkManager off #在RHEL/CENTOS系统中,NetworkManager服务无法管理网桥的配置,且会网络配置与生效产生干扰。
查看网桥:
$ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.2047478aa28c yes bond0
vnet0
vnet1
vnet2
virbr0 8000.525400652d4c yes virbr0-nic
网桥virbr0是用于NAT网络模式使用的网桥
$ ifconfig virbr0
virbr0 Link encap:Ethernet HWaddr 52:54:00:65:2D:4C
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
$ ps -ef|grep dns
nobody 2396 1 0 2016 ? 00:00:00 /usr/sbin/dnsmasq --strict-order --pid-file=/var/run/libvirt/network/default.pid
--conf-file= --except-interface lo --bind-interfaces --listen-address 192.168.122.1 --dhcp-range 192.168.122.2,192.168.122.254
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases --dhcp-lease-max=253 --dhcp-no-override
--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE tcp -- 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
MASQUERADE udp -- 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
MASQUERADE all -- 192.168.122.0/24 !192.168.122.0/24
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
3.2 使用virtio-net
Virtio半虚拟化驱动的方式,可以获得很好的I/O性能,其性能几乎可以达到和native(即:非虚拟化环境中的原生系统)差不多的I/O性能。所以,在使用KVM之时,如果宿主机内核和客户机都支持virtio的情况下,一般推荐使用virtio达到更好的性能。
其中前端驱动(frondend,如virtio-blk、virtio-net等)是在客户机中存在的驱动程序模块,而后端处理程序(backend)是在QEMU中实现的。在这前后端驱动之间,还定义了两层来支持客户机与QEMU之间的通信。其中,“virtio”这一层是虚拟队列接口,它在概念上将前端驱动程序附加到后端处理程序。一个前端驱动程序可以使用0个或多个队列,具体数量取决于需求。例如,virtio-net网络驱动程序使用两个虚拟队列(一个用于接收,另一个用于发送),而virtio-blk块驱动程序仅使用一个虚拟队列。
虚拟队列实际上被实现为跨越客户机操作系统和hypervisor的衔接点,但它可以通过任意方式实现,前提是客户机操作系统和virtio后端程序都遵循一定的标准,以相互匹配的方式实现它。而virtio-ring实现了环形缓冲区(ring buffer),用于保存前端驱动和后端处理程序执行的信息。
3.3 关于vhost_net
这是宿主机中默认使用的虚拟机网络后端处理程序。在较新的Linux内核中已经集成作为一个驱动模块。当为KVM虚拟机选用virtio网络驱动模式时,后端即默认使用vhost_net。
$ lsmod|grep vhost _net
vhost_net 30520 3
$ ps -ef|grep vhost
bjxtb 3805 3346 0 16:32 pts/3 00:00:00 grep vhost
qemu 6508 1 99 2015 ? 578-08:41:17 /usr/libexec/qemu-kvm -name gate1-24 -S -M rhel6.6.0 -enable-kvm -m 32768 -realtime mlock=off
-smp 12,sockets=12,cores=1,threads=1 -uuid bad75b87-6984-adb3-8946-db9f156afd03 -nodefconfig -nodefaults -chardev socket,id=charmonitor
,path=/var/lib/libvirt/qemu/gate1-24.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown
-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0
,addr=0x5.0x2 -drive file=/var/lib/libvirt/images/gate1-24.img,if=none,id=drive-virtio-disk0,format=raw,cache=none -device virtio-blk-pci,
scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -drive file=/var/lib/libvirt/images/gate1-24-1.img,
if=none,id=drive-ide0-0-0,format=raw,cache=none -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0
-drive file=/isotool/CentOS-6.5-x86_64-minimal.iso,if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw -device ide-drive,bus=ide.1,unit=0,
drive=drive-ide0-1-0,id=ide0-1-0 -netdev tap,fd=22,id=hostnet0,vhost=on,vhostfd=23 -device virtio-net-pci,netdev=hostnet0,id=net0
,mac=52:54:00:e5:02:c3,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,
id=input0 -vnc 127.0.0.1:0 -k en-us -vga cirrus -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0,bus=sound0.0,
cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 -msg timestamp=on
root 6529 2 99 2015 ? 213557-03:59:26 [vhost-6508]
3.4 宿主机中的TSO、GSO配置
TSO,GSO是Linux中结合硬件实现的延迟大数据包拆分的技术,将原来由cpu负责的数据包拆分工作延迟至网卡上去完成,可以提升处理效率。
在KVM virtio网络虚拟化的实现中,有相关的案例中发现开启TSO,GSO功能后,反而会导致处理性能的下降。所以在这种情况下,可以人为得关闭这两个功能。
查看相关配置参数:
ethtool -k eth0
关闭TSO,GSO:
ethtool -K em1 gso off
ethtool -K em1 tso off
4、KVM性能
同等资源条件的物理机和KVM虚拟机,虚机的资源利用率相当于物理机的:
- CPU 97%
- Memory 95%
- Network 除非是驱动设置有误,否则几乎相当,但相对于物理网卡会增加0.1ms的延时
- disk 虚拟机的磁盘读写性能普遍上要低于物理机(数据块较小时差别明显,但当block size>1M时几乎无差别), 其中IDE驱动方式的性能又普遍低于virtio方式。如果采用磁盘的半虚拟化实现技术,则损失灵活性的同时,磁盘I/O性能会与物理机相当。
5、centos6的KVM虚拟化安装方法
宿主机的系统安装要求:最小化安装,并使用yum -y update升级至centos6.8。
#安装KVM相关的依赖包和工具包
yum -y groupinstall "Desktop" "X Window System" chinese-support 'Virtualization' 'Virtualization Client' 'Virtualization Platform'
yum -y install kvm virt-viewer virt-manager bridge-utils tunctl libvirt libvirt-python python-virtinst
#查看和验证安装结果
service libvirtd status
lsmod |grep kvm
#使用xshell登录并验证KVM服务,需要能正常打开图形化的管理窗口
virt-manager
创建桥接网卡:
virsh iface-bridge bond0 br0
virsh iface-bridge bond1 br1
6、centos7的KVM虚拟化安装方法
宿主机的系统安装要求
centos7系统的KVM宿主机安装的软件包有以下:
@^gnome-desktop-environment
@base
@core
@directory-client
@fonts
@gnome-desktop
@guest-agents
@guest-desktop-agents
请确认在安装的软件包中包含了以上内容。
#停用系统可能自带和启用的NetworkManager
systemctl stop NetworkManager
systemctl disable NetworkManager
#安装kvm tools相关的工具包
yum -y groupinstall 'Virtualization' 'Virtualization Client' 'Virtualization Platform'
#调整centos7上ssh服务端口,设置为仅监听ipv4地址。否则会无法打开virt-manager图形窗口。
sed -i 's/#AddressFamily any/AddressFamily inet/g' /etc/ssh/sshd_config
systemctl restart sshd
#使用xshell登录并验证KVM服务,需要能正常打开图形化的管理窗口
virt-manager
更多推荐
已为社区贡献9条内容
所有评论(0)