Linux内核虚拟机 学习KVM架构及其优点

简介:

虚拟化 概念很早就已出现。简单来说,虚拟化就是使用某些程序,并使其看起来类似于其他程序的过程。将这个概念应用到计算机系统中可以让不同用户看到不同的单个系统(例如,一台计算机可以同时运行 Linux 和 Microsoft® Windows®)。这通常称为全虚拟化(full virtualization)。

虚拟化也可以使用更加复杂的格式,其中单个计算机看上去具有多个架构(对于一个用户来说,它是一个标准的 x86 平台;对于另外一个用户来说,它是 IBM Power PC® 平台)。这种虚拟化形式通常被称为 硬件仿真

最后,更加简单的一种虚拟化是操作系统虚拟化,其中一台计算机可以运行相同类型的多个操作系统。这种虚拟化可以将一个操作系统的多个服务器隔离开来(这意味着全都必须使用相同类型和版本的操作系统)。

虚拟化和准虚拟化(para-virtualization)

虚拟化最常使用的两种方法是全虚拟化 和准虚拟化。使用全虚拟化,在虚拟化的操作系统和硬件之间存在一个层,用于决定访问。这个层称为系统管理程序 或虚拟机监视器(VMM)。准虚拟化与之类似,但是系统管理程序会以一种更具协作性的方式进行操作。这是因为每个客户操作系统都了解自己正在虚拟化模式中运行,因此每个系统都与系统管理程序协作,来实现底层硬件的虚拟化。

全虚拟化的例子包括商业虚拟化解决方案 VMware,以及商业 IBM zSeries® 计算机上使用的 IBM System z9 Virtual Machine(z/VM)操作系统。准虚拟化的例子有 Xen 和 User-Mode-Linux (UML)。 KVM 也被认为是一个全虚拟化解决方案,不过我们稍后再介绍这个问题。

虚拟化的工作原理

我们首先简要介绍一下虚拟化技术及其涉及的元素。虚拟化解决方案的底部是要进行虚拟化的机器。这台机器可能直接支持虚拟化,也可能不会直接支持虚拟化;那么就需要系统管理程序 层的支持。系统管理程序,或称为 VMM,可以看作是平台硬件和操作系统的抽象化。在某些情况中,这个系统管理程序就是一个操作系统;此时,它就称为主机操作系统,如 图 1 所示。


图 1. 虚拟化的分层抽象
虚拟化的分层抽象

系统管理程序之上是客户机操作系统,也称为虚拟机(VM)。这些 VM 都是一些相互隔离的操作系统,将底层硬件平台视为自己所有。但是实际上,是系统管理程序为它们制造了这种假象。

处理器对于虚拟化的支持

由于平台虚拟化的优点非常有用,因此处理器供应商已经修改了自己的芯片来直接支持这种方法。这样做使处理器可以直接支持不同于客户机操作系 统的系统管理程序。对于 VMM 和 VM 来说,除了处理器状态(寄存器等)的管理不同之外,处理器还支持 I/O 和中断的虚拟化。要了解更多信息,请参看 参考资料

目前使用虚拟化解决方案的问题是,并非所有硬件都可以很好地支持虚拟化。较老的 x86 处理器根据执行范围对特定指令会产生不同结果。这就产生了一个问题,因为系统管理程序应该只能在一个最受保护的范围中执行。由于这个原因,诸如 VMWare 之类的虚拟化解决方案会提前扫描要执行的代码,从而将这些指令替换为一些陷阱指令(trap instruction),这样系统管理程序就可以正确地处理它们。Xen 可以支持一种协作的虚拟化方法,它不需要任何修改,因为客户机知道自己正在进行虚拟化,并已经进行了修改。KVM 会简单地忽略这个问题,如果您希望进行虚拟化,就强制必须在更新的硬件上运行。

刚开始会觉得这有些不方便,但是考虑到目前上市的较新机器都可以支持虚拟化(例如 Intel® VT 和 AMD SVM),用不了多久,这将成为标准方法而不是少数例外情况。有关可以支持虚拟化的处理器的更多信息,请参看 参考资料 和侧栏 处理器对于虚拟化的支持

KVM 系统管理程序

考虑到虚拟化技术的发展时间并不长,KVM 实际上还是一种相对来说比较新的技术。目前存在各具功能的开源技术,例如 Xen、Bochs、UML、Linux-VServer 和 coLinux,但是 KVM 目前正在被大量使用。另外,KVM 不再仅仅是一个全虚拟化解决方案,而将成为更大的解决方案的一部分。

KVM 所使用的方法是通过简单地加载内核模块而将 Linux 内核转换为一个系统管理程序。这个内核模块导出了一个名为 /dev/kvm 的设备,它可以启用内核的客户模式(除了传统的内核模式和用户模式)。有了 /dev/kvm 设备,VM 使自己的地址空间独立于内核或运行着的任何其他 VM 的地址空间。设备树(/dev)中的设备对于所有用户空间进程来说都是通用的。但是每个打开 /dev/kvm 的进程看到的是不同的映射(为了支持 VM 间的隔离)。

Linux 内核中 KVM 的源代码

您可以在 ./linux/drivers/kvm(V2.6.20 及更新版本)中找到 KVM 的源代码。这个目录包含了 KVM 的源文件,以及对于 Intel 和 AMD 扩展的处理器支持文件。

KVM 然后会简单地将 Linux 内核转换成一个系统管理程序(在安装 kvm 内核模块时)。由于标准 Linux 内核就是一个系统管理程序,因此它会从对标准内核的修改中获益良多(内存支持、调度程序等)。对这些 Linux 组件进行优化(例如 2.6 版本内核中的新 O(1) 调度程序)都可以让系统管理程序(主机操作系统)和 Linux 客户操作系统同时受益。但是 KVM 并不是第一个这样做的程序。UML 很久以前就将 Linux 内核转换成一个系统管理程序了。使用内核作为一个系统管理程序,您就可以启动其他操作系统,例如另一个 Linux 内核或 Windows 系统。

KVM

安装 KVM 之后,您可以在用户空间启动客户操作系统。每个客户操作系统都是主机操作系统(或系统管理程序)的一个单个进程。 图 2 提供了一个使用 KVM 进行虚拟化的视图。底部是能够进行虚拟化的硬件平台(目前指的是 Intel VT 或 AMD-SVM 处理器)。在裸硬件上运行的是系统管理程序(带有 KVM 模块的 Linux 内核)。这个系统管理程序与可以运行其他应用程序的普通 Linux 内核类似。但是这个内核也可以支持通过 kvm 工具加载的客户操作系统。最后,客户操作系统可以支持主机操作系统所支持的相同应用程序。


图 2. 使用 KVM 的虚拟化组件
使用 KVM 的虚拟化组件

记住 KVM 只是虚拟化解决方案的一部分。处理器直接提供了虚拟化支持(可以为多个操作系统虚拟化处理器)。内存可以通过 kvm 进行虚拟化(这在下一节中将会讨论)。最后,I/O 通过一个稍加修改的 QEMU 进程(执行每个客户操作系统进程的一个拷贝)进行虚拟化。

KVM 向 Linux 中引入了一种除现有的内核和用户模式之外的新进程模式。这种新模式就称为客户 模式,顾名思义,它用来执行客户操作系统代码(至少是一部分代码)。回想一下内核模式表示代码执行的特权模式,而用户模式则表示非特权模式(用于那些运行 在内核之外的程序)。根据运行内容和目的,执行模式可以针对不同的目的进行定义。客户模式的存在就是为了执行客户操作系统代码,但是只针对那些非 I/O 的代码。在客户模式中有两种标准模式,因此客户操作系统在客户模式中运行可以支持标准的内核,而在用户模式下运行则支持自己的内核和用户 空间应用程序。客户操作系统的用户模式可以用来执行 I/O 操作,这是单独进行管理的。

在客户操作系统上执行 I/O 的功能是由 QEMU 提供的。QEMU 是一个平台虚拟化解决方案,允许对一个完整的 PC 环境进行虚拟化(包括磁盘、图形适配器和网络设备)。客户操作系统所生成的任何 I/O 请求都会被中途截获,并重新发送到 QEMU 进程模拟的用户模式中。

KVM 通过 /dev/kvm 设备提供了内存虚拟化。每个客户操作系统都有自己的地址空间,并且是在实例化客户操作系统时映射的。映射给客户操作系统的物理内存实际上是映射给这个进程 的虚拟内存。为了支持客户物理地址到主机物理地址的转换,系统维护了一组影子页表(shadow page table)。处理器也可以通过在访问未经映射的内存位置时使用系统管理程序(主机内核)来支持内存转换进程。

实例化新客户操作系统

新客户操作系统的实例化是由一个名为 kvm 的工具提供的。这个工具可以与 kvm 模块协同工作,使用 /dev/kvm 来加载客户操作系统,将它与虚拟磁盘(主机操作系统中的一个普通文件)关联起来,然后启动客户操作系统。

通过一组在 /dev/kvm 设备上执行的 ioctls 可以提供控制支持。当第一次打开这个特殊文件时,就会创建一个新的 VM 对象,它与一个虚拟 CPU 关联在一起。您然后可以使用几个 ioctls 来创建一个虚拟 CPU,检查 kvm 版本,创建内存区域,然后启动一个虚拟 CPU。您可以使用 kvm 命令实现这种功能。在接下来的几节中,我们将介绍 kvm 命令,并给出几个受支持的 ioctls 的示例。

使用 KVM

如果硬件支持的话,使用 KVM 实际上非常简单。您需要一个具有虚拟化支持的处理器。通过查看 /proc/cpuinfo 可以知道系统是否支持虚拟化。这个文件指定了是否支持 vmx(Intel)或 svm(AMD)扩展。

接下来,您需要一个启用了 KVM 支持的 Linux 内核。您可以在 Device Drivers > Virtualization 下的内核配置中完成这种配置。还必须启用处理器对环境的支持。另外,还必须具有 kvm 和 qemu 用户空间应用程序。更多信息请参见 参考资料

有了启用了虚拟化支持的引导内核,接下来的一个步骤是为客户操作系统创建一个磁盘映像。您可以使用 qeumu-img 来完成此操作,如下所示。注意这个映像的大小是 4GB,但是使用 QEMU 的写时复制格式(copy-on-write,qcow)时,整个文件将根据需要增长,而不是完全占据这 4 GB 的空间。

$ qemu-img create -f qcow vm-disk.img 4G
			

 

在创建虚拟磁盘之后,就可以将客户操作系统加载到其上。下面的例子假设客户操作系统是在 CD-ROM 上。除了使用 CD-ROM ISO 映像来填充虚拟磁盘之外,还必须在结束时启动这个映像。

$ kvm -no-acpi -m 384 -cdrom guestos.iso -hda vm-disk.img -boot d
			

 

Ari Kivity 已经编写了一组测试工具来测试 KVM,而不需要全部的设备模型。下面的代码片断(来自于 kvm-12/user/main.c)从较高的层次上查看了 VM 的启动(请参见 清单 1)。控制特性是由内核中的 ioctls 提供的(具体来说,在 ./linux-2.6.20/drivers/kvm/kvm_main.c 文件中)。

对 kvm_init 的调用会打开 /dev/kvm 设备,检查版本号(由 KVM 内核模块导出),然后分配一个 KVM 上下文对象并填充一些回调函数。kvm_create 函数会建立并映射两个内存区域,然后使用 ioctl(KVM_CREATE_VCPU)创建一个虚拟 CPU(VCPU)。

load_file 函数然后会将映像加载到给定的 VM 的地址空间中,然后调用 kvm_run 执行该 VM(使用 ioctl KVM_RUN)。尽管这个过程非常简单,但是它解释了如何使用 KVM 实例化新客户操作系统。


清单 1. 测试 KVM 系统管理程序的应用程序片断

				
int main()
{
	void *vm_mem;

	kvm = kvm_init(&test_callbacks, 0);
	if (!kvm) {
	    fprintf(stderr, "kvm_init failed\n");
	    return 1;
	}
	if (kvm_create(kvm, 128 * 1024 * 1024, &vm_mem) < 0) {
	    kvm_finalize(kvm);
	    fprintf(stderr, "kvm_create failed\n");
	    return 1;
	}
	if (ac > 1)
	    if (strcmp(av[1], "-32") != 0)
		load_file(vm_mem + 0xf0000, av[1]);
	    else
		enter_32(kvm);
	if (ac > 2)
	    load_file(vm_mem + 0x100000, av[2]);
	kvm_show_regs(kvm, 0);

	kvm_run(kvm, 0);

	return 0;
}

 

结束语

KVM 是解决虚拟化问题的一个有趣的解决方案,但是由于它是第一个进入内核的虚拟化解决方案,很难想象它会很快用于服务器虚拟化。还有其他一些方法一直在为进入 内核而竞争(例如 UML 和 Xen),但是由于 KVM 需要的修改较少,并且可以将标准内核转换成一个系统管理程序,因此它的优势不言而喻。

KVM 的另外一个优点是它是内核本身的一部分,因此可以利用内核的优化和改进。与其他独立的系统管理程序解决方案相比,这种方法是一种不会过时的技术。KVM 两个最大的缺点是需要较新的能够支持虚拟化的处理器,以及一个用户空间的 QEMU 进程来提供 I/O 虚拟化。但是不论好坏,KVM 位于内核中,这对于现有解决方案来说是一个巨大的飞跃。



本文转自 念槐聚 博客园博客,原文链接:http://www.cnblogs.com/haochuang/archive/2011/12/19/2293721.html,如需转载请自行联系原作者

相关文章
|
5天前
|
安全 Linux KVM
Linux虚拟化技术:从Xen到KVM
Xen和KVM是Linux平台上两种主要的虚拟化技术,各有优缺点和适用场景。通过对比两者的架构、性能、安全性、管理复杂性和硬件依赖性,可以更好地理解它们的适用场景和选择依据。无论是高性能计算、企业虚拟化还是云计算平台,合理选择和配置虚拟化技术是实现高效、稳定和安全IT环境的关键。
39 8
|
24天前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
24天前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
25天前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
25天前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
27天前
|
负载均衡 算法 Linux
深入探索Linux内核调度机制:公平与效率的平衡####
本文旨在剖析Linux操作系统内核中的进程调度机制,特别是其如何通过CFS(完全公平调度器)算法实现多任务环境下资源分配的公平性与系统响应速度之间的微妙平衡。不同于传统摘要的概览性质,本文摘要将直接聚焦于CFS的核心原理、设计目标及面临的挑战,为读者揭开Linux高效调度的秘密。 ####
35 3
|
30天前
|
负载均衡 算法 Linux
深入探索Linux内核调度器:公平与效率的平衡####
本文通过剖析Linux内核调度器的工作机制,揭示了其在多任务处理环境中如何实现时间片轮转、优先级调整及完全公平调度算法(CFS),以达到既公平又高效地分配CPU资源的目标。通过对比FIFO和RR等传统调度策略,本文展示了Linux调度器如何在复杂的计算场景下优化性能,为系统设计师和开发者提供了宝贵的设计思路。 ####
41 6
|
29天前
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
存储 网络协议 Linux