龙空技术网

KVM、QEMU、LIBVIRT 是什么

一曦时光 702

前言:

如今兄弟们对“kvmubuntu14”大概比较讲究,看官们都想要分析一些“kvmubuntu14”的相关文章。那么小编也在网上网罗了一些关于“kvmubuntu14””的相关内容,希望小伙伴们能喜欢,看官们一起来了解一下吧!

2、KVM2.1、KVM 详解2.1.1、简介

KVM 全称是基于内核的虚拟机(Kernel-based Virtual Machine),最初由以色列的公司Qumranet 开发。KVM于2006年12月被合并在发布于2007年2月的linux 2.6.20内核中。RedHat公司在2008年9月收购Qumranet公司后,在RHEL 6及以后发行版中使用KVM作为默认的虚拟化引擎。

KVM是x86架构且硬件支持虚拟化技术( intel VT 或 AMD-V)的Linux全虚拟化解决方案,它包含一个为处理器提供底层虚拟化、可加载的核心模块kvm.ko(kvm-intel.ko或kvm-AMD.ko)。KVM 本身不执行任何硬件模拟,需要修改过的QEMU向它提供模拟的 I/O。

2.1.2、架构

在 KVM 架构中,每个虚拟机其实就是一个常规的 Linux 进程,由 Linux 调度程序进行调度,因此,KVM使用Linux 内核的所有功能。如图所示,KVM就是Linux内核中的一个模块,在用户空间通过使用修改的 QEMU 提供BIOS、PCI 总线、USB 总线和一组标准的设备(比如 IDE 和 SCSI 磁盘控制器、网络卡等)的模拟。

2.2、KVM 和 QEMU

QEMU是一个开源的模拟器,作者是法布里斯·贝拉(Fabrice Bellard)。QEMU可以模拟完整的硬件环境,与Bochs,PearPC类似,但具有高速度、跨平台等特性。由于QEMU是纯软件模拟,Guest OS的指令都需要QEMU转义给真正的硬件,因而性能较差。

KVM只是一个内核模块,本身只能提供CPU和内存的虚拟化,没有用户空间的管理工具,需要QEMU为其提供I/O支持。

在QEMU 1.0的时候出现了QEMU-KVM分支,发布了三个正式版本(1.1/1.2/1.3)后,与QEMU主版本合并了。所以,现在的QEMU默认就支持QEMU-KVM。

说明:个人理解,KVM是内核虚拟化技术,而内核是不能使用在界面上使用的,那么此时QEMU提供了用户级别的使用界面,相互辅助。当然,单独使用QEMU也是可以实现一整套虚拟机,不过QEMU+KVM基本是标配Linux虚拟机管理工具。

qemu是什么那。其实它也是一款虚拟化技术,就算不使用kvm,单传的qemu也可以完全实现一个虚拟机。那为何还会有qemu-kvm这个名词那。是因为虽然kvm的技术已经相当成熟而且可以对很多东西进行隔离,但是在某些方面还是无法虚拟出真实的机器。比如对网卡的虚拟,那这个时候就需要另外的技术来做补充,而qemu-kvm则是这样一种技术。它补充了kvm技术的不足,而且在性能上对kvm进行了优化。

Qemu 是纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备,我们最熟悉的就是能够模拟一台能够独立运行操作系统的虚拟机,虚拟机认为自己和硬件打交道,但其实是和 Qemu 模拟出来的硬件打交道,Qemu 将这些指令转译给真正的硬件。

正因为 Qemu 是纯软件实现的,所有的指令都要经 Qemu 过一手,性能非常低,所以,在生产环境中,大多数的做法都是配合 KVM 来完成虚拟化工作,因为 KVM 是硬件辅助的虚拟化技术,主要负责 比较繁琐的 CPU 和内存虚拟化,而 Qemu 则负责 I/O 虚拟化,两者合作各自发挥自身的优势,相得益彰。

从本质上看,虚拟出的每个虚拟机对应 host 上的一个 Qemu 进程,而虚拟机的执行线程(如 CPU 线程、I/O 线程等)对应 Qemu 进程的一个线程。下面通过一个虚拟机启动过程看看 Qemu 是如何与 KVM 交互的。

2.2.1、交互过程

 // 第一步,获取到 KVM 句柄 kvmfd = open("/dev/kvm", O_RDWR); // 第二步,创建虚拟机,获取到虚拟机句柄。 vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0); // 第三步,为虚拟机映射内存,还有其他的 PCI,信号处理的初始化。 ioctl(kvmfd, KVM_SET_USER_MEMORY_REGION, &mem); // 第四步,将虚拟机镜像映射到内存,相当于物理机的 boot 过程,把镜像映射到内存。 // 第五步,创建 vCPU,并为 vCPU 分配内存空间。 ioctl(kvmfd, KVM_CREATE_VCPU, vcpuid); vcpu->kvm_run_mmap_size = ioctl(kvm->dev_fd, KVM_GET_VCPU_MMAP_SIZE, 0); // 第五步,创建 vCPU 个数的线程并运行虚拟机。 ioctl(kvm->vcpus->vcpu_fd, KVM_RUN, 0); // 第六步,线程进入循环,并捕获虚拟机退出原因,做相应的处理。 for (;;) {   ioctl(KVM_RUN)   switch (exit_reason) {       case KVM_EXIT_IO:  /* ... */       case KVM_EXIT_HLT: /* ... */   } } // 这里的退出并不一定是虚拟机关机, // 虚拟机如果遇到 I/O 操作,访问硬件设备,缺页中断等都会退出执行, // 退出执行可以理解为将 CPU 执行上下文返回到 Qemu。
2.2.2、Qemu 源码结构

Qemu 软件虚拟化实现的思路是采用二进制指令翻译技术,主要是提取 guest 代码,然后将其翻译成 TCG 中间代码,最后再将中间代码翻译成 host 指定架构的代码,如 x86 体系就翻译成其支持的代码形式,ARM 架构同理。

所以,从宏观上看,源码结构主要包含以下几个部分:

/vl.c:最主要的模拟循环,虚拟机环境初始化,和 CPU 的执行。/target-arch/translate.c:将 guest 代码翻译成不同架构的 TCG 操作码。/tcg/tcg.c:主要的 TCG 代码。/tcg/arch/tcg-target.c:将 TCG 代码转化生成主机代码。/cpu-exec.c:主要寻找下一个二进制翻译代码块,如果没有找到就请求得到下一个代码块,并且操作生成的代码块。

其中,涉及的主要几个函数如下:

函数

路径

注释

main_loop

{/vl.c}

很多条件的判断,如电源是否断等

qemu_main_loop_start

{/cpus.c}

分时运行 CPU 核

struct CPUState

{/target-xyz/cpu.h}

CPU 状态结构体

cpu_exec

{/cpu-exec.c}

主要的执行循环

struct TranslationBlock

{/exec-all.h}

TB(二进制翻译代码块) 结构体

cpu_gen_code

{translate-all.c}

初始化真正代码生成

tcg_gen_code

{/tcg/tcg.c}

tcg 代码翻译成 host 代码

知道了这个总体的代码结构,再去具体了解每一个模块可能会相对容易一点。

2.2.3、Qemu 的使用2.2.3.1、源码下载

 centos: sudo apt-get install qemu ubuntu: sudo yum install qemu -y 安装包: $wget  $tar xjvf qemu-2.0.0.tar.bz2 Git: $git clone git://git.qemu-project.org/qemu.git
2.2.3.2、编译及安装
 $cd qemu-2.0.0 //如果使用的是git下载的源码,执行cd qemu $./configure --enable-kvm --enable-debug --enable-vnc --enable-werror  --target-list="x86_64-softmmu" $make -j8 $sudo make install

configure 脚本用于生成 Makefile,其选项可以用 ./configure --help 查看。

这里使用到的选项含义如下:

--enable-kvm:编译 KVM 模块,使 Qemu 可以利用 KVM 来访问硬件提供的虚拟化服务。--enable-vnc:启用 VNC。--enalbe-werror:编译时,将所有的警告当作错误处理。--target-list:选择目标机器的架构。默认是将所有的架构都编译,但为了更快的完成编译,指定需要的架构即可。

安装好之后,会生成如下应用程序:

ivshmem-client/server:这是一个 guest 和 host 共享内存的应用程序,遵循 C/S 的架构。qemu-ga:这是一个不利用网络实现 guest 和 host 之间交互的应用程序(使用 virtio-serial),运行在 guest 中。qemu-io:这是一个执行 Qemu I/O 操作的命令行工具。qemu-system-x86_64:Qemu 的核心应用程序,虚拟机就由它创建的。qemu-img:创建虚拟机镜像文件的工具,下面有例子说明。qemu-nbd:磁盘挂载工具。

下面通过创建虚拟机操作来对这些工具有个初步的认识。

2.2.3.3、创建虚拟机使用qemu-img创建虚拟机镜像

虚拟机镜像用来模拟虚拟机的硬盘,在启动虚拟机之前需要创建镜像文件。

 Copyqemu-img create -f qcow2 test-vm-1.qcow2 10G

-f 选项用于指定镜像的格式,qcow2 格式是 Qemu 最常用的镜像格式,采用来写时复制技术来优化性能。test-vm-1.qcow2 是镜像文件的名字,10G是镜像文件大小。镜像文件创建完成后,可使用 qemu-system-x86 来启动x86 架构的虚拟机.

使用 qemu-system-x86 来启动 x86 架构的虚拟机

 Copyqemu-system-x86_64 test-vm-1.qcow2

因为 test-vm-1.qcow2 中并未给虚拟机安装操作系统,所以会提示 “No bootable device”,无可启动设备。

启动 VM 安装操作系统镜像

 Copyqemu-system-x86_64 -m 2048 -enable-kvm test-vm-1.qcow2 -cdrom ./Centos-Desktop-x86_64-20-1.iso

-m 指定虚拟机内存大小,默认单位是 MB, -enable-kvm 使用 KVM 进行加速,-cdrom 添加 fedora 的安装镜像。可在弹出的窗口中操作虚拟机,安装操作系统,安装完成后重起虚拟机便会从硬盘 ( test-vm-1.qcow2 ) 启动。之后再启动虚拟机只需要执行:

 Copyqemu-system-x86_64 -m 2048 -enable-kvm test-vm-1.qcow2

qemu-img 支持非常多种的文件格式,可以通过 qemu-img -h 查看. 其中 raw 和 qcow2 是比较常用的两种,raw 是 qemu-img 命令默认的,qcow2 是 qemu 目前推荐的镜像格式,是功能最多的格式。这些知识后面会有文章来专门讲述。

2.3、KVM 和 Libvirt

libvirt 是一套实现 Linux 虚拟化功能的开源 API,旨在提供一种单一的方式管理多种不同的虚拟化方案。libvirt 由一套API库,一个libvirtd服务,以及一个virsh命令行管理工具组成。虽然libvirt是C开发的,但是可以很好的支持主流的编程语言,包括C, Python, Perl, Java 等等。

最新的发行版还包含了一系列基于 libvirt 的工具,用于简化虚拟机的维护管理:

virt-install: 一个创建虚拟机的工具,支持从本地镜像或者网络镜像(NFS、FTP等等)启动。virsh: 一个交互式/批处理shell工具,可以用于完成虚拟机的日常管理工作。virt-manager: 一个通用的图形化管理工具,可以用来管理本地或远程的Hypervisor及其虚拟机。virt-viewer: 一个轻量级的、能够安全连接到远程虚拟机的图形控制台工具。

简单的说,它是一系列提供出来的库函数,用以其他技术调用,来管理机器上的虚拟机。包括各种虚拟机技术,kvm、xen与lxc等,都可以调用libvirt提供的api对虚拟机进行管理。有这么多的虚拟机技术,它为何能提供这么多的管理功能那。是因为它的设计理念,它是面向驱动的架构设计。对任何一种虚拟机技术都开发设计相对于该技术的驱动。这样不同虚拟机技术就可以使用不同驱动,而且相互直接不会影响,方便扩展。而且libvirt提供了多种语言的编程接口,可以直接通过编程,调用libvirt提供的对外接口实现对虚拟机的操作。如今流行的云计算中的IaaS是与该库联系相当密切的。通过下图可以看出它的架构设计思想。

从该图可以看出,在libvirt api之上会有很多个driver,对于每一种虚拟机技术都会有一种driver,用来充当该虚拟机技术与libvirt之间的包装接口。如此设计就可以避免libvirt需要设计各种针对不同虚拟机技术的接口,它主要关注底层的实现,提供对外接口调用,而不同的虚拟机技术通过调用libvirt提供的接口来完成自己所需要的功能。

2.4、KVM - QEMU - libvirt 关系图2.5、KVM 与 Hypervisor

KVM是hypervisor的一种实现,开源的

2.5.1、Hypervisor是什么

Hypervisor 是一种运行在物理服务器和操作系统之间的中间软件层(可以是软件程序,也可以是固件程序),可允许多个操作系统和应用共享一套基础物理硬件,因此也可以看作是虚拟环境中的“元”操作系统,它可以协调访问服务器上的所有物理设备和虚拟机,也叫虚拟机监视器VMM(Virtual Machine Monitor)。

Hypervisor是所有虚拟化技术的核心。非中断地支持多工作负载迁移的能力是Hypervisor的基本功能。当服务器启动并执行Hypervisor时,它会给每一台虚拟机分配适量的内存、CPU、网络和磁盘,并加载所有虚拟机的客户操作系统。

Hypervisor 翻译过来就是超级监督者,被引申用为超级管理程序、超多功能管理器、虚拟机管理器、VMM。

2.5.2、Hypervisor分类2.5.2.1、Type-I(裸金属型)

指 VMM 直接运作在裸机上,使用和管理底层的硬件资源,GuestOS 对真 实硬件资源的访问都要 通过 VMM 来完成,作为底层硬件 的直接操作者, VMM 拥有硬件的驱动程序。裸金属虚拟化中Hypervisor 直接管理调用硬件资源,不需要底层操作系统,也可以理解为 Hypervisor 被做成了一个很薄的操作系统。 这种方案的性能处于主机虚拟化与操作系统虚 拟化之间 。

代表产品: Hyper-V,VMware ESX Server,Citrix XenServer,Oracle OVM for SPARC,KVM;

2.5.2.2、Type-II 型(宿主型)

指 VMM 之下还有一层宿主操作系统,由于 Guest OS 对硬件的访问必须 经过宿主操作系统,因而带来了额外的性能开销,但可充分利用宿主操作系统 提供的设备驱动和底层服务来进行内存管理、进程调度和资源管理等。主机虚 拟化中 VM 的应用程序调用硬件资源时需要经过:VM 内核->Hypervisor->主机内核 ,导致性能较差。

代表产品: VMware Server,VMware Fusion,Microsoft Virtual Server,Oracle VM Virtual Box,Oracle VM for x86, Solaris Zones,Parallels,Microsoft Virtual PC。

2.6、KVM 使用

创建KVM虚拟机常用的方法:

使用qemu-kvm命令创建虚拟机;使用virt-manager工具创建虚拟机;使用virsh工具创建虚拟机;使用Python调用libvirt接口创建虚拟机。2.6.1、准备磁盘镜像

创建KVM虚拟机前需准备虚拟机的磁盘镜像。虚拟机镜像用来模拟虚拟机的硬盘,在启动虚拟机之前需要创建镜像文件。两种常用方法:

使用qemu-img命令创建虚拟机镜像:# 创建10G大小、qcow2格式、名字是tiny.qcow2的镜像文件

qemu-img create -f qcow2 tiny.qcow2 10G使用现有的系统镜像文件,直接作为硬盘镜像启动虚拟机。2.6.2、创建虚拟机2.6.2.1、使用qemu-kvm命令创建虚拟机2.6.2.2、使用virt-manager工具创建虚拟机

创建KVM虚拟机最简单的方法是使用virt-manager工具。

以root身份启动virt-manager:

 [root@localhost ~]#  virt-manager

在virt-manager窗口中点击file菜单的"新建"选项,根据提示进行创建。

2.6.2.3、使用virsh工具创建虚拟机

使用virsh工具来创建虚拟机的话,需要再准备一个xml配置文件。这个xml文件对要创建的虚拟机进行了详细的配置。具体xml内容与配置方法可以参考libvirt相关文档。()

创建虚拟机命令:

 [root@localhost ~]# virsh create tiny.xml

其中,tiny.xml定义了要创建的虚拟机配置信息。

2.6.2.4、使用Python调用libvirt接口创建虚拟机

libvirt提供了支持主流编程语言的库,本文以Python为例,介绍创建虚拟机的过程。

参考:

「链接」

「链接」

【虚拟机】虚拟化技术以及KVM、QEMU与libvirt介绍_libvirt介绍和使用-CSDN博客

标签: #kvmubuntu14