1.2 Linux虚拟化技术
虚拟化是云计算的基础。虚拟化使得在一台物理服务器上可以运行多台虚拟机,虚拟机共享物理机的CPU、内存、I/O硬件资源,但逻辑上虚拟机之间是相互隔离的。OpenStack作为IaaS云操作系统,最主要的服务就是为用户提供虚拟机。在目前 OpenStack 的实际应用中,主要使用 KVM 和Xen这两种Linux虚拟化技术。这里主要讨论Linux虚拟化技术。
1.2.1 计算机虚拟化基础
1.虚拟化体系结构与Hypervisor
虚拟化主要是指通过软件实现的方案,常见的体系结构如图1-3所示。这是一个直接在物理主机上运行虚拟机管理程序的虚拟化系统。在 x86平台虚拟化技术中,这个虚拟机管理程序通常被称为虚拟机监控器(Virtual Machine Monitor,VMM),又称为Hypervisor。它是运行在物理机和虚拟机之间的一个软件层,物理机被称为主机(Host),虚拟机被称为客户机(Guest),中间软件层即Hypervisor。
图1-3 虚拟化体系结构
这里解释两个基本概念。
(1)主机——指物理存在的计算机,又称宿主计算机(简称宿主机)。当虚拟机嵌套时,运行虚拟机的虚拟机也是宿主机,但不是物理机。主机操作系统是指宿主计算机上的操作系统,在主机操作系统上安装的虚拟机软件可以在计算机上模拟一台或多台虚拟机。
(2)虚拟机——指在物理计算机上运行的操作系统中模拟出来的计算机,又称客户机,理论上完全等同于实体的物理计算机。每个虚拟机都可安装自己的操作系统或应用程序,并连接网络。运行在虚拟机上的操作系统称为客户操作系统。
Hypervisor基于主机的硬件资源给虚拟机提供了一个虚拟的操作平台并管理每个虚拟机的运行,所有虚拟机独立运行并共享主机的所有硬件资源。Hypervisor就是提供虚拟机硬件模拟的专门软件,可分为两类:原生型和宿主型。
(1)原生型(Native)
原生型又称裸机型(Bare-metal),Hypervisor作为一个精简的操作系统(操作系统也是软件,只不过它是一个比较特殊的软件)直接运行在硬件之上以控制硬件资源并管理虚拟机。比较常见的有VMware ESXi、Microsoft Hyper-V等。
(2)宿主型(Hosted)
宿主型又称托管型,Hypervisor运行在传统的操作系统上,同样可模拟出一整套虚拟硬件平台。比较著名的有VMware Workstation、Oracle Virtual Box等。
从性能角度来看,不论原生型还是宿主型都会有性能损耗,但宿主型比原生型的损耗更大,所以企业生产环境中基本使用的是原生型Hypervisor,宿主型的Hypervisor一般用于实验或测试环境中。
2.全虚拟化和半虚拟化
根据虚拟化实现技术的不同,虚拟化可分为全虚拟化和半虚拟化两种,其中,全虚拟化产品将是未来虚拟化的主流。
(1)全虚拟化(Full Virtualization)
用全虚拟化模拟出来的虚拟机中的操作系统是与底层的硬件完全隔离的,虚拟机中所有的硬件资源都通过虚拟化软件来模拟。这为虚拟机提供了完整的虚拟硬件平台,包括处理器、内存和外设,支持运行任何理论上可在真实物理平台上运行的操作系统,为虚拟机的配置提供了较大程度的灵活性。每台虚拟机都有一个完全独立和安全的运行环境,虚拟机中的操作系统也不需要做任何修改,并且易于迁移。在操作全虚拟化的虚拟机的时候,用户感觉不到它是一台虚拟机。全虚拟化的代表产品有VMware ESXi和KVM。
由于虚拟机的资源都需要通过虚拟化软件来模拟,虚拟机会损失一部分的性能。
(2)半虚拟化(Para Virtualization)
半虚拟化的架构与全虚拟化基本相同,需要修改虚拟机中的操作系统来集成一些虚拟化方面的代码,以减小虚拟化软件的负载。其代表产品有Microsoft Hyper-V和XEN。
半虚拟化模拟出来的虚拟机整体性能会更好些,因为修改后的虚拟机操作系统承载了部分虚拟化软件的工作。不足之处是,由于要修改虚拟机的操作系统,用户会感知使用的环境是虚拟化环境,而且兼容性比较差,用户使用时也比较麻烦,需要获得集成虚拟化代码的操作系统。
1.2.2 OpenStack所支持的虚拟化技术
在 OpenStack 环境中,计算服务通过 API 服务器来控制虚拟机管理程序,它具备一个抽象层,可以在部署时选择一种虚拟化技术来创建虚拟机,向用户提供云服务。OpenStack可用的虚拟化技术列举如下。
1.KVM
基于内核的虚拟机(Kernel-based Virtual Machine,KVM)是通用的开放虚拟化技术,也是OpenStack用户使用较多的虚拟化技术,它支持OpenStack的所有特性。
2.Xen
Xen是部署快速、安全、开源的虚拟化软件技术,可使多个同样的操作系统或不同操作系统的虚拟机运行在同一主机上。Xen技术主要包括XenServer(服务器虚拟化平台)、Xen Cloud Platform (XCP,云基础架构)、XenAPI(管理XenServer和XCP的API程序)、XAPI(XenServer和XCP的主守护进程,可与XenAPI直接通信)、基于Libvirt的Xen。OpenStack通过XenAPI支持XenServer和XCP两种虚拟化技术。不过,在RHEL等平台上,OpenStack使用的是基于Libvirt的Xen。
3.容器
容器是在单一 Linux 主机上提供多个隔离的 Linux 环境的操作系统级虚拟化技术。不像基于虚拟化管理程序的传统虚拟化技术,容器并不需要运行专用的客户操作系统。目前的容器有以下两种技术。
(1)Linux容器(Linux Container,LXC):提供了在单一可控主机节点上支持多个相互隔离的服务器容器同时执行的机制。
(2)Docker:一个开源的应用容器引擎,让开发者可以把应用以及依赖包打包到一个可移植的容器中,然后发布到任何流行的Linux平台上。利用Docker也可以实现虚拟化,容器完全使用沙箱机制,相互之间不会有任何接口。
Docker 的目的是尽可能减少容器中运行的程序,减少到只运行单个程序,并且通过 Docker来管理这个程序。LXC可以快速兼容所有应用程序和工具,以及任意管理和编制层次,来替代虚拟机。
虚拟化管理程序提供更好的进程隔离,呈现一个完全的系统。LXC/Docker除了一些基本隔离,并未提供足够的虚拟化管理功能,缺乏必要的安全机制。基于容器的方案无法运行与主机内核不同的其他内核,也无法运行一个完全不同的操作系统。目前 OpenStack 社区对容器的驱动支持还不如虚拟化管理程序。在OpenStack项目中,LXC属于计算服务项目Nova,通过调用Libvirt来实现;Docker驱动是一种新加入的虚拟化管理程序的驱动,目前无法替代虚拟化管理程序。
4.Hyper-V
Hyper-V是微软推出的企业级虚拟化解决方案。Hyper-V的设计借鉴了Xen,管理程序采用微内核的架构,兼顾了安全性和性能的要求。Hyper-V作为一种免费的虚拟化方案,在OpenStack中得到了很多支持。
5.VMware ESXi
VMware提供业界领先且可靠的服务器虚拟化平台和软件定义计算产品,其中ESXi虚拟化平台用于创建和运行虚拟机及虚拟设备。在OpenStack中它也得到了支持,但是如果没有vCenter和企业级许可,一些API的使用会受限。
6.Baremetal与Ironic
有些云平台除了提供虚拟化和虚拟机服务,还提供传统的主机服务。在 OpenStack 中可以将Baremetal(裸金属)与其他部署有虚拟化管理程序的节点通过不同的计算池(可用区域,Availabity Zone)一起管理。
Baremetal是计算服务的后端驱动,与Libvirt驱动、XenAPI驱动、VMware驱动一样,只不过它是用来管理没有虚拟化的硬件,主要通过PXE和IPMI进行控制管理。
现在Baremetal已由Ironic所替代,Nova管理的是虚拟机的生命周期,而Ironic管理的是主机的生命周期。Ironic提供了一系列管理主机的API接口,可以对“裸”操作系统的主机进行管理,从主机上架安装操作系统到主机下架维修,可以像管理虚拟机一样地管理主机,创建一个Nova计算物理节点,只需告诉Ironic,然后自动地从镜像模板中加载操作系统到nova-compute安装完成即可。Ironic解决主机的添加、删除、电源管理、操作系统部署等问题,目标是成为主机管理的成熟解决方案,让OpenStack不仅可以在软件层面解决云计算问题,而且供应商可以对应自己的服务器开发Ironic插件。
1.2.3 KVM——基于Linux内核的虚拟化解决方案
KVM是一种基于Linux x86硬件平台的开源全虚拟化解决方案,也是主流的Linux虚拟化解决方案,支持广泛的客户机操作系统。KVM需要CPU的虚拟化指令集的支持,如Intel的Intel VT(vmx指令集)或AMD的AMD-V(svm指令集)。
1.KVM模块
KVM模块是一个可加载的内核模块kvm.ko。由于KVM对x86硬件架构的依赖,因此KVM还需要一个处理器规范模块。如果使用Intel架构,则加载kvm-intel.ko模块;使用AMD架构,则加载kvm-amd.ko模块。
KVM模块负责对虚拟机的虚拟CPU和内存进行管理及调度,主要任务是初始化CPU硬件,打开虚拟化模式,然后将虚拟机运行在虚拟模式下,并对虚拟机的运行提供一定的支持。
至于虚拟机的外部设备交互,如果是真实的物理硬件设备,则利用Linux系统内核来管理;如果是虚拟的外部设备,则借助于QEMU(Quick Emulator,快速仿真)来处理。
由此可见,KVM本身只关注虚拟机的调度和内存管理,是一个轻量级的Hypervisor,很多Linux发行版集成KVM作为虚拟化解决方案,CentOS也不例外。
2.QEMU
KVM模块本身无法作为一个Hypervisor模拟出一个完整的虚拟机,而且用户也不能直接对Linux内核进行操作,因此需要借助其他软件来进行,QEMU就是KVM所需的这样一个软件。
QEMU并非KVM的一部分,而是一个开源的虚拟机软件。与KVM不同,作为一个宿主型的Hypervisor,没有 KVM,QEMU 也可以通过模拟来创建和管理虚拟机,只因为是纯软件实现,所以性能较低。QEMU的优点是,在支持QEMU编译运行的平台上就可以实现虚拟机的功能,甚至虚拟机可以与主机不是同一个架构。KVM在QEMU的基础上进行了修改。虚拟机运行期间,QEMU会通过KVM模块提供的系统调用进入内核,由KVM模块负责将虚拟机置于处理器的特殊模式运行。遇到虚拟机进行输入/输出(I/O)操作(外设交互),KVM 模块转交给 QEMU 解析和模拟这些设备。
QEMU 使用 KVM 模块的虚拟化功能,为自己的虚拟机提供硬件虚拟化的加速,从而极大地提高了虚拟机的性能。除此之外,虚拟机的配置和创建,虚拟机运行依赖的虚拟设备,虚拟机运行时的用户操作环境和交互,以及一些针对虚拟机的特殊技术(如动态迁移),都是由 QEMU 自己实现的。
KVM虚拟机的创建和运行是一个用户空间的QEMU程序和内核空间的KVM模块相互配合的过程。KVM模块作为整个虚拟化环境的核心工作在系统空间,负责CPU和内存的调度。QEMU作为模拟器工作在用户空间,负责虚拟机I/O模拟。
3.KVM架构
从上面的分析来看,KVM作为Hypervisor主要包括两个重要的组成部分:一个是Linux内核的KVM模块,主要负责虚拟机的创建、虚拟内存的分配、VCPU寄存器的读写以及VCPU的运行;另一个是提供硬件仿真的 QEMU,用于模拟虚拟机的用户空间组件、提供 I/O 设备模型和访问外设的途径。KVM的基本架构如图1-4所示。
图1-4 KVM的基本架构
在KVM模型中,每一个虚拟机都是一个由Linux调度程序管理的标准进程,可以在用户空间启动客户机操作系统。一个普通的Linux进程有两种运行模式:内核和用户,而KVM增加了第三种模式——客户模式,客户模式又有自己的内核和用户模式。
当新的虚拟机在KVM上启动时(通过一个称为kvm的实用程序),它就成为主机操作系统的一个进程,因此就可以像其他进程一样调度它。但与传统的 Linux 进程不一样,客户端被 Hypervisor标识为处于Guest模式(独立于内核和用户模式)。每个虚拟机都是通过/dev/kvm设备映射的,它们拥有自己的虚拟地址空间,该空间映射到主机内核的物理地址空间。如前所述,KVM使用底层硬件的虚拟化支持来提供完整的(原生)虚拟化。I/O 请求通过主机内核映射到在主机上(Hypervisor)执行的QEMU进程。
4.KVM虚拟磁盘(镜像)文件格式
在KVM中往往使用Image(镜像)这个术语来表示虚拟磁盘,主要有以下3种文件格式。
(1)raw:原始的格式,它直接将文件系统的存储单元分配给虚拟机使用,采取直读直写的策略。该格式实现简单,不支持诸如压缩、快照、加密和CoW等特性。
(2)qcow2:QEMU引入的镜像文件格式,也是目前KVM默认的格式。qcow2文件存储数据的基本单元是簇(cluster),每一簇由若干个数据扇区组成,每个数据扇区的大小是512字节。在qcow2中,要定位镜像文件的簇,需要经过两次地址查询操作,qcow2根据实际需要来决定占用空间的大小,而且支持更多的主机文件系统格式。
(3)qed:qcow2的一种改进,qed的存储、定位、查询方式,以及数据块大小与qcow2一样,它的目的是为了克服qcow2格式的一些缺点,提高性能,不过目前还不够成熟。
如果需要使用虚拟机快照,需要选择qcow2格式。对于大规模数据的存储,可以选择raw格式。qcow2格式只能增加容量,不能减少容量,而raw格式可以实现增加或者减少容量。
1.2.4 Libvirt套件
仅有KVM模块和QEMU组件是不够的,为了使KVM整个虚拟化环境易于管理,还需要Libvirt服务和基于Libvirt开发出来的管理工具。
Libvirt是一个软件集合,是一套为方便管理平台虚拟化技术而设计的开源代码的应用程序接口、守护进程和管理工具。它不仅提供了对虚拟机的管理,而且提供了对虚拟网络和存储的管理。Libvirt最初是为Xen虚拟化平台设计的一套API,目前还支持其他多种虚拟化平台,如KVM、ESX和QEMU等。在KVM解决方案中,Qemu用来进行平台模拟,面向上层管理和操作;而Libvirt用来管理KVM,面向下层管理和操作。整个Libvirt架构如图1-5所示。
图1-5 Libvirt架构
Libvirt是目前使用广泛的虚拟机管理应用程序接口,一些常用的虚拟机管理工具(如virsh)和云计算框架平台(如OpenStack)都是在底层使用Libvirt的应用程序接口。
Libvirt包括两部分,一部分是服务(守护进程名为libvirtd),另一部分是API。作为一个运行在主机上的服务端守护进程,libvirtd为虚拟化平台及其虚拟机提供本地和远程的管理功能,基于Libvirt开发出来的管理工具可通过libvirtd服务来管理整个虚拟化环境。也就是说,libvirtd在管理工具和虚拟化平台之间起到一个桥梁的作用。Libvirt API是一系列标准的库文件,给多种虚拟化平台提供一个统一的编程接口,相当于管理工具需要基于Libvirt的标准接口来进行开发,开发完成后的工具可支持多种虚拟化平台。