CloudCompute

Posted by Mathew on 2017-02-11

云计算

什么是云计算,为什么要使用云主机?

  我们传统的获取计算能力的模式一般都是买一台计算机,我们要考虑其CPU的选型,内存大小,显卡,磁盘等。一般情况下,我们对计算机的计算资源的占用只有20%, 而我们使用计算机的时间一般也只有20%, 可能大部分时间都不在使用。这样的模式,我们对其计算资源的占用不高,而且可能产生不必要的浪费(电费、网费等)

  云计算其实算是一种”计费方式”, 计算能力就像水和电一样,能够按量进行分配、收费,从而使得用户只需要一个终端设备(手机、显示器…)并连接到网络即可获得计算资源,需要更大的计算能力时还可以进行弹性扩展,不使用时可以暂时停机从而只收取存储空间的费用。
我们站在PC用户的角度来看待云计算给我们带来的便捷,虽然现在云计算还没能够真正进入普通用户的视野,仅在教育等行业中有少量使用,但是我相信在未来的某一天,云桌面一定会进入我们每一个人的生活!
  曾经的小型企业一般都租用服务器并托管在IDC中提供服务,我们先不考虑资源浪费的问题,相对于小型企业来说,在节点较少且没有做高可用的情况下,容易出现单点故障,修复较为麻烦,可能硬件层到应用层的故障都需要我们考虑,如果使用了云主机提供商(阿里云、腾讯云、青云…)的云主机,相比于托管在机房的物理服务器而言,云主机的故障率肯定是低不少的,而且底层硬件的故障不需要我们考虑,我们只需要管系统、服务、应用级别的故障,并且还能实现计算能力的弹性扩展,从而应对计算能力不足的问题。
  而大型企业则可以自建云,更容易实现运维平台化,从一台云主机的创建到上线可能只需要数秒钟。

云计算的类型

目前来讲,从用户角度来看,云计算分为三种类型:

  • 公有云:公有的云环境,在云环境中有数个租户,国内公有云提供商一般- 有阿里云、青云等,当然,咱们公司的快云也属于公有云。
  • 私有云:公司内部搭建的云环境,仅供公司内部使用。
  • 混合云:公司部分较为敏感的数据和业务放在私有云,而其他部分业务放在公有云中。

根据层级来划分:

  • 基础结构即服务 (IaaS)
    云计算服务的最基本类别。使用 IaaS 时,你以即用即付的方式从服务提供商处租用 IT 基础结构,如服务器和虚拟机 (VM)、存储空间、网络和操作系统。
  • 平台即服务 (PaaS)
    平台即服务 (PaaS) 是指云计算服务,它们可以按需提供开发、测试、交付和管理软件应用程序所需的环境。PaaS 旨在让开发人员能够更轻松地快速创建 Web 或移动应用,而无需考虑对开发所必需的服务器、存储空间、网络和数据库基础结构进行设置或管理。
  • 软件即服务 (SaaS)
    软件即服务 (SaaS) 是通过 Internet 交付软件应用程序的方法,通常以订阅为基础按需提供。使用 SaaS 时,云提供商托管并管理软件应用程序和基础结构,并负责软件升级和安全修补等维护工作。用户(通常使用电话、平板电脑或 PC 上的 Web 浏览器)通过 Internet 连接到应用程序。

云计算的实现方式

  这里只讨论IaaS,IaaS的实现方式也不只一个,例如:Amazon EC2,Linode,Joyent,Rackspace,IBM Blue Cloud和Cisco UCS等。
IaaS云实现的基本功能

  • 资源抽象:通过虚拟化技术,抽象资源的方法,能更好的调度和管理物理资源
  • 负载管理:通过负载管理,不仅能使部署在基础设施上的应用能更好的应对突发情况,而且还能更好的利用系统资源
  • 数据管理:对云计算而言,数据的完整性,可靠性和可管理性是对IaaS的基本要求
  • 资源部署:将整个资源从创建到使用的流程自动化
  • 安全管理:IaaS的安全管理的主要目标是保证基础设置和其提供资源被合法地访问和使用
  • 计费管理:通过细致的计费管理能使用户更灵活的使用资源

虚拟化

什么是虚拟化

  虚拟化(Virtualization)技术最早出现在 20 世纪 60 年代的 IBM 大型机系统,在70年代的 System 370 系列中逐渐流行起来,这些机器通过一种叫虚拟机监控器(Virtual Machine Monitor,VMM)的程序在物理硬件之上生成许多可以运行独立操作系统软件的虚拟机(Virtual Machine)实例。随着近年多核系统、集群、网格甚至云计算的广泛部署,虚拟化技术在商业应用上的优势日益体现,不仅降低了 IT 成本,而且还增强了系统安全性和可靠性,虚拟化的概念也逐渐深入到人们日常的工作与生活中。
虚拟化是一个广义的术语,对于不同的人来说可能意味着不同的东西,这要取决他们所处的环境。在计算机科学领域中,虚拟化代表着对计算资源的抽象,而不仅仅局限于虚拟机的概念。例如对物理内存的抽象,产生了虚拟内存技术,使得应用程序认为其自身拥有连续可用的地址空间(Address Space),而实际上,应用程序的代码和数据可能是被分隔成多个碎片页或段),甚至被交换到磁盘、闪存等外部存储器上,即使物理内存不足,应用程序也能顺利执行。

虚拟化的技术分类

虚拟化技术主要分为以下几个大类:

  1. 平台虚拟化(Platform Virtualization),针对计算机和操作系统的虚拟化。
  2. 资源虚拟化(Resource Virtualization),针对特定的系统资源的虚拟化,比如内存、存储、网络资源等。
  3. 应用程序虚拟化(Application Virtualization),包括仿真、模拟、解释技术等。
      我们通常所说的虚拟化主要是指平台虚拟化技术,通过使用控制程序(Control Program,也被称为 Virtual Machine Monitor 或 Hypervisor),隐藏特定计算平台的实际物理特性,为用户提供抽象的、统一的、模拟的计算环境(称为虚拟机)。虚拟机中运行的操作系统被称为客户机操作系统(Guest OS),运行虚拟机监控器的操作系统被称为主机操作系统(Host OS),当然某些虚拟机监控器可以脱离操作系统直接运行在硬件之上(如 VMWARE 的 ESX 产品)。运行虚拟机的真实系统我们称之为主机系统。

平台虚拟化技术又可以细分为如下几个子类:

  1. 全虚拟化(Full Virtualization)
    全虚拟化是指虚拟机模拟了完整的底层硬件,包括处理器、物理内存、时钟、外设等,使得为原始硬件设计的操作系统或其它系统软件完全不做任何修改就可以在虚拟机中运行。操作系统与真实硬件之间的交互可以看成是通过一个预先规定的硬件接口进行的。全虚拟化 VMM 以完整模拟硬件的方式提供全部接口(同时还必须模拟特权指令的执行过程)。比较著名的全虚拟化 VMM 有 Microsoft Virtual PC、VMware Workstation、Sun Virtual Box、Parallels Desktop for Mac 和 QEMU。
  2. 半虚拟化(Paravirtualization)
    这是一种修改 Guest OS 部分访问特权状态的代码以便直接与 VMM 交互的技术。在半虚拟化虚拟机中,部分硬件接口以软件的形式提供给客户机操作系统,这可以通过 Hypercall(VMM 提供给 Guest OS 的直接调用,与系统调用类似)的方式来提供。例如,Guest OS 把切换页表的代码修改为调用 Hypercall 来直接完成修改影子 CR3 寄存器和翻译地址的工作。由于不需要产生额外的异常和模拟部分硬件执行流程,半虚拟化可以大幅度提高性能,比较著名的 VMM 有 Denali、Xen。
  3. 硬件辅助虚拟化(Hardware-Assisted Virtualization)
    硬件辅助虚拟化是指借助硬件(主要是主机处理器)的支持来实现高效的全虚拟化。例如有了 Intel-VT 技术的支持,Guest OS 和 VMM 的执行环境自动地完全隔离开来,Guest OS 有自己的“全套寄存器”,可以直接运行在最高级别。因此在上面的例子中,Guest OS 能够执行修改页表的汇编指令。Intel-VT 和 AMD-V 是目前 x86 体系结构上可用的两种硬件辅助虚拟化技术。

计算机资源的虚拟化

CPU的虚拟化
内存的虚拟化
I/O设备的虚拟化

KVM

  KVM 全称是 基于内核的虚拟机(Kernel-based Virtual Machine),它是一个 Linux 的一个内核模块,该内核模块使得 Linux 变成了一个 Hypervisor:

  1. 它由 Quramnet 开发,该公司于 2008年被 Red Hat 收购。
  2. 它支持 x86 (32 and 64 位), s390, Powerpc 等 CPU。
  3. 它从 Linux 2.6.20 起就作为一模块被包含在 Linux 内核中。
  4. 它需要支持虚拟化扩展的 CPU。
  5. 它是完全开源的。

KVM架构

KVM 是基于虚拟化扩展(Intel VT 或者 AMD-V)的 X86 硬件的开源的 Linux 原生的全虚拟化解决方案。KVM 中,虚拟机被实现为常规的 Linux 进程,由标准 Linux 调度程序进行调度;虚机的每个虚拟 CPU 被实现为一个常规的 Linux 进程。这使得 KVM 能够使用 Linux 内核的已有功能。
但是,KVM 本身不执行任何硬件模拟,需要客户空间程序通过 /dev/kvm 接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的 I/O,并将它的视频显示映射回宿主的显示屏。目前这个应用程序是 QEMU。

Linux 上的用户空间、内核空间和虚机:

   Guest:客户机系统,包括CPU(vCPU)、内存、驱动(Console、网卡、I/O 设备驱动等),被 KVM 置于一种受限制的 CPU 模式下运行。
   KVM:运行在内核空间,提供CPU 和内存的虚级化,以及客户机的 I/O 拦截。Guest 的 I/O 被 KVM 拦截后,交给 QEMU 处理。
QEMU:修改过的为 KVM 虚机使用的 QEMU 代码,运行在用户空间,提供硬件 I/O 虚拟化,通过 IOCTL /dev/kvm 设备和 KVM 交互。
KVM 实现拦截虚机的 I/O 请求的原理

  现代 CPU 本身集成了对特殊指令的截获和重定向的硬件支持,甚至新的硬件会提供额外的资源来帮助软件实现对关键硬件资源的虚拟化从而提高性能。以 X86 平台为例,支持虚拟化技术的 CPU 带有特别优化过的指令集来控制虚拟化过程。通过这些指令集,VMM 很容易将客户机置于一种受限制的模式下运行,一旦客户机试图访问物理资源,硬件会暂停客户机的运行,将控制权交回给 VMM 处理。VMM 还可以利用硬件的虚拟化增强机制,将客户机在受限模式下对一些特定资源的访问,完全由硬件重定向到 VMM 指定的虚拟资源,整个过程不需要暂停客户机的运行和 VMM 的参与。由于虚拟化硬件提供全新的架构,支持操作系统直接在上面运行,无需进行二进制转换,减少了相关的性能开销,极大简化了VMM的设计,使得VMM性能更加强大。从 2005 年开始,Intel 在其处理器产品线中推广 Intel Virtualization Technology 即 IntelVT 技术。

QEMU-KVM

  其实 QEMU 原本不是 KVM 的一部分,它自己就是一个纯软件实现的虚拟化系统,所以其性能低下。但是,QEMU 代码中包含整套的虚拟机实现,包括处理器虚拟化,内存虚拟化,以及 KVM需要使用到的虚拟设备模拟(网卡、显卡、存储控制器和硬盘等)。
  为了简化代码,KVM 在 QEMU 的基础上做了修改。VM 运行期间,QEMU 会通过 KVM 模块提供的系统调用进入内核,由 KVM 负责将虚拟机置于处理的特殊模式运行。遇到虚机进行 I/O 操作,KVM 会从上次的系统调用出口处返回 QEMU,由 QEMU 来负责解析和模拟这些设备。
  从 QEMU 的角度看,也可以说是 QEMU 使用了 KVM 模块的虚拟化功能,为自己的虚机提供了硬件虚拟化加速。除此以外,虚机的配置和创建、虚机运行说依赖的虚拟设备、虚机运行时的用户环境和交互,以及一些虚机的特定技术比如动态迁移,都是 QEMU 自己实现的。

KVM模块

  KVM 内核模块在运行时按需加载进入内核空间运行。KVM 本身不执行任何设备模拟,需要 QEMU 通过 /dev/kvm 接口设置一个 GUEST OS 的地址空间,向它提供模拟的 I/O 设备,并将它的视频显示映射回宿主机的显示屏。它是KVM 虚机的核心部分,其主要功能是初始化 CPU 硬件,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚机的运行提供一定的支持。以在 Intel 上运行为例,KVM 模块被加载的时候,
它:

  1. 首先初始化内部的数据结构;
  2. 做好准备后,KVM 模块检测当前的 CPU,然后打开 CPU 控制及存取 CR4 的虚拟化模式开关,并通过执行 VMXON 指令将宿主操作系统置于虚拟化模式的根模式;
  3. 最后,KVM 模块创建特殊设备文件 /dev/kvm 并等待来自用户空间的指令。

  接下来的虚机的创建和运行将是 QEMU 和 KVM 相互配合的过程。两者的通信接口主要是一系列针对特殊设备文件 dev/kvm 的 IOCTL 调用。其中最重要的是创建虚机。它可以理解成KVM 为了某个特定的虚机创建对应的内核数据结构,同时,KVM 返回一个文件句柄来代表所创建的虚机。

  针对该句柄的调用可以对虚机做相应地管理,比如创建用户空间虚拟地址和客户机物理地址、真实物理地址之间的映射关系,再比如创建多个 vCPU。KVM 为每一个 vCPU 生成对应的文件句柄,对其相应地 IOCTL 调用,就可以对vCPU进行管理。其中最重要的就是“执行虚拟处理器”。通过它,虚机在 KVM 的支持下,被置于虚拟化模式的非根模式下,开始执行二进制指令。在非根模式下,所有敏感的二进制指令都被CPU捕捉到,CPU 在保存现场之后自动切换到根模式,由 KVM 决定如何处理。

   除了 CPU 的虚拟化,内存虚拟化也由 KVM 实现。实际上,内存虚拟化往往是一个虚机实现中最复杂的部分。CPU 中的内存管理单元 MMU 是通过页表的形式将程序运行的虚拟地址转换成实际物理地址。在虚拟机模式下,MMU 的页表则必须在一次查询的时候完成两次地址转换。因为除了将客户机程序的虚拟地址转换了客户机的物理地址外,还要将客户机物理地址转化成真实物理地址。

KVM的功能列表

KVM 所支持的功能包括:

  1. 支持CPU 和 memory 超分(Overcommit)
  2. 支持半虚拟化I/O驱动 (virtio)
  3. 支持热插拔 (cpu,块设备、网络设备等)
  4. 支持对称多处理(Symmetric Multi-Processing,缩写为 SMP )
  5. 支持实时迁移(Live Migration)
  6. 支持 PCI 设备直接分配和 单根I/O 虚拟化 (SR-IOV)
  7. 支持 内核同页合并 (KSM )
  8. 支持 NUMA (Non-Uniform Memory Access,非一致存储访问结构 )

####KVM工具集合

  1. libvirt:操作和管理KVM虚机的虚拟化 API,使用 C 语言编写,可以由 Python,Ruby, Perl, PHP, Java 等语言调用。可以操作包括 KVM,vmware,XEN,Hyper-v, LXC 等 Hypervisor。
  2. Virsh:基于 libvirt 的 命令行工具 (CLI)
  3. Virt-Manager:基于 libvirt 的 GUI 工具
  4. virt-* 工具:包括 Virt-install (创建KVM虚机的命令行工具), Virt-viewer (连接到虚机屏幕的工具),Virt-clone(虚机克隆工具),virt-top 等
  5. qemu-kvm,原始的虚机创建启动管理工具

CPU和内存的虚拟化

CPU虚拟化

为什么需要CPU虚拟化?

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

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

enter image description here

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

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

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

半虚拟化(或者半虚拟化/操作系统辅助虚拟化Paravirtualizatrion)

半虚拟化的思想就是,修改操作系统内核,替换掉不能虚拟化的指令,通过超级调用(hypercall)直接和底层的虚拟化层hypervisor来通讯,hypervisor 同时也提供了超级调用接口来满足其他关键内核操作,比如内存管理、中断和时间保持。
这种做法省去了全虚拟化中的捕获和模拟,大大提高了效率。所以像XEN这种半虚拟化技术,客户机操作系统都是有一个专门的定制内核版本,和x86、mips、arm这些内核版本等价。这样以来,就不会有捕获异常、翻译、模拟的过程了,性能损耗非常低。这就是XEN这种半虚拟化架构的优势。这也是为什么XEN只支持虚拟化Linux,无法虚拟化windows原因,微软不改代码啊。

enter image description here

硬件辅助的全虚拟化

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模式下。
enter image description here
  而且两种操作模式可以互相转换。运行在 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。
  利用二进制翻译的全虚拟化 硬件辅助虚拟化 操作系统协作/半虚拟化实现技术 BT和直接执行 遇到特权指令转到root模式下执行 Hypercall客户操作系统修改/兼容性 无需修改客户操作系统,最佳兼容性 无需修改客户操作系统,最佳兼容性 客户操作系统需要修改来支持hypercall,因此它不能运行在物理硬件本身或其他的hypervisor上,兼容性差,不支持Windows性能 差 全虚拟化下,CPU需要在两种模式之间切换,带来性能开销;但是,其性能在逐渐逼近半虚拟化 好。半虚拟化下CPU性能开销几乎为0,虚机的性能接近于物理机。
厂商 VMware Workstation/QEMU/Virtual PC VMware ESXi/Microsoft Hyper-V/Xen 3.0/KVMHypercall Xen

KVM虚机的创建过程
enter image description here
(1)一个 KVM 虚机即一个 Linux qemu-kvm 进程,与其他 Linux 进程一样被Linux 进程调度器调度。
(2)KVM 虚机包括虚拟内存、虚拟CPU和虚机 I/O设备,其中,内存和 CPU 的虚拟化由 KVM 内核模块负责实现,I/O 设备的虚拟化由 QEMU 负责实现。
(3)KVM户机系统的内存是 qumu-kvm 进程的地址空间的一部分。
(4)KVM 虚机的 vCPU 作为 线程运行在 qemu-kvm 进程的上下文中。
vCPU、QEMU 进程、LInux 进程调度和物理CPU之间的逻辑关系:

enter image description here

KVM CPU虚拟化

多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) 结构。
    详细描述可以参考:SMP、NUMA、MPP体系结构介绍

并不存在虚拟的CPU,KVM Guest代码是运行在物理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 给客户机使用。
下图有助于理解CPU的虚拟化
enter image description here

  几个概念: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 的数目为 511 = 5。客户机看到的是基于 KVM vCPU 的 CPU 核,而 vCPU 作为 QEMU 线程被 Linux 作为普通的线程/轻量级进程调度到物理的 CPU 核上。可以参考Vcpu configuration。

KVM的CPU虚拟化

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

QEMU-KVM相比 的QEMU的改动:

  • 原生的 QEMU 通过指令翻译实现 CPU 的完全虚拟化,但是修改后的 QEMU-KVM 会调用 ICOTL 命令来调用 KVM 模块。
  • 原生的 QEMU 是单线程实现,QEMU-KVM 是多线程实现。
    主机Linux将一个虚机视作一个QEMU进程,该进程包括下面几种线程:
  • I/O 线程用于管理模拟设备
  • vCPU 线程用于运行 Guest 代码

内存虚拟化

  除了CPU虚拟化,另一个关键是内存虚拟化,通过内存虚拟化共享物理系统内存,动态分配给虚拟机。虚拟机的内存虚拟化很像现在的操作系统支持的虚拟内存方式,应用程序看到邻近的内存地址空间,这个地址空间无需如下面的物理机器内存直接对应,操作系统保持着虚拟页到物理页的映射。现在所有的x86 CPU都包括了一个称为内存管理的模块MMU(Memory Management Unit)和TLB(Translation Lookside Buffer ),通过MMU和TLB来优化虚拟内存的性能。
在有两个虚拟机的情况下,情形是这样的:
enter image description here
  可见,KVM 为了在一台机器上运行多个虚拟机,需要增加一个新的内存虚拟化层,也就是说,必须虚拟 MMU 来支持客户操作系统,来实现 VA -> PA -> MA 的翻译。客户操作系统继续控制虚拟地址到客户内存物理地址的映射 (VA -> PA),但是客户操作系统不能直接访问实际机器内存,因此VMM 需要负责映射客户物理内存到实际机器内存 (PA -> MA)。

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

KSM(Kernel SamePage Merging 或者 Kernel Shared Memory)

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

原理

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

优点

其好处是,在运行类似的客户机操作系统时,通过 KSM,可以节约大量的内存,从而可以实现更多的内存超分,运行更多的虚机。
合并过程
(1) 初始状态
enter image description here
(2) 合并后
enter image description here
(3) Guest1写内存后
enter image description here

KVM内存虚拟化

KVM当中,虚机的物理内存即为qemu-kvm进程所占用的内存空间。KVM使用CPU辅助虚拟化方式。在Intel和AMD平台,其内存虚拟化的实现方式分别为:
  AMD 平台上的 NPT (Nested Page Tables) 技术
  Intel 平台上的 EPT (Extended Page Tables)技术
 EPT 和 NPT采用类似的原理,都是作为 CPU 中新的一层,用来将客户机的物理地址翻译为主机的物理地址。
enter image description here
  EPT的好处是,它的两阶段记忆体转换,特点就是将 Guest Physical Address → System Physical Address,VMM不用再保留一份 SPT (Shadow Page Table),以及以往还得经过 SPT 这个转换过程。除了降低各部虚拟机器在切换时所造成的效能损耗外,硬体指令集也比虚拟化软体处理来得可靠与稳定。

I/O全虚拟化和半虚拟化 [KVM I/O QEMU Full-Virtualizaiton Para-virtualization]

全虚拟化I/O设备

  KVM在IO虚拟化方面,传统或者默认的方式是使用QEMU纯软件的方式来模拟I/O设备,包括键盘、鼠标、显示器,硬盘和网卡等。模拟设备可能会使用物理的设备,或者使用纯软件来模拟。
原理
enter image description here

过程:

  1. 客户机的设备驱动程序发起 I/O 请求操作请求

  2. KVM 模块中的 I/O 操作捕获代码拦截这次 I/O 请求

  3. 经过处理后将本次 I/O 请求的信息放到 I/O 共享页 (sharing page),并通知用户空间的 QEMU 程序。

  4. QEMU 程序获得 I/O 操作的具体信息之后,交由硬件模拟代码来模拟出本次 I/O 操作。

  5. 完成之后,QEMU 将结果放回 I/O 共享页,并通知 KMV 模块中的 I/O 操作捕获代码。

  6. KVM 模块的捕获代码读取 I/O 共享页中的操作结果,并把结果放回客户机。

    注意:当客户机通过DMA (Direct Memory Access)访问大块I/O时,QEMU 模拟程序将不会把结果放进共享页中,而是通过内存映射的方式将结果直接写到客户机的内存中共,然后通知KVM模块告诉客户机DMA操作已经完成。
    

这种方式的优点是可以模拟出各种各样的硬件设备;其缺点是每次 I/O 操作的路径比较长,需要多次上下文切换,也需要多次数据复制,所以性能较差。

半虚拟化 I/O驱动virtio

Virtio的架构

  KVM/QEMU 的 vitio 实现采用在 Guest OS 内核中安装前端驱动 (Front-end driver)和在 QEMU 中实现后端驱动(Back-end)的方式。前后端驱动通过 vring 直接通信,这就绕过了经过 KVM 内核模块的过程,达到提高 I/O 性能的目的。
enter image description here
  纯软件模拟的设备和 Virtio 设备的区别:virtio 省去了纯软件模拟模式下的异常捕获环节,Guest OS 可以和 QEMU 的 I/O 模块直接通信。
enter image description here
使用 Virtio 的完整虚机 I/O流程:
enter image description here
Host 数据发到 Guest:

  1. KVM 通过中断的方式通知 QEMU 去获取数据,放到 virtio queue 中
  2. KVM 再通知 Guest 去 virtio queue 中取数据。

Virtio在Linux中的实现

  Virtio 是在半虚拟化管理程序中的一组通用模拟设备的抽象。这种设计允许管理程序通过一个应用编程接口 (API)对外提供一组通用模拟设备。通过使用半虚拟化管理程序,客户机实现一套通用的接口,来配合后面的一套后端设备模拟。后端驱动不必是通用的,只要它们实现了前端所需的行为。因此,Virtio 是一个在 Hypervisor 之上的抽象API接口,让客户机知道自己运行在虚拟化环境中,进而根据 virtio 标准与 Hypervisor 协作,从而客户机达到更好的性能。
• 前端驱动:客户机中安装的驱动程序模块
• 后端驱动:在 QEMU 中实现,调用主机上的物理设备,或者完全由软件实现。
• virtio 层:虚拟队列接口,从概念上连接前端驱动和后端驱动。驱动可以根据需要使用不同数目的队列。比如 virtio-net 使用两个队列,virtio-block只使用一个队列。该队列是虚拟的,实际上是使用 virtio-ring 来实现的。
• virtio-ring:实现虚拟队列的环形缓冲区
enter image description here

Linux 内核中实现的五个前端驱动程序:

• 块设备(如磁盘)
• 网络设备
• PCI 设备
• 气球驱动程序(动态管理客户机内存使用情况)
• 控制台驱动程序
  Guest OS 中,在不使用 virtio 设备的时候,这些驱动不会被加载。只有在使用某个 virtio 设备的时候,对应的驱动才会被加载。每个前端驱动器具有在管理程序中的相应的后端的驱动程序。

Virtio-ballon

  另一个比较特殊的 virtio 设备是 virtio-balloon。通常来说,要改变客户机所占用的宿主机内存,要先关闭客户机,修改启动时的内存配置,然后重启客户机才可以实现。而 内存的 ballooning (气球)技术可以在客户机运行时动态地调整它所占用的宿主机内存资源,而不需要关闭客户机。该技术能够:
• 当宿主机内存紧张时,可以请求客户机回收利用已分配给客户机的部分内存,客户机就会释放部分空闲内存。若其内存空间不足,可能还会回收部分使用中的内存,可能会将部分内存换到交换分区中。
• 当客户机内存不足时,也可以让客户机的内存气球压缩,释放出内存气球中的部分内存,让客户机使用更多的内存。
enter image description here

  目前很多的VMM,包括 KVM, Xen,VMware 等都对 ballooning 技术提供支持。其中,KVM 中的 Ballooning 是通过宿主机和客户机协同来实现的,在宿主机中应该使用 2.6.27 及以上版本的 Linux内核(包括KVM模块),使用较新的 qemu-kvm(如0.13版本以上),在客户机中也使用 2.6.27 及以上内核且将“CONFIG_VIRTIO_BALLOON”配置为模块或编译到内核。在很多Linux发行版中都已经配置有“CONFIG_VIRTIO_BALLOON=m”,所以用较新的Linux作为客户机系统,一般不需要额外配置virtio_balloon驱动,使用默认内核配置即可。

原理:

  1. KVM 发送请求给 VM 让其归还一定数量的内存给KVM。
  2. VM 的 virtio_balloon 驱动接到该请求。
  3. VM 的驱动是客户机的内存气球膨胀,气球中的内存就不能被客户机使用。
  4. VM 的操作系统归还气球中的内存给VMM
  5. KVM 可以将得到的内存分配到任何需要的地方。
  6. KM 也可以将内存返还到客户机中。

优势不足

  1. ballooning 可以被控制和监控
  2. 对内存的调节很灵活,可多可少。
  3. KVM 可以归还内存给客户机,从而缓解其内存压力。
  4. 需要客户机安装驱动
  5. 大量内存被回收时,会降低客户机的性能。
  6. 目前没有方便的自动化的机制来管理 ballooning,一般都在 QEMU 的 monitor 中执行命令来实现。
  7. 内存的动态增加或者减少,可能是内存被过度碎片化,从而降低内存使用性能。

网络虚拟化

OpenVSwitch

  OpenVSwitch,简称OVS,是一个虚拟交换软件,主要用于虚拟机VM环境,作为一个虚拟交换机,支持Xen/XenServer, KVM, and VirtualBox多种虚拟化技术。
  虚拟交换机(vswitch)主要有两个作用:传递虚拟机VM之间的流量,以及实现VM和外界网络的通信。
OVS:基于C语言研发

  1. 特性
    802.1q协议, trunk, access
    NIC bonding(网卡版定)
    NetFlow(数据流), sFlow
    QoS配置及策略
    GRE(通用路由封装技术), VxLAN,
    OpenFlow

  2. OVS的组成部分
    ovs-vswitchd: OVS daemon, 实现数据报文交换功能,和Linux内核兼容模块一同实现了基于流的交换技术;
    ovsdb-server:轻量级的数据库服务,主要保存了整个OVS的配置信息,例如接口、交换和VLAN等等;ovs-vswitchd的交换功能基于此库实现;
    ovs-dpctl 一个工具,用来配置交换机内核模块,可以控制转发规则
    ovs-vsctl:用于获取或更改ovs-vswitchd的配置信息,其修改操作会保存至ovsdb-server中;
    ovs-appctl:主要是向OVS守护进程发送命令的,一般用不上。
    ovsdbmonitor:GUI工具来显示ovsdb-server中数据信息。
    ovs-controller:一个简单的OpenFlow控制器
    ovs-ofctl:用来控制OVS作为OpenFlow交换机工作时候的流表内容。
    ovs-pki

OpenStack

  什么是OpenStack?(http://www.openstack.org/)Openstack是一个云管理系统,可以在数据中心中管控大池计算、存储和网络资源,管理员可以通过仪表盘(dashboard)一个Web GUI接口对他们用户的资源进行管控和授权。
  我们所用的是Openstack的Icehouse版本。http://docs.openstack.org/icehouse/

OpenStack架构以及常用组件介绍

OpenStack项目是一个开源的云计算平台可以支持所有类型的云环境。
OpenStack通过一系列的补充服务提供了Infrastructure-as-a-Service(IaaS)基础设施服务。每一个服务都提供了一个应用程序接口API来促进这个项目的完整性。下面这个图表展示了OpenStack提供服务的列表:

服务 项目名字 描述

  1. Dashboard也叫仪表盘 Horizon 提供了一个基于Web自身服务入口用来和潜在的OpenStack服务进行交互,例如启动一个实例,分配指定IP和配置访问控制。
  2. Compute计算服务 Nova 管理在OpenStack环境中计算实例的生命周期。主要负责启动VM,调度VMs等。
  3. Networking网络服务 Neutron 为OpenStack提供网络管理,支持众多网络管理插件,OpenVSwitch等。
    存储
    Object Storage对象存储 Swift 基于RESTful风格的API实现非结构化数据对象的存储和检索。
    Block Storage
    块存储 Cinder 为运行中的实例提供稳定的块存储。插件式的架构促进了块存储设备的创建和管理。
    共享服务
    Identify
    认证服务 Keystone 为OpenStack中的所有服务提供认证、授权及端点编录
    Image
    镜像服务 Glance 存储和检索虚拟机磁盘镜像。
    计量服务Telemetry Ceilometer 用于实现OpenStack中各组件联动。
    高级服务
    Orchestration Heat Orchestration为其他一些热门的模板格式或者AWS云格式模板整合了许多云应用。
    Database Service
    数据服务 Trove 提供DBaaS服务

KeyStone组件介绍

OpenStack中提供Identify服务的组件为KeyStone,主要实现以下功能

用户管理:认证和授权
服务目录:所有OpenStack服务的信息库,包括其API路径

User
即用户,可以是通过Keystone访问的人或程序,User可以通过Credentials,Password,API Keys等进行身份认证
 Role
即角色,用于分配操作的权限,可将角色指定给用户,使得用户获取到对应的操作权限
Tenant
即租户,一个人或者项目、组织资源的集合,在一个租户中可以有很多个用户,这些用户可以通过权限的划分使用租户的资源。
Service
即服务,如Nova、Glance、Swift等服务
Endpoint
即端点,访问特定服务的入口

enter image description here

  下面举个比较好形象的例子来辅助我们理解上述的几个概念,我们去宾馆住的时候,我们自己就相当于 User,而宾馆就是Tenant。这是最简单的情况,宾馆只提供房间,我们只需要住房。

  随着后来生活物质等的提高,这种现象就变了。我们去宾馆住的时候,很多东西都不一样,比如,开房间要身份证,房间的钥匙是一个可以刷卡的牌子,我们进出宾馆的时候需要用自己的钥匙来开启宾馆的大门;还有就是,宾馆不仅仅是用来住的了,它可以给我们提供饮食,娱乐,健身等各种服务;而且服务层次的不同,房间也不同,房间里面的配置也不一样。这种情况下,描述我们和宾馆之间的关系就复杂一些了,这就引发了一些新的概念。
 User:住宾馆的人
 Credentials:开启房间的钥匙
 Authenticaiton:宾馆为了拒绝不必要的人进出宾馆,专门设置的机制,只有拥有钥匙的人才能进出
 Token:也是一种钥匙,有点特别
 Tenant:宾馆
 Service:宾馆可以提供的服务类别,比如,饮食类,娱乐类
 Endpoint:具体的一种服务,比如吃烧烤,打羽毛球
 Role:VIP等级,等级越高,享有越高的权限
Keystone的组织结构图如下

Glance组件介绍

glance-api
	glance的API服务接口,负责接收对Image Service API中映像文件的查看、下载及存储请求
glance-registry
	存储、处理及获取映像文件的元数据,例如映像文件的大小及类型
database
	存储映像文件元数据
storage repository for image files
	映像文件存储仓库,支持多种类型的映像文件存储机制,包括使用普通的文件系统、对象存储、RADOS块设备等

enter image description here
Glance组织架构图
enter image description here

Nova组件介绍

 API Server(Nova-Api)
 Message Queue(rabbitMQ Server)
 Compute Workers(Nova-compute)
 Network Controller(Nova-network)
 Volume Worker(Nova-volume)
 Scheduler(Nova-schedular)

API Server(Nova-API)

  API Server对外提供一个与云基础设施交互的接口,也是外部可用于管理基础设施的唯一组件。管理使用EC2 API通过Web Service调用实现。然后API Server通过消息队列(Message Queue)轮流与云基础设施的相关组件通信。作为EC2 API的另外一种选择,OpenStack也提供一个内部使用的“OpenStack API”。
Message Queue(Rabbit MQ Server)

  OpenStack 节点之间通过消息队列使用AMQP(Advanced Message Queue Protoctl)完成通信。Nova通过异步调用请求响应,使用回调函数在收到响应时触发。因为使用了异步通信,不会有用户长时间卡在等待状态。这是有效的,因为许多API调用预期的行为都非常耗时,例如加载一个实例,或者上传一个镜像。
Compute Worker(Nova-compute)

  Compute Worker处理管理实例生命周期。他们通过Message Queue接收实例生命周期管理的请求,并承担操作工作。在一个典型生产环境的云部署中有一些compute workers。一个实例部署在哪个可用的compute worker上取决于调度算法。
Network Controller(Nova-network)

  Network Controller 处理主机地网络配置。它包括IP地址分配、为项目配置VLAN、S实现安全组、配置计算节点网络。
Volume Workers(Nova-volume)

  Volume Workers用来管理基于LVM(Logical Volume Manager)的实例卷。Volume Workers有卷的相关功能,例如新建卷、删除卷、为实例附加卷,为实例分离卷。卷为实例提供一个持久化存储,因为根分区是非持久化的,当实例终止时对它所做的任何改变都会消失。当一个卷从实例分离或者实例终止(这个卷附加在该终止的实例上)时,这个卷保留着存储在其上的数据。当吧这个卷重复加载相同实例或者附加到不同实例上时,这些数据依旧能被访问。

  一个实例的重要数据几乎总是要写在卷上,这样可以确保能在以后访问。这个对存储的典型应用需要数据库等服务的支持。
Scheduler(Nova-scheduler)

  调度器Scheduler把Nova-API调用映射为OpenStack组件。调度器作为一个称为Nova-scheduler守护进程运行,通过前档的调度算法从可用资源池获得一个计算服务。Scheduler会根据诸如负载、内存、可用域的物理距离、CPU架构等做出调度决定。Nova Scheduler实现了一个可插入式的结构。

当前Nova-scheduler实现了一些基本的调度算法:
 随机算法:计算主机在所有可用域内随机选择
 可用域算法:跟随机算法相仿,但是计算主机在指定的可用域内随机选择
 简单算法:这种方法选择负载最小的主机运行实例。负载信息可通过负载均衡器获得

Neutron组件介绍

 Neutron-server:接收和路由API request到合适的OpenStack Networking Plugins,以达到预想的目的
 OpenStack Networking plugins and agents:创建网络和子网、提供IP地址、插拔端口,这些Plugins和agents都因不同的供应商和技术而不同。
 Message queue:大多数的OpenStack Networking安装都会应用消息队列的功能,用于在neutron-server和各种各样的agents进程之间信息的路由。也为某些特定的插件扮演临时数据库的角色,以此来存储网络状态。

  OpenStack networking service主要和OpenStack compute service进行交互,以提供compute service连接到虚拟机实例所需要的网络条件。

OVS(OpenVSwitch)

Neutron支持的一个插件

OpenVSwitch概述
OVS是由Nicira NetWorks主导的,运行在虚拟化平台(例如KVM,Xen)上的虚拟交换机。在虚拟化平台,OVS可以动态变化的端点提供2层交换功能,很好的控制了虚拟网络中的访问策略、网络隔离、流量监控等等。
OVS支持Apache 2.0许可证,能同时支持多种标准的管理接口和协议。
OpenVSwitch关键点
在OVS中有几个非常重要的概念:
	Bridge:Bridge 代表一个以太网交换机(Switch),一个主机中可以创建一个或者多个Bridge设备
	Port:端口 与物理交换机的端口概念类似,每个Port都隶属于一个Bridge
	Interface:连接到Port的网络接口设备。通常情况下,Port和Interface是一对一的关系,只有在配置Port为bond模式后,Port和Interface是一对多的关系
	Controller:OpenFlow控制器。OVS可以同时接受一个或者多个OpenFlow控制器的管理
	Datapath:在OVS中,datapath负责执行数据交换,也就是把接收端口收到的数据包在流表中进行匹配,并执行匹配到的动作
	Flow table:每个Datapath都和一个flow table关联,当datapath收到数据之后,OVS会在flow table中查找可以匹配的flow,执行相对应的操作,例如转发数据到另外的端口。
Neutron体系结构图

enter image description here

Cinder块存储组件介绍

API Service

  Cinder-API是主要服务接口,负责接受和处理外界的API请求,并将请求放入RabbitMQ队列,交由后端执行。Cinder目前提供Volume API V2

Scheduler Service

  处理任务队列的任务,并根据预定策略选择合适的Volume Service节点来执行任务。

Volume Service

  该服务运行在存储节点上,管理存储空间,塔处理cinder数据库的维护状态的读写请求,通过消息队列和直接在块设备或软件商与其它进程交互。每个存储节点都有一个Volume Service,若干个这样的存储节点联合起来可以构成一个存储资源池。

一次请求创建虚机的过程
enter image description here

  1. 客户端使用自己的用户名密码请求认证。
  2. keystone通过查询keystone的数据库user表中保存了user的相关信息,包括password加密后的hash值,并返回一个token_id(令牌),和serviceCatalog(一些服务的endpoint地址,cinder、glance、glance-api后面下载镜像和创建块存储时会用到)。
  3. 客户端带上keystone返回的token_id和创建虚机的相关参数,Post请求nova-api创建虚拟机。
  4. nova-api接收到请求后,首先使用请求携带的token_id来访问该api,以验证请求是否有效。
  5. keystone验证通过后返回更新后的认证信息。
  6. nova api检查创建虚拟机参数是否有效与合法。 检查虚拟机name是否符合命名规范,flavor_id是否在数据库中存在,image_uuid是否是正确的uuid格式 检查instanche、wcpu、ram的数量是否超过配额
  7. 当且仅当所有传参都有效合法时,更新nova数据库,新建一条instance记录,vm_states设为BUILDING,task_state设为SCHEDULING。
  8. nova api 远程调用传递请求、参数给nova scheduler,把消息“请给我创建一台虚拟机”丢到消息队列,然后定期查询虚机的状态。
  9. nova scheduler从queue中获取到这条消息
  10. nova scheduler访问nova数据库,通过调度算法,过滤出一些合适的计算节点,然后进行排序。
  11. 更新虚机节点信息,返回一个最优节点id给nova scheduler。
  12. nova scheduler选定host之后,通过rpc调用nova-compute服务,把“创建虚机请求”消息丢给mq。
  13. nova compute收到创建虚拟机请求的消息。 nova-compute有个定时任务,定期从数据库中查找到运行在该节点上的所有虚拟机信息,统计得到空闲内存大小和空闲磁盘大小。然后更新数据库compute_node信息,以保证调度的准确性。
  14. nova compute通过rpc查询nova数据库中虚机的信息例如主机模板和id
  15. nova conductor从消息队列中拿到请求查询数据库
  16. nova conductor查询nova数据库
  17. 数据库返回虚机信息
  18. nova compute从消息队列中获取信息
  19. nova compute 请求glance的rest api,下载所需要的镜像,一般是qcow2的。
  20. glance api也会去验证请求的token的有效性。
  21. glance api返回镜像信息给nova-compute。
  22. 同理,nova compute请求neutron api配置网络,例如获取虚机ip地址
  23. 验证token的有效性
  24. neutron返回网络信息
  25. 同glance、neutron验证token返回块设备信息
  26. 同glance、neutron验证token返回块设备信息
  27. 同glance、neutron验证token返回块设备信息。
  28. 据上面配置的虚拟机信息,生成xml,写入libvirt,xml文件,然后调用libvirt driver去使用libvirt.xml文件启动虚拟机。

参考资料:
KVM
全虚拟化和半虚拟化的区别
Virtualization and Cloud Computing
Virtualization
虚拟化时记忆体管理:AMD NPT/Intel EPT简介
KVM and CPU feature enablement
SMP、NUMA、MPP体系结构介绍