尽管这种变化的动机主要与构建和支持相关,而不是技术,但事实是许多对虚拟化感兴趣的企业 IT 小组需要学习 KVM 所使用的管理和控制工具。类似地,已投资 Xen 虚拟化且正在转向使用 KVM 的 IT 小组,可能希望尽可能将现有的虚拟机转换为 KVM 支持的格式,而不是重新创建它们。
能够在单个服务器硬件平台上运行多个虚拟机 (VM) 的能力在如今的 IT 基础架构中实现了了成本、系统管理和灵活性等方面的优势。在单个硬件平台上托管多个虚拟机,可减少硬件开支并帮助最大限度降低基础架构成本,比如能耗和制冷成本。将操作方式不同的系统作为虚拟机整合在一个硬件平台上,可简化通过管理层(比如开源虚拟化库 (libvirt))和基于它的工具(比如图形化的虚拟机管理器 (VMM))对这些系统的管理工作。虚拟化还提供了如今面向服务的高可用性 IT 操作中所需的操作灵活性,支持将正在运行的虚拟机从一个物理主机迁移到另一个主机,以满足硬件或物理场所问题的需要,或者通过负载平衡最大限度提高性能,或者应对日益增长的处理器和内存需求。
开源桌面虚拟化应用程序(比如 VirtualBox)使用户甚至是小型企业(中小型业务部门或中小型企业)环境能够在单个物理系统上运行多个虚拟机。但是,VirtualBox 等虚拟化环境是作为客户端应用程序在桌面或服务器系统上运行的。企业计算环境需要更接近物理硬件(“裸机”)的高性能、面向服务器的虚拟化环境,支持用少得多的操作系统开销来执行虚拟机。裸机虚拟化机制可更好地管理硬件资源,也可最佳地利用对内置于大多数 64 位 x86 和 PowerPC 处理器中的虚拟化硬件支持。
裸机虚拟化机制使用一个称为虚拟机管理程序的小操作系统,来管理和计划虚拟机以及相关的资源。裸机虚拟机管理程序称为 Type 1 虚拟机管理程序。两种最流行的裸机开源虚拟化技术是 Kernel Virtual Machine (KVM) 和 Xen。尽管 Xen 和 KVM 各有自己的优点和爱好者,但 KVM 的流行度和复杂度在不断增加,它现在已成为大多数 Linux® 发行版的推荐默认虚拟化机制。
比较 KVM 和 Xen
Xen 虚拟化环境在传统上提供了 Linux 系统上性能最高的开源虚拟化技术。Xen 使用一个虚拟机管理程序来管理虚拟机和相关的资源,还支持半虚拟化,这可在 “知道” 自己已实现虚拟化的虚拟机中提供更高的性能。Xen 提供了一个专门执行资源和虚拟管理与计划的开源虚拟机管理程序。在裸机物理硬件上引导系统时,Xen 虚拟机管理程序启动一个称为 Domain0 或管理域的主虚拟机,该虚拟机提供了对所有在该物理主机上运行的其他虚拟机(称为 Domain1 到 DomainN,或者简单地称为 Xen Guest)的中央虚拟机管理功能。
不同于 Xen,KVM 虚拟化使用 Linux 内核作为它的虚拟机管理程序。对 KVM 虚拟化的支持自 2.6.20 版开始已成为主流 Linux 内核的默认部分。使用 Linux 内核作为虚拟机管理程序是 KVM 受到批评的一个主要方面,因为(在默认情况下)Linux 内核并不符合 Type 1 虚拟机管理程序的传统定义—“一个小操作系统”。尽管大多数 Linux 发行版所提供的默认内核的确如此,但可以轻松地配置 Linux 内核来减少它的编译大小,以便它仅提供作为 Type 1 虚拟机管理程序运行所需的功能和驱动程序。Red Hat 自己的 Enterprise Virtualization 产品仅依靠这样一种特殊配置的、相对轻量型的 Linux 内核来运行。但更重要的是,“小”只是一个相对的词汇,如今具有数 GB 内存的 64 位服务器可轻松地提供现代 Linux 内核所需的几 MB 空间。
KVM 超越 Xen 成为大多数企业环境首选的开源裸机虚拟化技术,这有多个原因:
KVM 支持自 2.6.20 版开始已自动包含在每个 Linux 内核中。在 Linux 内核 3.0 版之前,将 Xen 支持集成到 Linux 内核中需要应用
大量的补丁,但这仍然无法保证每个可能硬件设备的每个驱动程序都能在 Xen 环境中正确工作。 Xen 支持所需的内核源代码补丁仅提供给特定的内核版本,这阻止了 Xen 虚拟化环境利用仅在其他内核版本中可用的新驱动程序、子系统及内核修复和增强。KVM 在 Linux 内核中的集成使它能够自动利用新 Linux 内核版本中的任何改进。 Xen 要求在物理虚拟机服务器上运行一个特殊配置的 Linux 内核,以用作在该服务器上运行的所有虚拟机的管理域。KVM 可在物理服务器上使用在该物理系统上运行的 Linux VM 中使用的相同内核。 Xen 的虚拟机管理程序是一段单独的源代码,它自己的潜在缺陷与它所托管的操作系统中的缺陷无关。因为 KVM 是 Linux 内核的一个集成部分,所以只有内核缺陷能够影响它作为 KVM 虚拟机管理程序的用途。
尽管 Xen 仍可提供比 KVM 性能更高的裸机虚拟化,但这些性能改进的价值常常比不上 KVM 虚拟化的简单性和易用性价值。
KVM 和 Xen 的常见管理工具
作为一种比 KVM 更成熟的裸机虚拟化技术,Xen 提供了一组专门的管理命令,最著名的是 xm 命令行套件。像任何特定于技术的管理命令集一样,xm 工具拥有自己的学习曲线,而且不是所有 Linux 系统管理员都熟悉它。KVM 很大一部分初始管理基础架构继承自 QEMU,这是一个已被广泛接受的 Linux 仿真和虚拟化包,它拥有相当的学习曲线且需要一定的专门知识。
尽管任何独创的技术拥有自己的命令集是很自然的,但越来越多的虚拟化技术让 Linux 供应商开始寻求一个管理接口来运行它们。Red Hat 毋庸置疑是第一家大型开源公司,而且它领导了开发 libvirt 虚拟化应用编程接口 (API) 的工作,以支持可管理多种虚拟化技术的工具的开发工作。libvirt API 支持 KVM、Xen、LXC 容器、OpenVZ、User-mode Linux、VirtualBox、Microsoft® Hyper-V® 和许多 VMware 技术等虚拟化技术。
无需将赌注压在单个技术和相关的命令集上,专注于 libvirt 使系统管理员能够学习一组依赖于该 API 的命令行和图形化命令并继续使用这些工具,无论底层虚拟化技术有何变化都是如此。类似地,虚拟化工具供应商可直接使用 libvirt API 获得相同的收益。
接下来的几节介绍基于 libvirt 的工具如何简化 KVM 虚拟化站点的常见管理任务。这些内容重点介绍了使用 virsh 和 virt-install 命令的命令行示例,但所有这些任务都可在图形化的、基于 libvirt 的 VMM (virt-manager) 中执行。必须以 root 用户身份(或通过 sudo 命令)执行所有这些命令。
本文剩下内容中的示例假设您已安装了合适的软件包,使 Linux 发行版能够支持 KVM 虚拟化并提供必要的工具。根据您的 Linux 平台,所需的包会有所不同。例如,在 Red Hat Enterprise Linux (RHEL) 系统(或 RHEL 克隆)上,需要安装 Virtualization、Virtualization Client、Virtualization Platform 和 Virtualization Tools 包组。
使用存储池
一篇介绍如何创建简单 KVM 虚拟机的 developWorks 文章解释了如何使用一个磁盘镜像来安装虚拟机,该镜像是在支持虚拟机的服务器本地的磁盘存储中创建的。手动创建每个用作磁盘镜像的本地文件,是初步试验虚拟机的一种常见方式,但这种方式很快会变得耗时、单调且难以管理。
libvirt 为虚拟机镜像和文件系统的位置提供了一种方便的抽象,称为存储池。存储池是一个本地目录、本地存储设备(物理设备、逻辑卷或 SCSI 主机总线适配器 [HBA] 存储)、网络文件系统 (NFS) 或块级连网存储,可使用 libvirt 管理它们,并且可在其中创建和存储一个或多个虚拟机镜像。本地存储很简单,但可能不灵活且不支持企业虚拟化的最关键需求:在虚拟机运行时将其从一个服务器迁移到另一个服务器的能力,这也称为实时迁移 (live migration)。要轻松地支持实时迁移,虚拟机磁盘镜像应位于一个 NFS、块级连网存储或可从多个虚拟机主机使用的 HBA 存储中。
本节中的示例使用 virsh 命令,它是一个基于 libvirt 的命令套件,为创建和管理 libvirt 使用的所有对象—虚拟机(域)、存储卷、存储池、网络、网络接口、设备等提供了各个子命令。
默认情况下,基于 libvirt 的命令使用虚拟化主机上的目录 /var/lib/libvirt/images 作为初始文件系统目录存储池。可使用 virsh pool-create-as 命令轻松创建一个新的存储池。例如,下面的命令显示了在创建基于 NFS 的 (netfs) 存储池时必须指定的强制性参数:
virsh pool-create-as NFS-POOL netfs \--source-host 192.168.6.238 \--source-path /DATA/POOL \--target /var/lib/libvirt/images/NFS-POOL
第一个参数 (NFS-POOL) 指定新存储池的名称,第二个参数指定所创建的存储池类型。--source-host 选项的参数指定了通过 NFS 导出存储池目录的主机。--source-path 选项的参数指定该主机上导出的目录的名称。--target 选项的参数指定了访问存储池时所使用的本地挂载点。
创建新存储池后,它将在 virsh pool-list 命令的输出中列出。下面的示例显示了默认的存储池和在上一个示例中创建的 NFS-POOL 池:
virsh pool-list --all --detailsName State Autostart Persistent Capacity Allocation Available----------------------------------------------------------------------------default running yes yes 54.89 GB 47.38 GB 7.51 GBNFS-POOL running no no 915.42 GB 522.64 GB 392.78 GB
在这个示例输出中,注意新存储池标记为不会自动启动,表明系统重新启动后它不会自动启动,而且它没有持久化,表明在系统重新启动后绝对不会定义它。存储池仅在它们受其 XML 描述支持时才能持久化,该 XML 描述位于目录 /etc/libvirt/storage 中。XML 存储池描述文件名与它们相关联的存储池名称相同,但文件扩展名是 .xml。
要为手动定义的存储池创建 XML 描述文件,可使用 virsh pool-dumpxml 命令指定一个池名称,将其 XML 描述转储为一个最终参数。此命令写入到标准输出,所以需要将它的输出重定向到合适的文件中。例如,以下命令将为之前创建的 NFS-POOL 存储池创建正确的 XML 描述文件:
cd /etc/libvirt/storagevirsh pool-dumpxml NFS-POOL > NFS-POOL.xml
即使将存储池持久化后,该池也不会标记为在重新启动虚拟化主机时自动启动。可使用 virsh pool-autostart 命令后跟一个存储池名称来将存储池设置为自动启动,如下面的示例所示:
virsh pool-autostart NFS-POOLPool NFS-POOL marked as autostarted
将存储池标记为自动启动,意味着存储池将在虚拟化主机重新启动时可用。在技术上,它意味着 /etc/libvirt/storage/autostart 目录包含该存储池 XML 描述的一个符号链接。
创建存储池后,可在该池内创建一个或多个虚拟机,如下一节中所述。
创建虚拟机
本节中的示例利用您在上节中创建的存储池,但使用了 virt-install 命令,这是一个基于 libvirt 的命令,从名称可以看出,其设计宗旨是帮助从命令行创建虚拟机。
下一个示例 virt-install 命令创建一个名为 RHEL-6.3-LAMP 的硬件虚拟机,它的名称表明这个虚拟机正在运行 RHEL 6.3 且用作一个标准的 Linux Web 服务器。默认情况下,在创建新磁盘池卷时会使用您的虚拟机名称,所以应仔细选择此名称。虚拟机名称通常遵循一种本地命名约定,它的设计应让您的管理员同事能轻松识别每个虚拟机的类型和用途。
virt-install --name RHEL-6.3-LAMP \--os-type=linux \--os-variant=rhel6 \--cdrom /mnt/ISO/rhel63-server-x86_64.iso \--graphics vnc\--disk pool=NFS-01,format=raw,size=20 \--ram 2048 \--vcpus=2 \--network bridge=br0 \--hvm \--virt-type=kvm \
virt-install 命令的其他选项表明这个虚拟机将针对 Linux 和 RHEL6 Linux 发行版而优化(分别是 --ostype 和 --osvariant),将使用 ISO 镜像 /mnt/ISO/rhel63-server-x86_64.iso 作为虚拟 CD-ROM 设备来安装 (--cdrom)。从虚拟 CD-ROM 驱动器引导时,virt-install 命令使用 Virtual Network Computing (VNC) 协议创建一个图形控制台并尝试显示它 (--graphics),在其中执行引导和后续安装流程。如何连接到这个控制台取决于您如何连接到虚拟化服务器,它是否拥有图形化功能等,因此不属于本文的介绍范畴。
--disk 选项的参数指定将在从存储池 NFS-POOL 自动分配的 20GB 存储中创建虚拟机,这个存储池已在上一节中创建。将以 raw 镜像格式创建这个虚拟机的磁盘镜像,这是一种很容易跨大部分虚拟化和仿真技术移植的简单磁盘镜像格式。
其他 virt-install 命令参数的作用是,新虚拟机最初将配置 2GB 内存 (--ram) 和两个虚拟 CPU (--vcpus),而且它通过网桥 br0 访问网络 (--network)。
virt-install 命令的最后两个选项优化了虚拟机,将其用作完全虚拟化的系统 (--hvm),并表明 KVM 是支持新虚拟机的基础虚拟机管理程序 (--virt-type)。这两个选项都支持在创建和执行系统安装过程中进行某些优化,并且实际上是在未指定这些选项时的默认值。如果要保留虚拟机安装的命令日志,那么显式指定这些选项是个不错的做法,因为这么做会在日志中保留每个虚拟机的虚拟化环境信息。
您可使用类似的命令创建一个运行其他操作系统的虚拟机,为它使用一个合适的名称并适当地更改 --cdrom、--os-type 和 --os-variant 选项的参数。
结束语
基于 Linux 的开源虚拟化技术在不停地发展。KVM 的易用性和持续发展已帮助它取代了可能更强大的 Xen 虚拟化技术,成为开源 Linux 虚拟化的标准。无论选择哪种虚拟化技术,这种演变都突出了使用标准的、独立于技术的管理命令(比如 libvirt 虚拟化 API 所提供的命令)的价值。
本文通过示例展示了如何使用基于 libvirt 的命令来简化虚拟机的存储分配以及在存储中安装它的过程,但仅触及了 libvirt API 和基于它的免费命令所提供的许多强大管理功能的冰山一角。