虚拟化是云计算的基础,在有虚拟化之前,一个物理主机上只能安装一个操作系统和运行一个核心业务程序。在有了虚拟化之后,一个物理主机上可以运行多台虚拟机,虚拟机上可以安装不同的操作系统和运行不同的核心业务程序,虚拟机共享物理主机的CPU、内存、I/O硬件资源,但是逻辑上虚拟机之间是相互隔离的。
物理主机是通过一个叫虚拟机监控器(Hypervisor)的软件程序实现硬件资源虚拟化的,那么根据Hypervisor是直接安装在硬件之上还是直接安装在宿主机操作系统之上,又将虚拟化分为类型1虚拟化和类型2虚拟化,如图1所示。
类型1虚拟化,宿主机上没有安装Linux或Windows常规操作系统,Hypervisor直接安装在宿主机之上,虚拟机运行在Hypervisor之上,由Hypervisor直接控制硬件资源以及虚拟机。典型的类型1虚拟化有Xen和VMware ESXi。
类型2虚拟化,宿主机上安装了Linux或Windows常规操作系统,Hypervisor直接安装在宿主机操作系统之上,也就是说这类型的Hypervisor是宿主机操作系统的一个应用程序,受宿主机操作系统的管理。典型的类型2虚拟化有KVM、VirtualBox和VMware Workstation。
KVM是在硬件辅助虚拟化技术之上构建起来的虚拟机监控器,所以小编在介绍KVM架构之前,假设各位看官对CPU、内存、I/O等硬件虚拟化技术有大概的了解,如果有不太了解的,可以到网上去了解相关的内容,这里就不再赘述。
KVM的全称是Kernel-based Virtual Machine,即基于内核的虚拟机,是采用硬件虚拟化技术的开源全虚拟化解决方案,也是业界主流的Linux虚拟化解决方案。
KVM是Linux操作系统的一个内核模块kvm.ko,通过直接加载kvm.ko模块将Linux内核转变为一个虚拟机监视器(Hypervisor),同时借助Linux内核来管理硬件,所以KVM是一个典型的类型2虚拟化,其功能框架如图2所示。注意,图2摘自危机百科,考虑到国内访问危机百科不方便,这里就不贴访问路径了。
小编将图2的英文翻译成中文,方便英文不好的小伙伴们去理解,如图3所示。
在介绍KVM功能之前,我们先来了解一下什么是“宿主机”,什么是“客户机”,什么是“物理机”,什么是“虚拟机”,这里我只是讲个大概,大家知道是那个意思就行了。虚拟机监视器(Hypervisor)运行的实际物理机,称为宿主机。虚拟机监视器(Hypervisor)上虚拟出来的虚拟机,称为客户机。所以在大约的情况下,宿主机等同于物理机,客户机等同于虚拟机。
下面我们开始介绍KVM功能框架。客户机是在宿主机操作系统上的一个抽象,通常抽象就是进程,所以一个KVM客户机对应于一个Linux进程,每个vCPU则是这个进程下的一个线程,还有单独的处理IO的线程,也在一个线程组内。所以宿主机上各个客户机是由宿主机内核像调度普通进程一样调度的,即可以通过Linux操作系统的各种进程调度的手段来实现不同客户机的权限限定、优先级等功能。
客户机所看到的硬件设备是QEMU模拟出来的(不包括VT-d直通设备),当客户机对模拟设备进行操作时,由QEMU截获并转换为对实际的物理设备的驱动操作来完成。
在KVM虚拟化架构下,每个客户机就是一个QEMU进程,在一个宿主机上有多少个虚拟机就会有多少个QEMU进程;客户机中的每一个vCPU对应QEMU进程中的一个执行线程;一个宿主机中只有一个KVM内核模块,所有客户机都与这个内核模块进行交互。
KVM支持实时迁移,这提供了在宿主机之间转移正在运行的客户机而不中断服务的能力。实时迁移对用户是透明的,客户机保持打开,网络连接保持活动,用户应用程序也持续运行,但客户机转移到了一个新的宿主机上。
除了实时迁移,KVM支持将客户机的当前状态(快照)保持到磁盘,以允许存储并在以后恢复它。
KVM支持混合虚拟化,其中半虚拟化的驱动程序安装在客户机操作系统中,允许虚拟机使用优化的I/O接口而不使用模拟的设备,从而为网络和块设备提供高性能的I/O。
KVM使用的半虚拟化的驱动程序是IBM和Redhat联合Linux社区开发的VirtIO标准,它是一个与Hypervisor独立的、构建设备驱动程序的接口,允许多种Hypervisor使用一组相同的设备驱动程序,能够实现更好的对客户机的互操作性。
同时,KVM也支持Intel的VT-d技术,通过将宿主机的PCI总线上的设备直通给客户机,让客户机可以直接使用原生的驱动程序高效地使用这些设备。这种使用是几乎不需要Hypervisor的介入的。
KVM也继承了Linux的性能和可伸缩性。KVM在CPU、内存、网络、磁盘等虚拟化性能上表现出色,大多数都在原生系统的95%以上。KVM的伸缩性也非常好,支持拥有多达288个vCPU和4TB RAM的客户机,对于宿主机上可以同时运行的客户机数量,软件上无上限。
KVM虚拟化基础架构比较简单,如图4所示。KVM是Linux操作系统的一个内核模块kvm.ko,通过直接加载kvm.ko模块将Linux内核转变为一个虚拟机监视器(Hypervisor),同时KVM借助QEMU将模拟硬件提供给虚拟机使用。
KVM内核模块是KVM虚拟化的核心模块,它在内核中由两部分组成:一个是处理器架构无关的部分,叫做“kvm”模块;另一个是处理器架构相关的部分,如果你的宿主机属于Intel架构,那么这里显示的就是“kvm_intel”模块,如果你的宿主机属于ADM架构,那么这里显示的就是“kvm_amd”,如下所示:
root@ubuntu:~# lsmod | grep kvm
kvm_intel 294912 0 # 宿主机是Intel架构,显示kvm_intel模块
kvm 823296 1 kvm_intel # kvm模块
KVM除了支持最常见的Intel和AMD为代表的x86和x86_64平台之外,也支持PowerPC、S/390、ARM等非x86架构的平台。
KVM模块负责对虚拟机的vCPU和内存进行管理及调度,主要任务是初始化CPU硬件,打开虚拟化模式,然后将虚拟机运行在虚拟模式下,并对虚拟机的运行提供一定的支持。
KVM本身不实现模拟,它通过创建一个特殊设备文件/dev/kvm,用户空间的应用程序(QEMU)通过访问/dev/kvm接口的ioctl函数来实现vCPU的创建以及虚拟内存的地址空间分配。也就是说,虚拟机的创建和运行的过程就是用户空间的应用程序(QEMU)和KVM模块相互配合的过程。QEMU通过/dev/kvm接口来调用KVM的源代码如下列所示:
open("/dev/kvm") # 打开/dev/kvm设备
ioctl(KVM_CREATE_VM) # 通过KVM_CREATE_VM创建一个虚拟机对象
ioctl(KVM_CREATE_VCPU) # 通过KVM_CREATE_VCPU为虚拟机创建vCPU对象
for (;;) {
ioctl(KVM_RUN) # 通过KVM_RUN设置vCPU运行起来
switch (exit_reason) {
case KVM_EXIT_IO:
case KVM_EXIT_HLT:
}
}
至于虚拟机的外部设备交互,如果是真实的物理硬件设备,则利用Linux系统内核来管理;如果是虚拟的外部设备,则交给QEMU来处理。
QEMU是一个纯粹的软件虚拟化技术,是一个开源的虚拟机软件项目,不属于KVM虚拟化软件。也就是说,就算没有KVM,QEMU也可以通过模拟来创建和管理虚拟机,只不过是因为纯软件实现,所以性能比较低而已。
KVM模块本身无法作为一个Hypervisor模拟出一个完整的虚拟机,而且用户也不能直接对Linux内核进行操作,因此需要借助其他软件来进行,QEMU就是KVM所需的这样一个软件。在虚拟机运行期间,QEMU会通过调用KVM模块提供的/dev/kvm接口的ioctl函数进入内核,由KVM模块负责将虚拟机置于处理器的特殊模式运行。遇到虚拟机进行I/O操作(外设交互),KVM模块将其转交给QEMU解析和模拟这些设备。
QEMU使用KVM模块的虚拟化功能,为自己的虚拟机提供硬件虚拟化的加速,从而极大地提高了虚拟机的性能。除此之外,虚拟机的配置和创建,虚拟机运行依赖的虚拟设备,虚拟机运行时的用户操作环境和交互,以及一些针对虚拟机的特殊技术(如动态迁移),都是由QEMU自己实现的。
因此,KVM虚拟机的创建和运行是一个用户态QEMU程序和内核态KVM模块相互配合的过程。KVM模块作为整个虚拟化环境的核心工作在内核空间,负责CPU和内存的调度。QEMU作为模拟器工作在用户空间,负责虚拟机I/O模拟。
总之,QEMU是一个功能完整的Hypervisor,在QEMU/KVM的软件栈中承担设备模拟的工作。
存储和虚拟磁盘文件属于I/O外设,而I/O外设主要由QEMU来负责,所以存储和虚拟磁盘文件是QEMU的功能特性。
KVM支持Linux操作系统所支持的所有存储,包括具有IDE、SCSI和SATA的本地磁盘,网络附件存储NAS(包括NFS和SAMBA/CIFS),或者支持iSCSI和SAN等。
在KVM中往往使用Image(镜像)这个术语来表示虚拟磁盘,主要有以下3种文件格式。
要实现一个可运行、可运维的KVM虚拟化解决方案,需要解决两个问题,第一个是虚拟化技术实现问题,第二个是集群虚拟机管理问题。我们刚才所介绍的内容只是解决了虚拟化技术问题,还有集群虚拟机管理问题没有解决,因此我们需要有一套KVM管理工具实现对KVM虚拟化的管理和运维。
KVM模块和QEMU组件只是解决了虚拟化技术实现问题,为了使KVM整个虚拟化环境易于管理,还需要Libvirt服务和基于Libvirt开发出来的KVM管理工具。
Libvirt是一个软件集合,是一套为方便管理平台虚拟化技术而设计的开源代码的应用程序接口、守护进程和管理工具。它不仅提供了对虚拟机的管理,而且提供了对虚拟网络和存储的管理。Libvirt最初是为Xen虚拟化平台设计的一套API,目前还支持其他的虚拟化平台,如KVM、ESX和QEMU等。在KVM解决方案中,Qemu用来进行平台模拟,面向上层管理和操作;而Libvirt用来管理KVM,面向下层管理和操作。整个Libvirt架构如图5所示。
Libvirt是目前使用广泛的虚拟机管理工具和应用程序接口,已经是事实上的虚拟化接口标准。图5中的虚拟机管理工具如virsh、OpenStack等都是基于libvirt API来实现的。Libvirt不但能管理KVM,还能管理Xen、VMware、VirtualBox、Hyper-V等其他的虚拟化方案。
Libvirt包括两部分,一部分是服务(守护进程名为Libvirtd),另一部分是API。作为一个运行在主机上的服务端守护进程,Libvirtd为虚拟化平台及虚拟机提供本地和远程的管理功能,基于Libvirt开发出来的管理工具可通过Libvirtd服务来管理整个虚拟化环境。也就是说,Libvirtd在管理工具和虚拟化平台之间起到一个桥梁的作用。Libvirt API是一系列标准的库文件,给多种虚拟化平台提供一个统一的编程接口,相当于管理工具需要基于Libvirt的标准接口来进行开发,开发完成后的工具可支持多种虚拟化平台。
到目前为止,KVM拥有从virsh命令行工具到OpenStack云管理平台工具等一整套的开源KVM管理工具,这些工具的能力层次以及身份段位各有不同,如图6所示。
初级段位,“KVM+virsh”虚拟化解决方案主要是通过在/etc/libvirtd/qemu里面的“.xml”配置文件去描述每一台虚拟机的配置,然后用virsh命令行管理虚拟机,最后用VNC/SPICE按照配置好的端口链接过去,模拟终端操作。“KVM+virsh”这种方式更多的是基于单机管理模式,单机KVM不具备数据中心和集群等高级管理特性,从商业化角度来看,无法成为一个成熟的虚拟化解决方案。
中级段位,“KVM+virt-manager”虚拟化解决方案主要是通过桌面图形化工具virt-manager直接创建、编译和管理虚拟机。使用桌面版本的 VNC/SPICE连接到KVM主机,输入“virt-manager”命令之后,自动弹出虚拟系统管理器窗口来进行创建、编译和管理虚拟机工作。“KVM+virt-manager” 这种方式仍然属于基于单机管理模式,单机KVM不具备数据中心和集群等高级管理特性,从商业化角度来看,无法成为一个成熟的虚拟化解决方案。
高级段位,“KVM+Web管理工具”虚拟化解决方案主要是通过Proxmox VE、WebVirtMgr、Kimchi以及oVirt等各种轻量级的Web GUI工具进行中小规模级别的虚拟机集群管理。Web GUI工具简单易用易理解,尤其是傻瓜化的Proxmox VE,更是受小白们欢迎。“KVM+Web管理工具”这种方式可以实现中小规模化的虚拟机集群管理,具备了数据中心和集群等高级特性,而且管理界面非常友好,从商业化角度来看,已经是一个成熟的虚拟化解决方案。
超级段位,“KVM+云管理平台工具”虚拟化解决方案主要通过OpenStack、ZStack等云管理平台来管理一个或多个数据中心的所有计算资源池、存储资源池、网络资源池等硬件资源,可以实现大规模/超大规模的KVM主机管理。不过云管理平台工具这种方式,在安装和使用方面都非常复杂,尤其是OpenStack基本需要一个DevOps团队才玩得转。ZStack相对来说简单一些,但是也比轻量级的Web管理工具要复杂。
尽管与老牌虚拟化巨头VMware提供的商业虚拟化管理工具相比在功能和易用性上有所差距,但KVM这一整套管理工具都是API化的、开源的,在使用灵活性以及对其做二次开发的定制化方面仍有一定优势。
virsh是一个常用的管理KVM虚拟化的命令行工具,对于系统管理员在单个宿主机上进行运维操作,virsh命令行可能是最佳选择。virsh是用C语言编写的一个使用libvirt API的虚拟化管理工具,其源代码也是在Libvirt这个开源项目中的。
vir-manager是专门针对虚拟机的图形化管理软件,底层与虚拟化交互的部分仍然是调用libvirt API来操作的。vir-manager除了提供虚拟机生命周期(包括:创建、启动、停止、打快照、动态迁移等)管理的基本功能,还提供性能和资源使用率的监控,同时内置了VNC和SPICE客户端,方便图形化连接到虚拟客户机中。vir-manager在RHEL、CentOS、Fedora等操作系统上是非常流行的虚拟化管理软件,在管理的机器数量规模较小时,vir-manager是很好的选择。因其图形化操作的易用性,成为新手入门学习虚拟化操作的首选管理软件。
Proxmox VE的使用很简单,很傻瓜化,深受小白们的欢迎。管理操作可以通过内嵌的Web GUI完成,不需要专门安装管理工具或基于大型数据库的管理服务器节点。多主集群架构能够让你通过任意节点管理整个集群。基于JavaScript框架(ExtJS)开发的集中Web管理界面不仅能够让你通过GUI 界面控制一切功能,而且可以浏览每个节点的历史活动和syslog日志,例如虚拟机备份恢复日志、虚拟机在线迁移日志、HA活动日志等。
WebVirtMgr是一个基于libvirt开发的KVM管理平台,提供对宿主机和虚机的统一管理,它有别于KVM自带的图形管理工具(virtual machine manager),让KVM的管理变得更为可视化,比较合适用于小型的KVM应用场景,比如对于虚拟机在10-200之间的集群来说,采用WebvirtMgr是一种不错的选择。
Kimchi是一款基于HTML5的KVM管理工具,它被设计成尽可能容易使用KVM并创建虚拟机的Web工具,它通过libvirt管理KVM虚拟机。
oVirt是Red Hat虚拟化管理平台RHEV的开源版本,利用oVirt管理KVM虚拟机和网络,企业可以快速地搭建一个私有云环境,oVirt基于Web方式进行管理,管理界面非常友好,oVirt比较适合较中小集群规模,比如虚拟机上千的集群,使用oVirt是一种不错的选择。
OpenStack是一个开源的基础架构即服务(IaaS)云计算管理平台,可用于构建公有云和私有云的基础设施。OpenStack是目前业界使用最广泛的功能最强大的云管理平台,它不仅提供了管理虚拟机的丰富功能,还有非常多其他重要管理功能,如对象存储、块存储、网络、镜像、身份验证、编排服务、控制面板等。OpenStack仍然使用libvirt API来完成对底层虚拟化的管理。
ZStack是2015年在国内创立的一个开源IaaS项目,其核心系统使用Java语言开发,ZStack的主要特点是部署和升级简单、可扩展性(可以管理上万个物理节点和支持高并发的API访问)、快速(启动虚拟机速度非常快)、默认网络就是NFV(网络功能虚拟化)、全API的管理功能(也提供了一个Web UI管理界面)、插件系统(添加或删除某个特性不会影响核心功能)等
KVM软件栈中常见的几个KVM管理工具就简单介绍到这里,更详细的介绍以及使用操作敬请关注后续章节。如大家还想了解更多的KVM管理工具,请参见KVM官网,如下所示:
常见的KVM管理工具:http://www.linux-kvm.org/page/Management_Tools
参考资料:
《KVM实战——原来、进阶与性能调优》,任永杰、程舟著;
《OpenStack云计算实战》,钟小平、徐宁编著;