<Mastering KVM Virtualization>:第三章 搭建独立的KVM虚拟化
在第二章,你了解了KVM的内部结构;在本章中,您将了解如何将Linux服务器设置为虚拟化主机。我们正在讨论将KVM用于虚拟化并将libvirt作为虚拟化管理引擎。
KVM开启了虚拟化并利用你的服务器或工作站来运行虚拟机。从技术术语来说,KVM是一组针对具备虚拟化扩展的x86架构硬件的内核模块;被加载后,它可以将Linux服务器转化为虚拟化hypervisor。可加载模块包括kvm.ko,它提供了核心虚拟化功能,以及一个处理器相关的模块,如kvm-intel.ko或者kvm-amd.ko。
NOTE:根据https://en.wikipedia.org/wiki/Hypervisor。hypervisor/VMM是一种计算机软件、固件或硬件,用来创建和运行虚拟机。
要启动虚拟机,仅仅加载KVM模块还不够。您需要emulator来模拟虚拟机的外围硬件设备。下面是介绍QEMU的时间。
QEMU是一个开源机器仿真软件。这个模拟器将帮助您在一个架构上运行为另一种架构设计的的操作系统。例如,QEMU 可以在x86平台上运行为ARM平台设计的操作系统。然而,这里有一个问题。由于QEMU使用二进制转译(一种用于在主机上执行虚拟机指令的技术),因此VM运行会比较缓慢。
如果QEMU运行缓慢,那它如何能以接近物理机的速度运行基于KVM的虚拟机呢?KVM开发人员考虑到了这个问题,并修改了QEMU作为解决方案。这个修改后的QEMU被称为QEMU-KVM,它可以直接与KVM模块交互,并在不使用动态转译的情况下,直接在CPU上执行指令。简而言之,我们使用qemu-kvm来运行基于KVM的虚拟机。
是不是越听越迷糊了?如果qemu-kvm可以运行虚拟机,那么为什么还需要libvirt。答案很简单,libvirt管理qemu-kvm,qemu-kvm运行KVM虚拟机。
NOTE:qemu-kvm已经弃用,现在所有的代码都已经与qemu-system-x86_64合并了。为了便于理解,我们还是使用qemu-kvm。一些Linux发行版仍然带有qemu-kvm。
闲话少说,让我们看看这一章将讨论什么话题:
- 介绍libvirt
- libvirt管理工具
- 硬件组装建议
熟悉libvirt
libvirt是一组位于最终用户和hypervisor之间的API。hypervisor可以基于任何libvirt支持的虚拟化技术来构建。截至此文成稿时,libvirt支持下列hypervisor:
- The KVM/QEMU Linux hypervisor
- The Xen hypervisor on Linux and Solaris hosts
- The LXC Linux container system
- The OpenVZ Linux container system
- The User Mode Linux paravirtualized kernel
- The VirtualBox hypervisor
- The VMware ESX and GSX hypervisors
- The VMware Workstation and Player hypervisors
- The Microsoft Hyper-V hypervisor
- The IBM PowerVM hypervisor
- The Parallels hypervisor
- The Bhyve hypervisor
libvirt是一个透明层,它接受用户的命令,根据底层虚拟化技术修改它们,然后在hypervisor上执行它们。这意味着,如果您知道如何使用基于libvirt的管理工具,您就能够管理前面提到的hypervisor,而不需要一一了解它们。您可以选择任何虚拟化管理技术。他们都使用libvirt作为后端基础设施管理层,尽管前端工具看起来不同;例如,oVirt、RHEV(Red Hat企业虚拟化技术)、OpenStack、Eucalyptus等。这本书是关于KVM libvirt及其工具的。
在下面的图中,我们将总结这些所有的东西是如何连接的:
Libvirt将负责存储、网络和虚拟硬件需求,以启动虚拟机和VM生命周期管理。
这里演示了使用libvirt启动VM是多么容易。在这里,我们使用virsh启动一个名为TestVM的VM。
# virsh start TestVM
NOTE:virsh是与libvirt服务交互的CLI命令行,而virt-manager是它的GUI前端。稍后,您将在本书中了解更多有关这些工具的知识。
在后端,你可以看到libvirt搭配一系列参数初始化qemu进程:
# qemu-system-x86_64 -machine accel=kvm -name TestVM -S -machine pc-i440fx-1.6,accel=kvm,usb=off -m 4000 -realtime mlock=off -smp 2,sockets=2,cores=1,threads=1 -uuid 39ac4786-1eca-1092-034c-edb6f93d291c -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/TestVM.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=/dev/vms/TestVM,if=none,id=drive-virtio-disk0,format=raw,cache=none,aio=native -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=2 -netdev tap,fd=27,id=hostnet0,vhost=on,vhostfd=28 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:a5:cd:61,bus=pci.0,addr=0x3,bootindex=1 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -vnc 127.0.0.1:2 -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
NOTE:在介绍libvirt的同时,我们有意避免提到libvirt的很多特性。这样做是为了使概念更加清晰,并将重点放在libvirt的关键功能上。当你学完这些章节,你将完全掌握这些功能特性。
现在,您已经熟悉了使用基于KVM的虚拟化所需的关键内容。在我们学习如何搭建环境之前,我们应该先了解一下系统需求。
Host系统需求
虚拟机需要分配一定数量的CPU、内存和存储。这意味着您计划在该主机上运行的虚拟机的数量决定了KVM hypervisor的硬件需求。
让我们从最低需求开始,在KVM上启动两个简单的虚拟机,每台756 MB内存:
- Intel或AMD 64-bit CPU,拥有虚拟化扩展(Intel VT-x或者AMD-v)
- 2GB 内存
- 安装Linux系统后,在KVM hypervisor上有8 GB的空闲磁盘空间
- 100 Mbps网络连接
NOTE:我们使用Fedora 21演示书中的例子。尽管如此,你也可以使用其他支持KVM和libvirt的Linux发行版(Ubuntu,Debian,CentOS或其他)。我们假设您已经安装了Fedora 21或其他Linux发行版,完成了包括网络在内的所有设置。
确定适合您环境的系统需求
这是一个非常重要的阶段,我们需要把它做好。拥有正确的系统配置是虚拟机获得近似原生性能的关键。让我们从CPU开始。
1. 物理CPU
Intel或AMD 64-bit CPU,拥有虚拟化扩展(Intel VT-x或者AMD-v)。
为了确定您的CPU是否支持虚拟化扩展,您可以检查以下标志:
# grep --color -Ew 'svm|vmx|lm' /proc/cpuinfo flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm ida dtherm tpr_shadow vnmi flexpriority ept vpid
svm标志意味着CPU支持AMD-v,vmx标志意味着CPU支持VT-x,lm意味着CPU支持64位。
如果您的CPU支持虚拟化扩展,那么您的系统可能已经准备好承载KVM虚拟机了。您还会注意到,无需额外的配置,对应的KVM模块就会自动加载。为了验证模块是否已加载,可以使用以下命令:
# lsmod | grep kvm kvm_intel 148081 9 kvm 461126 1 kvm_intel
如果系统是AMD,你会看到kvm_amd而不是kvm_intel。
如果您没有看到前面的CPU标志,或者所有KVM模块都没有加载,但是您确定系统支持虚拟化扩展,可以尝试以下排障步骤:
- 重新系统并进入BIOS。
- 进入CPU高级选项。启用Intel Virtualization Technology或Virtualization Extensions。对于AMD来说,应该是默认启用的。确切的描述可能会根据您的BIOS不同而有所不同。
- 重启主机。
- 您现在应该看到加载的KVM模块。如果您仍然没有看到它们的加载,那么尝试手动加载它们。
# modprobe kvm kvm_intel
ormodprobe kvm kvm_amd
- 如果您能够手动加载它们,但它们仍然不能正常工作,那么应该联系您的硬件供应商,或者仔细检查Intel或AMD各自产品页面的处理器细节。
除了虚拟化扩展之外,您可能还需要在BIOS中启用Intel VT-d或AMD IOMMU(AMD-Vi)。这是将PCI设备直接分配给虚拟机所需要的,例如,将物理网络接口卡(NIC)从hypervisor分配给虚拟机;我们将在接下来的章节中详细介绍这些内容。
2. CPU CORES
如果你计划运行服务器级别的虚拟机,那么推荐一个core对应一个vCPU。在计算core数时,不要在Intel CPU上计算 超线程core,而是只计算实际core。当然,你可以超过实际core数超量分配vCPU,但这会导致性能损失。
如果您计划运行桌面级的虚拟机或非CPU密集型的虚拟机,那么您可以放心地超量分配使用CPU,因为性能要求退居二线,每hypervisor虚拟机运行密度这一指标的优先级高于性能。
NOTE:超量分配的意思是,分配超过实际物理资源的虚拟资源。
单个hypervisor可以运行多少个VM并没有明确的定义。这完全取决于VM的工作负载类型以及您能够承受多少程度性能下降。如果所有的VM都运行CPU密集型任务,那么vCPU的超分配就不是个好主意。
TIP:使用lscpu命令查看CPU拓扑。
3. 物理内存
您可以使用一个简单的经验法则来决定物理节点需要多少内存:将计划分配给虚拟机的所有内存加相加,并为hypervisor本身添加额外2GB RAM。
如果您计划运行内存密集型工作负载,那么这就是预期的配置。
与CPU相似,KVM也支持内存的超分配。这意味着您可以冒着内存耗尽的风险,分配更多的内存给VM,而非hypervisor实际拥有的内存。通常这种类型的分配方式适合桌面级别虚拟机或测试虚拟机。
您可以使用以下公式来计算可供VM使用的RAM总量(单位GB):
- 对于拥有64 GB内存的系统:RAM - 2 GB = 可供VM使用的内存总量
- 对于超过64 GB内存的系统:RAM - (2 GiB + 0.5 *(RAM/64))= 可供VM使用的内存总量
在强制2GB的基础上,每64GB我们多分配500 MiB内存给hypervisor。使用这个公式可以粗略地了解有多少内存可供虚拟机使用。在某些工作负载中,您可能不需要超过5 GB的RAM用于hypervisor,即使我们的公式表明,在拥有1TB内存的系统上您可能需要保留10 GB内存给hypervisor。
4. 存储
在考虑hypervisor的存储空间时,您需要考虑OS安装、SWAP空间和虚拟机磁盘使用所需的空间。
推荐的SWAP空间大小是多少?(hypervisor的SWAP空间)
确定交换空间大小的理想数值有点复杂。如果您不打算执行任何内存超分策略,那么您可以使用下面oVirt Node的配置建议,它是一个专门用于运行VM的KVM hypervisor:
- 4GB或者更少,分配2GB SWAP空间
- 4GB到16GB内存,分配4GB SWAP空间
- 16GB到64GB内存,分配8GB SWAP空间
- 64GB到256GB内存,分配16GB SWAP空间
如果您计划执行内存超分策略,则需要添加额外的交换空间。如果超分比率0.5(即比可用物理RAM多50%),那么您需要使用以下公式来确定交换空间大小:
(RAM x 0.5) + SWAP for OS = SWAP space required for overcommitting
举例,如果你的系统有32 GB内存,你打算实行0.5的超分比例,则需要的交换空间是(32 * 0.5)+ 8 = 24 GB。
虚拟磁盘可以以文件的方式存储在本地文件系统(ext3,ext4,xfs等)或者共享文件系统(NFS,GlusterFS等)中。虚拟磁盘也可以通过块设备创建,例如LVM、本地磁盘分区、iSCSI磁盘、FC、FCoE等等。简而言之,您可以将hypervisor看到的任何块设备附加到VM上。正如您所猜测的,(虚拟磁盘)空间是由VM需要多少磁盘空间,或者是安装在上面的应用程序决定的。在存储中,你也可以像CPU和内存一样进行超量分配,但是对I/O负载较重的VM并不推荐。超分的虚拟磁盘称为瘦置备磁盘。
关于CPU、内存和存储超分的进一步说明,将在后面的章节中给出,这些章节涵盖了虚拟机性能调优的相关内容。
5. 网络
建议使用至少1 GBps带宽的网卡来保证平滑的网络操作,但这完全取决于你如何配置虚拟网络基础设施,和网络需求根据不同的场景的变化。
建议使用Linux bonding技术将多个网络接口汇聚成一个通道,并基于它来构建VM网络基础设施。它将有助于增加带宽和提供冗余。
NOTE:bonding mode有好多种,但并不都是支持用来构建虚拟网络基础设施。支持的bonding模式有Mode 1 (active-backup),Mode 2 (balance-xor),Mode 4 (802.3ad/LACP)和Mode 5 (balance-tlb);其余的bonding模式都不被支持。Mode 1和Mode 4最推荐和稳定的。
环境搭建
本节将指导你完成虚拟化软件包安装的整个过程,从启动libvirt服务开始,并验证系统已经准备好使用KVM虚拟化技术来运行虚拟机。
NOTE:我们假设您有一个Fedora 21系统,它具备图形用户界面和Internet连接可以访问默认的Fedora yum源,并通过它可以下载所需的KVM虚拟化软件包。我们还假设在你服务器的BIOS中已经启用了虚拟化技术(VT)功能。
要验证您的系统是否启用了默认的yum源,可以使用yum repolist命令。该命令列出了系统中已定义的yum源:
在输出中寻找一个名为Fedora/21/x86-64的repo源。通过这个源你可以访问所有KVM虚拟化的软件包。
1. 安装虚拟化软件包
这是将Fedora 21服务器或工作站系统转换为虚拟化主机的第一步。你只需以root权限执行 yum install <packages> 命令,<packages> 是空格分割的软件包包名的列表。
在Fedora 21系统上搭建虚拟化环境所需的最基本的包是libvirt、qemu-kvm和virt-manager。所以你需要执行以下命令:
# yum install qemu-kvm libvirt virt-install virt-manager virt-install -y
有很多依赖包会随着上述三个包一起安装,但是你不需要知道或者记住它们的名字,yum 命令会自动检查依赖并为你安装这些软件包。
yum groupinstall 命令也可以用于安装必须和可选的软件包,用以搭建KVM虚拟化环境:
# yum groupinstall "virtualization" -y
它除了安装核心的libvirt和qemu-kvm软件包以外,还会安装guestfs-browser,libguestfs-tools,python-libguestfs,virt-top,以下是yum groupinfo “virtuallization”的输出,供您参考:
#yum groupinfo "virtualization" Group: Virtualization Group-Id: virtualization Description: These packages provide a virtualization environment. Mandatory Packages: +virt-install Default Packages: libvirt-daemon-config-network libvirt-daemon-kvm qemu-kvm +virt-manager +virt-viewer Optional Packages: guestfs-browser libguestfs-tools python-libguestfs virt-top
目前,我们建议你使用yum安装命令安装核心软件包,以避免任何混淆。后面的章节中,会通过示例和安装步骤完整地解释KVM虚拟化的可选实用程序。
2. 启动libvirt服务
安装KVM虚拟化软件包之后,首先要做的是启动libvirt服务。当你启动libvirt服务时,它会对外发布一个应用程序接口(API)与qemu-kvm应用程序进行交互。virsh和virt-manager等客户端使用这个API与qemu-kvm进行通信,完成虚拟机生命周期的管理。要启用和启动服务,请运行以下命令:
# systemctl enable libvirtd && systemctl start libvirtd
TIP:使用 libvirtd --version 命令查询libvirt版本。
3. 验证和了解你系统的virt功能
在创建虚拟机之前,了解什么是virt功能,验证系统并确保它满足KVM虚拟化主机的所有先决条件是非常重要的。
了解这些信息将帮助您规划虚拟机的数量和系统上可以承载的配置。有两个重要的命令可以帮助验证KVM的系统配置。让我们从virt-host-validate开始:
- virt-host-validate:以root用户执行此命令,将执行对KVM功能的完整性检查,以验证虚拟化主机是否配置恰当。例如:TestSys1主机安装有KVM虚拟化所有必需的软件包,但缺乏硬件虚拟化支持。在这种情况下,它将输出以下内容:
root@'TestSys1 ~]#virt-host-validate QEMU: Checking for hardware virtualization : WARN (Only emulated CPUs are available, performance will be significantly limited) QEMU: Checking for device /dev/vhost-net : PASS QEMU: Checking for device /dev/net/tun : PASS LXC: Checking for Linux >= 2.6.26 : PASS
- 这个输出清楚地显示,系统没有启用硬件虚拟化,只支持“qemu”模式,它与qemu-kvm相比运行非常慢。
硬件虚拟化支持(hardware virtualization support)帮助KVM(qemu-kvm)虚拟机直接访问物理CPU,帮助它达到近似原生的性能。硬件支持不存在于单独的qemu中。
现在让我们看看,验证KVM虚拟化系统时,virt-host-validate命令还检查了其他哪些参数:
- /dev/kvm:KVM驱动在主机上创建了一个/dev/kvm字符设备,帮助虚拟机直接访问硬件。没有这个设备意味着VM无法访问物理硬件,哪怕它在BIOS中已经启用,这将大大降低VM的性能。
- /dev/vhost-net:vhost-net驱动在主机上创建了一个/dev/vhost-net字符设备。这个字符设备是配置vhost-net实例的接口。没有这个设备会大大降低虚拟机的网络性能。
- /dev/net/tun:这是另一个用来创建tun/tap设备,促进虚拟机网络联通性的字符设备。tun/tap设备的详细内容将在后面的章节说明。就目前而言,你只需理解,拥有一个字符设备对于KVM虚拟化的正常工作非常重要。
在系统上创建虚拟机之前,应始终确保已经通过所有virt-host-validate的完整性检查。验证完毕所有参数后,您将在系统上看到以下输出:
[root@kvmHOST ~]# virt-host-validate QEMU: Checking for hardware virtualization : PASS QEMU: Checking for device /dev/kvm : PASS QEMU: Checking for device /dev/vhost-net : PASS QEMU: Checking for device /dev/net/tun : PASS LXC: Checking for Linux >= 2.6.26 : PASS [root@kvmHOST ~]#
第二个命令是virsh。virsh(virtualization shell)是一个命令行接口,用于管理Linux系统上的VM和hypervisor。它使用libvirt管理API,可以作为图形化工具virt-manager和Web化工具kimchi-project的替代选择。virsh命令是分类隔离的,以下是一些重要的virsh命令分类:
- Guest管理命令(start,stop)
- Guest监控命令(memstat,cpustat)
- Host和hypervisor命令(capabilities,nodeinfo
)
- 虚拟网络命令(net-list,net-define)
- 存储管理命令(pool-list,pool-define)
- 快照命令(create-snapshot-as)
TIP:我们建议你通过man手册学习virsh命令,virsh是一个文档非常完善的命令,可以通过 # man virsh 查看virsh命令的man手册。
之所以要在本章中介绍virsh命令,是因为virsh可以显示很多关于主机功能的信息,比如主机CPU拓扑、虚拟机可用内存等等。让我们看一下virsh nodeinfo命令的输出,它将提供物理节点的系统资源信息:
#virsh nodeinfo CPU model: x86_64 CPU(s): 4 CPU frequency: 2534 MHz CPU socket(s): 1 Core(s) per socket: 2 Thread(s) per core: 2 NUMA cell(s): 1 Memory size: 7967796 KiB
NOTE:你必须以root权限运行virsh命令。
在virsh nodeinfo输出中,您可以看到系统硬件架构、CPU拓扑、内存大小等。显然,同样的信息也可以使用标准的Linux命令来收集,但是您必须运行多个命令。你可以使用这些信息,在硬件资源方面判断这是不是一台合适的主机,可供你创建合适的虚拟机。
另一个重要的命令是 #virsh domcapabilities。该命令显示了一个XML文档,描述了主机qemu-kvm的能力和libvirt的版本。了解emulator的功能非常有用。它可以帮助你确定虚拟机可使用的虚拟磁盘的类型、可分配的vCPU的最大数量等等。
硬件配置举例
让我们来看看一些常见的硬件配置;virsh命令的domcapabilities选项会显示主机的功能。您可以通过解析输出,找到特定硬件配置的确切支持值,用于虚拟机的设置。以下是你可以在VM上设置的最大vCPU的值:
[root@kvmHOST ~]# virsh domcapabilities | grep -i max <vcpu max='255'/> [root@kvmHOST ~]#
根据输出,在这个主机上,可以为虚拟机配置最多255个vCPU:
[root@kvmHOST ~]# virsh domcapabilities | grep diskDevice -A 5 <enum name='diskDevice'> <value>disk</value> <value>cdrom</value> <value>floppy</value> <value>lun</value> </enum> [root@kvmHOST ~]#
根据输出,这个主机上,可以为虚拟机配置disk,cdrom,floppy和lun类型的设备。
许多物理节点hypervisor的功能通过该命令输出。检视所有的功能选项超出本书的目标,因此,您可能想尝试在你自己的环境中运行这个命令来查看它所输出的报告。Alternatively, it might be good to link it to a definitive online resource。因此我们建议你在系统上运行该命令并学习其功能选项。
除了安装libvirt和qemu-kvm软件包,我们还在系统上安装了virt-manager软件包。如前所述,virt-manager是一个GUI工具,可以管理本地或者远程的hypervisor。现在,在完成本章之前,我们将向您展示如何启动virt-manager并将其连接到本地KVM hypervisor:
- 首先,确保libvirtd服务处于运行状态,而且已经通过virt-host-validate命令的所有检查项。
- 然后,导航到Menu -- System tools,点击Virtual Machine Manager。
- 点击virt-manager以后,与本地hypervisor(qemu-kvm)连接的Virtual Machine Manager图形工具将被打开,类似下图:
- 假如不能查找并连接到本地hypervisor,点击File菜单,打开Add Connection对话框,填写连接信息:
前面的hypervisor一栏必须从下拉菜单中选择QEMU/KVM,然后点击Connect。就是这样,它将通过libvirt将virt-manager连接到本地qemu-kvm hypervisor。如果你需要连接到远程hypervisor,选中Connect to remote host并填写详细信息。
如果你的virt-manager成功地连接到本地KVM hypervisor,那么你现在就可以创建虚拟机了。如果连接失败,请检查/user-home/.cache/virt-manager/virt-manager.log日志文件。
概述
在本章中,我们连带libvirt管理工具一起,学习了KVM虚拟化。我们还学习了与KVM和libvirt相关的各种工具,以及使您的系统平稳运行的硬件样例配置。
在下一章中,你将通过示例了解更多关于virsh命令及其语法的知识。您还将学习如何使用virt-manager创建虚拟机。我们还将详细解释virt-manager和virsh命令,并举例说明如何创建虚拟机。