kvm虚拟化技术原理 pdf

2016-10-18 21:39:25 nirendao 阅读数 3740

第一章和第二章

第一章 虚拟化和云计算

Saas(软件即服务):将已经部署好的软件作为一种服务来提供,比如:Google Docs, Google Apps
Paas(平台即服务):将开发环境作为一种服务来提供。
Iaas(基础设施即服务):将多台服务器组成的“云端”基础设施作为计量服务提供给客户。

软件虚拟化:

利用纯软件的方法在现有的物理平台上(往往并不支持硬件虚拟化)实现对物理平台访问的截获和模拟。
常见的软件虚拟机如QEMU,它是通过纯软件来仿真x86平台处理器的取指、解码和执行,客户机的指令并不在物理 平台上直接执行。
由于所有指令都是软件模拟的,因此性能往往比较差,但是可以在同一平台上模拟不同架构平台的虚拟机。

VMware的软件虚拟化使用了动态二进制翻译技术。虚拟机监控机(VMM)在可控制的范围内,允许客户机的指令在物理平台上直接运行。但是,客户机指令在运行前会被虚拟机监控机扫描,其中突破虚拟机监控机限制的指令会被动态替换为可以在物理平台上直接运行的安全指令,或者替换为对虚拟机监控机的软件调用。优点是比纯软件模拟性能有大幅提升,缺点是失去了跨平台虚拟化的能力。

硬件虚拟化:

物理平台本身提供对特殊指令的截获和重定向的支持;甚至新的硬件会提供额外的资源来帮助软件实现对关键硬件资源的虚拟化,从而提升性能。

以x86平台的虚拟化为例,支持虚拟技术的x86 CPU 带有特别优化过的指令集来控制虚拟过程,通过这些指令集,VMM很容易将客户机置于一种受限制的模式下运行,一旦客户机试图访问物理资源,硬件会暂停客户机的运行,将控制权交回给VMM处理。VMM可以将客户机在受限模式下对一些特殊资源的访问完全由硬件重定向到VMM指定的虚拟资源。整个过程不需要暂停客户机的运行和VMM软件的参与。

由于虚拟化硬件可提供全新的架构,支持操作系统直接在其上运行,无需进行二进制转码,减少了相关的性能开销,极大简化了VMM的设计,进而使得VMM能够按照通用标准进行编写,性能更加强大。

准虚拟化:

改动客户机操作系统,使它以为自己运行在虚拟环境下,能够同虚拟机监控机协同工作。所以,准虚拟化需要修改客户机的操作系统的源代码来实现主动通知。

Xen是准虚拟化的一个例子,它适用于Linux这样的开源操作系统,而不适合于Windows这样的闭源操作系统。

全虚拟化:

支持运行任何理论上可在真实物理平台上运行的操作系统。不需要对客户机操作系统进行任何修改。

KVM

KVM的开发人员并不是从底层开始新写一个Hypervisor,而是选择了基于Linux Kernel,通过加载新的模块而使Linux Kernel变身成为一个Hypervisor.
KVM目前设计为通过可加载的内核模块,支持广泛的客户机操作系统,包括Windows.

在KVM架构中,虚拟机实现为常规的Linux进程,由标准Linux调度程序进行调度。事实上,每个虚拟CPU实现为一个常规的Linux进程。这使得KVM可以享受Linux内核的所有功能。

KVM本身不执行任何模拟,需要用户空间程序通过/dev/kvm接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的I/O,并将它的视频显示映射回宿主的显示屏。这个应用程序(注:上述的“用户空间程序”)就是大名鼎鼎的QEMU.

REHL6.x系统中的一个KVM客户机可以支持160个虚拟CPU和多达2TB的内存,KVM宿主机支持4096个CPU核心和多达64TB的内存。


第二章 KVM原理简介

操作系统内核设计分为:微内核和单内核。

单内核指的是整个内核从整体上作为一个单独的大过程来实现,并且同时运行在一个单独的地址空间内。所有的内核服务都在这样一个大的内核空间运行,内核之间的通信可以简单地实现为函数调用。

对于微内核来说,内核的功能被划分为多个独立的过程,每一个过程叫做一个服务器。多个服务器都运行在自己的地址空间,只有少量核心的服务器运行在特权模式下,服务器之间的通信采用了进程间通信机制。独立的服务器进程提高系统的健壮性,但是进程间通信由于涉及内核空间和用户空间的上下文切换,其开销比函数调用大得多。

Linux采用实用主义的设计:Linux内核被设计成单内核以满足性能要求;但同时,Linux内核还具有模块化设计和动态装载内核模块的能力。除了诸如进程切换、内存管理等核心内核功能,将大部分内核功能作为单独的内核模块设计并实现。这些内核模块编译好后以单独的二进制文件的形式存在,内核在运行过程中,按照需求,动态地加载并链接进入内核空间运行。不使用的模块还可以在运行过程中动态卸载。这样的设计,既保证了内核的性能,也改进了传统单内核设计的灵活性。
KVM就是以内核模块的形式存在,为Linux内核增加了虚拟化的功能。

从虚拟机的基本架构来区分,分为2种:类型一和类型二。
类型一:
系统上电之后首先加载运行虚拟机监控程序,而传统的操作系统则是运行在其创建的虚拟机中。
类型一的虚拟机监控程序,可以视为一个特别为虚拟机而优化裁剪的操作系统内核。
著名的开源虚拟化软件Xen、商业软件VMware ESX/ESXi 和微软的Hyper-V就是类型一的代表。

类型二:
在系统上电之后仍然运行一般意义的操作系统(也就是俗称的宿主机操作系统),虚拟机监控程序作为特殊的应用程序,可以是为操作系统功能的扩展。
对于类型二虚拟机来说,最大的优势在于可以充分利用现有的操作系统;但也会受到宿主机操作系统的一些限制。
KVM、VMware Workstation、VirtualBox就是属于类型二虚拟机。

KVM模块

P38-39

KVM模块的主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚拟客户机的运行提供一定的支持。
KVM仅支持硬件虚拟化。

以KVM在Intel公司的CPU上运行为例:
1. 在内核被加载的时候,KVM模块会先初始化内部的数据结构;
2. 做好准备之后,KVM模块检测系统当前的CPU,然后打开CPU控制寄存器CR4中的虚拟化模式开关;
3. 通过执行VMXON指令将宿主操作系统(包括KVM模块本身)置于虚拟化模式的根模式;
4. 最后,KVM模块创建特殊设备文件 /dev/kvm 并等待来自用户空间的命令;
5. 接下来,虚拟机的创建和运行将是一个用户空间应用程序(QEMU)和KVM模块相互配合的过程。

KVM模块和用户空间QEMU的通信接口主要是一系列针对特殊设备文件的IOCTL调用。
KVM模块加载之初,只存在 /dev/kvm 文件,而针对该文件的最重要的IOCTL调用就是“创建虚拟机”,其可以被理解为KVM为了某个特定的虚拟客户机(用户空间程序创建并初始化)创建对应的内核数据结构。同时,KVM还会返回一个文件句柄来代表所创建的虚拟机。

针对虚拟处理器最重要的IOCTL调用就是“执行虚拟处理器”。通过它,用户空间准备好的虚拟机在KVM模块的支持下,被置于虚拟化模式的非根模式下,开始执行二进制指令。在非根模式下,所有敏感的二进制指令都会被处理器捕捉到,处理器在保存现场之后,自动切换到根模式,由KVM决定如何进一步处理(要么由KVM模块直接处理,要么返回用户空间交由用户空间程序处理)。

除了处理器的虚拟化,内存虚拟化也是由KVM模块实现的。实际上,这一部分是一个虚拟机实现代码中代码量最大、实现最复杂的部分(至少在硬件支持二维地址翻译之前是这样的)。

处理器对设备的访问主要是通过IO指令和MMIO,其中IO指令会被处理器直接截获,MMIO会通过配置内存虚拟化来捕捉。但是,外设的模拟一般并不由KVM模块负责。一般来说,只有对性能要求比较高的虚拟设备才会由KVM内核模块来直接负责,比如虚拟中断控制器和虚拟时钟。大部分输入输出设备还是会交给用户态程序QEMU负责。

QEMU设备模型

QEMU本身并不是KVM的一部分,其自身就是一个著名的开源虚拟机软件。它是一个纯软件的实现,所以性能低下。

为了简化开发和代码重用,KVM在QEMU的基础上进行了修改。在虚拟机运行期间,QEMU会通过KVM模块提供的系统调用计入内核,由KVM模块负责将虚拟机置于处理器的特殊模式运行。遇到虚拟机进行输入输出操作,KVM模块会从上次的系统调用出口处返回QEMU,有QEMU来负责解析和模拟这些设备。

2013-11-12 09:22:00 weixin_34303897 阅读数 0

kvm虚拟化技术:实战与原理解析


在具体内容上,本书不仅系统介绍了 KVM虚拟机的功能、特性和使用方 法,而且还深入地剖析了 KVM虚拟机的核心技术和工作原理,对 KVM做了全面而透彻的讲解。


对其内容详细阅读

转载于:https://my.oschina.net/u/856019/blog/175585

2019-08-25 13:30:15 weixin_44800915 阅读数 159

KVM 介绍(二):CPU 和内存虚拟化

1. 为什么需要 CPU 虚拟化

X86 操作系统是设计在直接运行在裸硬件设备上的,因此它们自动认为它们完全占有计算机硬件。x86 架构提供四个特权级别给操作系统和应用程序来访问硬件。 Ring 是指 CPU 的运行级别,Ring 0是最高级别,Ring1次之,Ring2更次之…… 就 Linux+x86 来说,

  • 操作系统(内核)需要直接访问硬件和内存,因此它的代码需要运行在最高运行级别
    Ring0上,这样它可以使用特权指令,控制中断、修改页表、访问设备等等。
  • 应用程序的代码运行在最低运行级别上ring3上,不能做受控操作。如果要做,比如要访问磁盘,写文件,那就要通过执行系统调用(函数),执行系统调用的时候,CPU的运行级别会发生从ring3到ring0的切换,并跳转到系统调用对应的内核代码位置执行,这样内核就为你完成了设备访问,完成之后再从ring0返回ring3。这个过程也称作用户态和内核态的切换。

那么,虚拟化在这里就遇到了一个难题,因为宿主操作系统是工作在 ring0 的,客户操作系统就不能也在ring0 了,但是它不知道这一点,以前执行什么指令,现在还是执行什么指令,但是没有执行权限是会出错的。所以这时候虚拟机管理程序(VMM)需要避免这件事情发生。虚机怎么通过 VMM 实现 Guest CPU 对硬件的访问,根据其原理不同有三种实现技术:

  1. 全虚拟化
  2. 半虚拟化
  3. 硬件辅助的虚拟化

1.1 基于二进制翻译的全虚拟化(Full Virtualization with Binary Translation)

客户操作系统运行在 Ring 1,它在执行特权指令时,会触发异常(CPU的机制,没权限的指令会触发异常),然后 VMM 捕获这个异常,在异常里面做翻译,模拟,最后返回到客户操作系统内,客户操作系统认为自己的特权指令工作正常,继续运行。但是这个性能损耗,就非常的大,简单的一条指令,执行完,了事,现在却要通过复杂的异常处理过程。

异常 “捕获(trap)-翻译(handle)-模拟(emulate)” 过程:

1.2. 超虚拟化(或者半虚拟化/操作系统辅助虚拟化 Paravirtualization)

半虚拟化的思想就是,修改操作系统内核,替换掉不能虚拟化的指令,通过超级调用(hypercall)直接和底层的虚拟化层hypervisor来通讯,hypervisor 同时也提供了超级调用接口来满足其他关键内核操作,比如内存管理、中断和时间保持。

这种做法省去了全虚拟化中的捕获和模拟,大大提高了效率。所以像XEN这种半虚拟化技术,客户机操作系统都是有一个专门的定制内核版本,和x86、mips、arm这些内核版本等价。这样以来,就不会有捕获异常、翻译、模拟的过程了,性能损耗非常低。这就是XEN这种半虚拟化架构的优势。这也是为什么XEN只支持虚拟化Linux,无法虚拟化windows原因,微软不改代码啊。

1.3. 硬件辅助的全虚拟化

2005年后,CPU厂商Intel 和 AMD 开始支持虚拟化了。 Intel 引入了 Intel-VT (Virtualization Technology)技术。这种 CPU,有 VMX root operation 和 VMX non-root operation两种模式,两种模式都支持Ring 0 ~ Ring 3 共 4 个运行级别。这样,VMM 可以运行在 VMX root operation模式下,客户 OS 运行在VMX non-root operation模式下。

而且两种操作模式可以互相转换。运行在 VMX root operation 模式下的 VMM 通过显式调用 VMLAUNCH 或 VMRESUME 指令切换到 VMX non-root operation 模式,硬件自动加载 Guest OS 的上下文,于是 Guest OS 获得运行,这种转换称为 VM entry。Guest OS 运行过程中遇到需要 VMM 处理的事件,例如外部中断或缺页异常,或者主动调用 VMCALL 指令调用 VMM 的服务的时候(与系统调用类似),硬件自动挂起 Guest OS,切换到 VMX root operation 模式,恢复 VMM 的运行,这种转换称为 VM exit。VMX root operation 模式下软件的行为与在没有 VT-x 技术的处理器上的行为基本一致;而VMX non-root operation 模式则有很大不同,最主要的区别是此时运行某些指令或遇到某些事件时,发生 VM exit。

也就说,硬件这层就做了些区分,这样全虚拟化下,那些靠“捕获异常-翻译-模拟”的实现就不需要了。而且CPU厂商,支持虚拟化的力度越来越大,靠硬件辅助的全虚拟化技术的性能逐渐逼近半虚拟化,再加上全虚拟化不需要修改客户操作系统这一优势,全虚拟化技术应该是未来的发展趋势。

2. KVM CPU 虚拟化

KVM 是基于CPU 辅助的全虚拟化方案,它需要CPU虚拟化特性的支持。

2.1. CPU 物理特性

这个命令查看主机上的CPU 物理情况:

要支持 KVM, Intel CPU 的 vmx 或者 AMD CPU 的 svm 扩展必须生效了:

2.2 CPU 服务器架构:SMP,NMP,NUMA

从系统架构来看,目前的商用服务器大体可以分为三类:

  • 多处理器结构 (SMP :Symmetric Multi-Processor):所有的CPU共享全部资源,如总线,内存和I/O系统等,操作系统或管理数据库的复本只有一个,这种系统有一个最大的特点就是共享所有资源。多个CPU之间没有区别,平等地访问内存、外设、一个操作系统。SMP 服务器的主要问题,那就是它的扩展能力非常有限。实验证明, SMP 服务器 CPU 利用率最好的情况是 2 至 4 个 CPU
  • 海量并行处理结构 (MPP : Massive Parallel Processing) :NUMA 服务器的基本特征是具有多个 CPU 模块,每个 CPU 模块由多个 CPU( 如 4 个 ) 组成,并且具有独立的本地内存、 I/O 槽口等。在一个物理服务器内可以支持上百个 CPU 。但 NUMA 技术同样有一定缺陷,由于访问远地内存的延时远远超过本地内存,因此当 CPU 数量增加时,系统性能无法线性增加。
  • MPP 模式则是一种分布式存储器模式,能够将更多的处理器纳入一个系统的存储器。一个分布式存储器模式具有多个节点,每个节点都有自己的存储器,可以配置为SMP模式,也可以配置为非SMP模式。单个的节点相互连接起来就形成了一个总系统。MPP可以近似理解成一个SMP的横向扩展集群,MPP一般要依靠软件实现。
  • 非一致存储访问结构 (NUMA :Non-Uniform Memory Access):它由多个 SMP 服务器通过一定的节点互联网络进行连接,协同工作,完成相同的任务,从用户的角度来看是一个服务器系统。其基本特征是由多个 SMP 服务器 ( 每个 SMP 服务器称节点 ) 通过节点互联网络连接而成,每个节点只访问自己的本地资源 ( 内存、存储等 ) ,是一种完全无共享 (Share Nothing) 结构。

查看你的服务器的 CPU 架构:

2.2 KVM CPU 虚拟化

2.2.1 KVM 虚机的创建过程

可见:

(1)qemu-kvm 通过对 /dev/kvm 的一系列 ICOTL 命令控制虚机,比如

(2)一个 KVM 虚机即一个 Linux qemu-kvm 进程,与其他 Linux 进程一样被Linux 进程调度器调度。

(3)KVM 虚机包括虚拟内存、虚拟CPU和虚机 I/O设备,其中,内存和 CPU 的虚拟化由 KVM 内核模块负责实现,I/O 设备的虚拟化由 QEMU 负责实现。

(3)KVM户机系统的内存是 qumu-kvm 进程的地址空间的一部分。

(4)KVM 虚机的 vCPU 作为线程运行在 qemu-kvm 进程的上下文中。

vCPU、QEMU 进程、LInux 进程调度和物理CPU之间的逻辑关系:

2.2.2 因为 CPU 中的虚拟化功能的支持,并不存在虚拟的 CPU,KVM Guest 代码是运行在物理 CPU 之上

根据上面的 1.3 章节,支持虚拟化的 CPU 中都增加了新的功能。以 Intel VT 技术为例,它增加了两种运行模式:VMX root 模式和 VMX nonroot 模式。通常来讲,主机操作系统和 VMM 运行在 VMX root 模式中,客户机操作系统及其应用运行在 VMX nonroot 模式中。因为两个模式都支持所有的 ring,因此,客户机可以运行在它所需要的 ring 中(OS 运行在 ring 0 中,应用运行在 ring 3 中),VMM 也运行在其需要的 ring 中(对 KVM 来说,QEMU 运行在 ring 3,KVM 运行在 ring 0)。CPU 在两种模式之间的切换称为 VMX 切换。从 root mode 进入 nonroot mode,称为 VM entry;从 nonroot mode 进入 root mode,称为 VM exit。可见,CPU 受控制地在两种模式之间切换,轮流执行 VMM 代码和 Guest OS 代码。

对 KVM 虚机来说,运行在 VMX Root Mode 下的 VMM 在需要执行 Guest OS 指令时执行 VMLAUNCH 指令将 CPU 转换到 VMX non-root mode,开始执行客户机代码,即 VM entry 过程;在 Guest OS 需要退出该 mode 时,CPU 自动切换到 VMX Root mode,即 VM exit 过程。可见,KVM 客户机代码是受 VMM 控制直接运行在物理 CPU 上的。QEMU 只是通过 KVM 控制虚机的代码被 CPU 执行,但是它们本身并不执行其代码。也就是说,CPU 并没有真正的被虚级化成虚拟的 CPU 给客户机使用。

这篇文章(http://frankdenneman.nl/2013/09/18/vcpu-configuration-performance-impact-between-virtual-sockets-and-virtual-cores/)是关于 vSphere 中 CPU 虚拟化的,我觉得它和 KVM CPU 虚拟化存在很大的一致。下图是使用 2 socket 2 core 共 4 个 vCPU 的情形:

几个概念:socket (颗,CPU 的物理单位),core (核,每个 CPU 中的物理内核),thread (超线程,通常来说,一个 CPU core 只提供一个 thread,这时客户机就只看到一个 CPU;但是,超线程技术实现了 CPU 核的虚拟化,一个核被虚拟化出多个逻辑 CPU,可以同时运行多个线程)。

上图分三层,他们分别是是VM层,VMKernel层和物理层。对于物理服务器而言,所有的CPU资源都分配给单独的操作系统和上面运行的应用。应用将请求先发送给操作系统,然后操作系统调度物理的CPU资源。在虚拟化平台比如 KVM 中,在VM层和物理层之间加入了VMkernel层,从而允许所有的VM共享物理层的资源。VM上的应用将请求发送给VM上的操作系统,然后操纵系统调度Virtual CPU资源(操作系统认为Virtual CPU和物理 CPU是一样的),然后VMkernel层对多个物理CPU Core进行资源调度,从而满足Virtual CPU的需要。在虚拟化平台中OS CPU Scheduler和Hyperviisor CPU Scheduler都在各自的领域内进行资源调度。

KVM 中,可以指定 socket,core 和 thread 的数目,比如设置 “-smp 5,sockets=5,cores=1,threads=1”,则 vCPU 的数目为 5*1*1 = 5。客户机看到的是基于 KVM vCPU 的 CPU 核,而 vCPU 作为 QEMU 线程被 Linux 作为普通的线程/轻量级进程调度到物理的 CPU 核上。至于你是该使用多 socket 和多core,这篇文章有仔细的分析,其结论是在 VMware ESXi 上,性能没什么区别,只是某些客户机操作系统会限制物理 CPU 的数目,这种情况下,可以使用少 socket 多 core。

2.2.3 客户机系统的代码是如何运行的

一个普通的 Linux 内核有两种执行模式:内核模式(Kenerl)和用户模式(User)。为了支持带有虚拟化功能的 CPU,KVM 向 Linux 内核增加了第三种模式即客户机模式(Guest),该模式对应于 CPU 的 VMX non-root mode。

KVM 内核模块作为 User mode 和 Guest mode 之间的桥梁:

  • User mode 中的 QEMU-KVM会通过 ICOTL 命令来运行虚拟机
  • KVM 内核模块收到该请求后,它先做一些准备工作,比如将 VCPU 上下文加载到 VMCS (virtual machine control structure)等,然后驱动 CPU 进入 VMX non-root 模式,开始执行客户机代码

三种模式的分工为:

  • Guest 模式:执行客户机系统非 I/O 代码,并在需要的时候驱动 CPU 退出该模式
  • Kernel 模式:负责将 CPU 切换到 Guest mode 执行 Guest OS 代码,并在 CPU 退出 Guest mode 时回到 Kenerl 模式
  • User 模式:代表客户机系统执行 I/O 操作

QEMU-KVM 相比原生 QEMU 的改动:

  • 原生的 QEMU 通过指令翻译实现 CPU 的完全虚拟化,但是修改后的 QEMU-KVM 会调用 ICOTL 命令来调用 KVM 模块。
  • 原生的 QEMU 是单线程实现,QEMU-KVM 是多线程实现。

主机 Linux 将一个虚拟视作一个 QEMU 进程,该进程包括下面几种线程:

  • I/O 线程用于管理模拟设备
  • vCPU 线程用于运行 Guest 代码
  • 其它线程,比如处理 event loop,offloaded tasks 等的线程

在我的测试环境中(RedHata Linux 作 Hypervisor):

这篇文章(http://blog.chinaunix.net/uid-26000137-id-3761114.html) 谈谈了这些线程的情况。

(图片来源:http://www.cnblogs.com/popsuper1982/p/3815398.html)

2.2.4 从客户机线程到物理 CPU 的两次调度

要将客户机内的线程调度到某个物理 CPU,需要经历两个过程:

  1. 客户机线程调度到客户机物理CPU 即 KVM vCPU,该调度由客户机操作系统负责,每个客户机操作系统的实现方式不同。在 KVM 上,vCPU 在客户机系统看起来就像是物理 CPU,因此其调度方法也没有什么不同。
  2. vCPU 线程调度到物理 CPU 即主机物理 CPU,该调度由 Hypervisor 即 Linux 负责。

KVM 使用标准的 Linux 进程调度方法来调度 vCPU 进程。Linux 系统中,线程和进程的区别是进程有独立的内核空间,线程是代码的执行单位,也就是调度的基本单位。Linux 中,线程是就是轻量级的进程,也就是共享了部分资源(地址空间、文件句柄、信号量等等)的进程,所以线程也按照进程的调度方式来进行调度。

(1)Linux 进程调度原理可以参考这篇文章http://www.cnblogs.com/zhaoyl/archive/2012/09/04/2671156.html)。通常情况下,在SMP系统中,Linux内核的进程调度器根据自有的调度策略将系统中的一个可运行(runable)进程调度到某个CPU上执行。下面是 Linux 进程的状态机:

(2)处理器亲和性:可以设置 vCPU 在指定的物理 CPU 上运行,具体可以参考这篇文章http://blog.chinaunix.net/uid-26000137-id-3695749.html) 和这篇文章http://frankdenneman.nl/2011/01/11/beating-a-dead-horse-using-cpu-affinity/)。

根据 Linux 进程调度策略,可以看出,在 Linux 主机上运行的 KVM 客户机的总 vCPU 数目最好是不要超过物理 CPU 内核数,否则,会出现线程间的 CPU 内核资源竞争,导致有虚机因为 vCPU 进程等待而导致速度很慢。

关于这两次调度,业界有很多的研究,比如上海交大的论文 Schedule Processes, not VCPUs 提出动态地减少 vCPU 的数目即减少第二次调度。

另外,这篇文章http://www.vmware.com/files/pdf/techpaper/VMware-vSphere-CPU-Sched-Perf.pdf) 谈到的是 vSphere CPU 的调度方式,有空的时候可以研究下并和 KVM vCPU的调度方式进行比较。

2.3 客户机CPU结构和模型

KVM 支持 SMP 和 NUMA 多CPU架构的主机和客户机。对 SMP 类型的客户机,使用 “-smp”参数:

对 NUMA 类型的客户机,使用 “-numa”参数:

CPU 模型(models)定义了哪些主机的 CPU 功能(features)会被暴露给客户机操作系统。为了在具有不同 CPU 功能的主机之间做安全的迁移,qemu-kvm 往往不会将主机CPU的所有功能都暴露给客户机。其原理如下:

你可以运行 qemu-kvm -cpu ?命令来获取主机所支持的 CPU 模型列表。

每个Hypervisor 都有自己的策略,来定义默认上哪些CPU功能会被暴露给客户机。至于哪些功能会被暴露给客户机系统,取决于客户机的配置。qemu32 和 qemu64 是基本的客户机 CPU 模型,但是还有其他的模型可以使用。你可以使用 qemu-kvm 命令的 -cpu <model> 参数来指定客户机的 CPU 模型,还可以附加指定的 CPU 特性。"-cpu" 会将该指定 CPU 模型的所有功能全部暴露给客户机,即使某些特性在主机的物理CPU上不支持,这时候QEMU/KVM 会模拟这些特性,因此,这时候也许会出现一定的性能下降。

RedHat Linux 6 上使用默认的 cpu64-rhe16 作为客户机 CPU model:

你可以指定特定的 CPU model 和 feature:

你也可以直接使用 -cpu host,这样的话会客户机使用和主机相同的 CPU model。

2.4 客户机 vCPU 数目的分配方法

  1. 不是客户机的 vCPU 越多,其性能就越好,因为线程切换会耗费大量的时间;应该根据负载需要分配最少的 vCPU。
  2. 主机上的客户机的 vCPU 总数不应该超过物理 CPU 内核总数。不超过的话,就不存在 CPU 竞争,每个 vCPU 线程在一个物理 CPU 核上被执行;超过的话,会出现部分线程等待 CPU 以及一个 CPU 核上的线程之间的切换,这会有 overhead。
  3. 将负载分为计算负载和 I/O 负载,对计算负载,需要分配较多的 vCPU,甚至考虑 CPU 亲和性,将指定的物理 CPU 核分给给这些客户机。

这篇文章(http://my.oschina.net/chape/blog/173981)介绍了一些指导性方法,摘要如下:

我们来假设一个主机有 2 个socket,每个 socket 有 4 个core。主频2.4G MHZ 那么一共可用的资源是 2*4*2.4G= 19.2G MHZ。假设主机上运行了三个VM,VM1和VM2设置为1socket*1core,VM3设置为1socket*2core。那么VM1和VM2分别有1个vCPU,而VM3有2个vCPU。假设其他设置为缺省设置。

那么三个VM获得该主机CPU资源分配如下:VM1:25%; VM2:25%; VM3:50%

假设运行在VM3上的应用支持多线程,那么该应用可以充分利用到所非配的CPU资源。2vCPU的设置是合适的。假设运行在VM3上的应用不支持多线程,该应用根本无法同时使用利用2个vCPU. 与此同时,VMkernal层的CPU Scheduler必须等待物理层中两个空闲的pCPU,才开始资源调配来满足2个vCPU的需要。在仅有2vCPU的情况下,对该VM的性能不会有太大负面影响。但如果分配4vCPU或者更多,这种资源调度上的负担有可能会对该VM上运行的应用有很大负面影响。

确定 vCPU 数目的步骤。假如我们要创建一个VM,以下几步可以帮助确定合适的vCPU数目

1 了解应用并设置初始值

该应用是否是关键应用,是否有Service
Level Agreement。一定要对运行在虚拟机上的应用是否支持多线程深入了解。咨询应用的提供商是否支持多线程和SMP(Symmetricmulti-processing)。参考该应用在物理服务器上运行时所需要的CPU个数。如果没有参照信息,可设置1vCPU作为初始值,然后密切观测资源使用情况。

2 观测资源使用情况

确定一个时间段,观测该虚拟机的资源使用情况。时间段取决于应用的特点和要求,可以是数天,甚至数周。不仅观测该VM的CPU使用率,而且观测在操作系统内该应用对CPU的占用率。特别要区分CPU使用率平均值和CPU使用率峰值。

假如分配有4个vCPU,如果在该VM上的应用的CPU

  • 使用峰值等于25%,也就是仅仅能最多使用25%的全部CPU资源,说明该应用是单线程的,仅能够使用一个vCPU (4 * 25% =1 )
  • 平均值小于38%,而峰值小于45%,考虑减少 vCPU 数目
  • 平均值大于75%,而峰值大于90%,考虑增加 vCPU 数目

3 更改vCPU数目并观测结果

每次的改动尽量少,如果可能需要4vCPU,先设置2vCPU在观测性能是否可以接受。

2. KVM 内存虚拟化

2.1 内存虚拟化的概念

除了CPU 虚拟化,另一个关键是内存虚拟化,通过内存虚拟化共享物理系统内存,动态分配给虚拟机。虚拟机的内存虚拟化很象现在的操作系统支持的虚拟内存方式,应用程序看到邻近的内存地址空间,这个地址空间无需和下面的物理机器内存直接对应,操作系统保持着虚拟页到物理页的映射。现在所有的 x86 CPU 都包括了一个称为内存管理的模块MMU(Memory Management Unit)和 TLB(Translation Lookaside Buffer),通过MMU和TLB来优化虚拟内存的性能。

KVM 实现客户机内存的方式是,利用mmap系统调用,在QEMU主线程的虚拟地址空间中申明一段连续的大小的空间用于客户机物理内存映射。

(图片来源:http://blog.csdn.net/lux_veritas/article/details/9383643 HVA 同下面的 MA,GPA 同下面的 PA,GVA 同下面的 VA)

在有两个虚机的情况下,情形是这样的:

可见,KVM 为了在一台机器上运行多个虚拟机,需要增加一个新的内存虚拟化层,也就是说,必须虚拟 MMU 来支持客户操作系统,来实现 VA -> PA -> MA 的翻译。客户操作系统继续控制虚拟地址到客户内存物理地址的映射(VA -> PA),但是客户操作系统不能直接访问实际机器内存,因此VMM 需要负责映射客户物理内存到实际机器内存(PA ->
MA)

VMM 内存虚拟化的实现方式:

  • 软件方式:通过软件实现内存地址的翻译,比如 Shadow page table (影子页表)技术
  • 硬件实现:基于 CPU 的辅助虚拟化功能,比如 AMD 的 NPT 和 Intel 的 EPT 技术

影子页表技术:

2.2 KVM 内存虚拟化

KVM 中,虚机的物理内存即为 qemu-kvm 进程所占用的内存空间。KVM 使用 CPU 辅助的内存虚拟化方式。在 Intel 和 AMD 平台,其内存虚拟化的实现方式分别为:

  • AMD 平台上的 NPT (Nested Page Tables)技术
  • Intel 平台上的 EPT (Extended Page Tables)技术

EPT 和 NPT采用类似的原理,都是作为 CPU 中新的一层,用来将客户机的物理地址翻译为主机的物理地址。关于 EPT, Intel 官方文档中的技术如下(实在看不懂...)

EPT的好处是,它的两阶段记忆体转换,特点就是将 Guest Physical Address → System Physical Address,VMM不用再保留一份 SPT(Shadow Page Table),以及以往还得经过 SPT 这个转换过程。除了降低各部虚拟机器在切换时所造成的效能损耗外,硬体指令集也比虚拟化软体处理来得可靠与稳定。

2.3 KSM (Kernel SamePage Merging 或者 Kernel Shared Memory)

KSM 在Linux 2.6.32 版本中被加入到内核中。

2.3.1 原理

其原理是,KSM 作为内核中的守护进程(称为 ksmd)存在,它定期执行页面扫描,识别副本页面并合并副本,释放这些页面以供它用。因此,在多个进程中,Linux将内核相似的内存页合并成一个内存页。这个特性,被KVM用来减少多个相似的虚拟机的内存占用,提高内存的使用效率。由于内存是共享的,所以多个虚拟机使用的内存减少了。这个特性,对于虚拟机使用相同镜像和操作系统时,效果更加明显。但是,事情总是有代价的,使用这个特性,都要增加内核开销,用时间换空间。所以为了提高效率,可以将这个特性关闭。

2.3.2 好处

其好处是,在运行类似的客户机操作系统时,通过 KSM,可以节约大量的内存,从而可以实现更多的内存超分,运行更多的虚机。

2.3.3 合并过程

(1)初始状态:

(2)合并后:

(3)Guest 1 写内存后:

2.4 KVM Huge Page Backed Memory (巨页内存技术)

这是KVM虚拟机的又一个优化技术.。Intel 的 x86 CPU 通常使用4Kb内存页,当是经过配置,也能够使用巨页(huge page): (4MB on x86_32, 2MB on x86_64 and x86_32 PAE)

使用巨页,KVM的虚拟机的页表将使用更少的内存,并且将提高CPU的效率。最高情况下,可以提高20%的效率!

使用方法,需要三部:

#保留一些内存给巨页

(使用 x86_64 系统时,这相当于从物理内存中保留了2048 x 2M = 4GB 的空间来给虚拟机使用)

#给 kvm 传递参数 hugepages

也可以在配置文件里加入

验证方式,当虚拟机正常启动以后,在物理机里查看:

老外的一篇文档(http://www.humblec.com/give-hugepage-memory-for-guests/),他使用的是libvirt方式,先让libvirtd进程使用hugepages空间,然后再分配给虚拟机。

2019-06-12 17:04:43 pansaky 阅读数 1263

CPU虚拟化

一个KVM(kernel-based virtual machine)虚拟机在宿主机上就是一个 qemu-kvm进程,与其他Linux进程一样被调用。 虚拟机的每个虚拟CPU则对应 qemu-kvm进程中的一个进程。 因此,虚拟CPU可以超过物理CPU的数量,叫CPU超配。

内存虚拟化

KVM通过内存虚拟化共享物理系统内存,动态分配给虚拟机。

image

为了在一台机器上运行多个虚拟机,KVM需要实现VA(虚拟内存) --> PA(物理内存) --> MA(机器内存)的转换,其中虚拟机OS控制VA->PA的转换,KVM负责PA->MA的映射。

存储虚拟化

KVM的虚拟化通过存储池(Storage Pool)和卷(Volume)实现。 存储池是宿主机可见的一片存储空间,,可以分为多种类型。 卷是存储池的一块空间,卷在虚拟机眼中就是一块硬盘。 不同类型的存储池:

1. 目录类型

文件目录是最常见的存储池。 目录是一个存储池,默认是 /var/lib/libvirt/images/ 目录里的一个文件就是一个卷。

使用文件做卷的优点:

  • 存储方便

  • 移植性好

  • 可复制

  • 可远程访问

KVM支持多种卷格式:

  1. raw: 默认格式,镜像什么格式,卷就是什么格式

  2. qcow2: cow即写时复制(copy on write),节省空间,支持AES加密。

  3. vmdk:是VMWare 的虚拟磁盘格式,VM虚拟机可以直接在KVM上运行

  4. vdi: 是VirtualBox的虚拟磁盘格式

2. 逻辑卷管理(Logical Volume Manager)类型

宿主机上的VG(Volume Group)中的LV(Logical Volume)作为虚拟磁盘分配给虚拟机使用,只能作为数据盘,不能作为启动盘,因为它没有MBR引导记录。 这种情形,主机的VG就是存储池,LV就是卷。

3. 其他类型

KVM还支持 iSCSI, Ceph等多种类型的存储池。

网络虚拟化

基本概念

假设宿主机有1块物理网卡en0, 运行着一个虚拟机VM1。那问题是如何让VM1访问外网呢? a):将物理网卡直接分配给虚拟机,但这样会导致宿主机和其他的虚拟机没有网络连接了。 b):给虚拟机分配一个虚拟网卡vnet0, 通过Linux Bridge br0 将 en0和vnet0连接起来。这个是实际采用的方案。

Linux Bridge可以看做是物理接口和虚拟接口的转发器。

如果添加虚拟机VM2,自然也给它分配虚拟网卡vet0, 这两块虚拟网卡都通过 br0 和en0通信,并且虚拟机之前是可以直接通信的。因此br0就充当了两台虚拟机的出口网关。

1. VLAN

没有VLAN之前,连在同一交换机上的主机共享广播域,独占冲突域,相互之间可以直接通信。 VLAN 能够将一个交换机的端口划分为若干个组, 使得连接在同一组中端口的主机位于同一逻辑网络中,不同VLAN间通信需要经过三层路由。

VLAN是二层上的隔离,隔离广播指的是二层以太网广播帧,和三层的IP广播报文区别开来。

VLAN用VLAN ID 唯一标示组,范围是 [1, 4096]。 支持VLAN的交换机因而具有两种端口:access端口和trunk端口。 access口隶属某一个组,只能把access口划分给一个VLAN组,没有显式指定,默认在0号组。 trunk口允许不同的VLAN帧通过,通常是连接两个交换机的端口模式。

image

eth0是宿主机的物理网卡,eth0.10是与它连接的子设备。

eth0.10就是VLAN设备,vlan id 是10。

eth0.10挂载在brvlan10的Linux Bridge上, 虚拟机VM1的虚拟网卡vnet0也挂载在 brvlan10上。

如此一来,vnet0, brvlan10 和 eth0.10 都接在VLAN10 的Access口上。而eth0充当trunk口。

如果再增加一个VLAN2

image

那么VM2的三个虚拟接口都是接在VLAN 20 上的。对于新创建的虚拟机,只要为它创建一个VLAN组,并将其虚拟网卡放到这个组中,就能共享宿主机的物理网卡了。还有,一个物理网卡可以为多个虚拟网卡服务,而一个虚拟网卡则只能对应于一块物理网卡。即一对多关系。

2. Linux Bridge + VLAN = 虚拟交换机

对LVM的网络虚拟化总结:

  • 物理交换机存在多个VLAN, 每个VLAN拥有多个端口。

    同一VLAN的主机可以互相通信,不同VLAN端口之间相互隔离。因此交换机包含两层功能:交换和隔离。

  • Linux的VLAN设备实现的是隔离,但没有交换功能。

    一个VLAN母设备(如eth0)不能拥有两个相同VLAN id的子设备。

  • Linux Bridge专门实现交换功能。

    将同一VLAN的子设备都挂载到一个Bridge上,设备(也就是两台虚拟机)之间可以交换数据。

所以,Linux Bridge + Vlan 模拟了现实的二层交换机。



作者:小码弟
链接:https://www.jianshu.com/p/553e1b9669a8
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

2015-09-28 20:35:00 weixin_33885676 阅读数 0

《KVM虚拟化技术:实战与原理解析》 书籍,我是从“笑遍世界”的博客处看到的。

博客中包含的内容有:

      KVM 环境搭建;

      KVM 使用讲解;

      KVM 管理工具 libvirt 介绍;

      KVM 性能测试。

觉得博主很认真,转载学习。

博主:“笑遍世界”的入口:

      http://smilejay.com/

 

转载于:https://www.cnblogs.com/YBhello/p/4844916.html