zl程序教程

您现在的位置是:首页 >  其他

当前栏目

KVM/QEMU/qemu-kvm/libvirt 概念全解

概念 kvm QEMU 全解
2023-09-27 14:28:47 时间

如果是刚开始接触虚拟机技术的话, 对上述的概念肯定会有所混淆, 傻傻的分不清. 尤其在看虚拟化技术文档时导致理解能力下降, 所以在开始学习虚拟化技术之前对这些概念有一个整体的认识和清晰的理解, 就显得很有必要了.


KVM(Kernel-basedVirtual Machine 基于内核的虚拟机), 狭义 KVM 指的是一个嵌入到 Linux kernel 中的虚拟化功能模块, 该模块在利用 Linux kernel 所提供的部分操作系统能力(如: 任务调度/内存管理/硬件设备交互)的基础上, 再为其加入了虚拟化能力, 使得 Linux kernel 具有了 转化 为 Hypervisor(虚拟化管理软件) 的条件.

NOTE: 上述语句中使用了 转化 一词, 而非 变成 或 成为.

这里写图片描述

但一般所说的 KVM 是广义 KVM, 即: 一套 Linux 全虚拟化解决方案 , 先了解一下更多的 KVM 细节:


KVM 内核模块本身只能提供 CPU 和内存的虚拟化 KVM 包含一个提供给 CPU 的 底层虚拟化可加载核心模块 kvm.ko(kvm-intel.ko/kvm-AMD.ko) KVM 需要在具备 Intel VT 或 AMD-V 功能的 x86 平台上运行, 所以 KVM 也被称之为 硬件辅助的全虚拟化实现.

由于 KVM 内核模块本身只能提供 CPU 和内存的虚拟化, 所以 KVM 需要一些额外的虚拟化技术组件来为虚拟机提供诸如 网卡/ IO 总线/显卡 等硬件的虚拟化实现. 最终变成了我们所使用到的 Linux 虚拟化解决方案.

QEMU(Quick Emulator) 是一个广泛使用的开源计算机 仿真器和虚拟机. QEMU 作为一个独立 Hypervisor(不同于 KVM 需要嵌入到 kernel), 能在应用程序的层面上运行虚拟机. 同时也支持兼容 Xen/KVM 模式下的虚拟化, 并且当 QEMU 运行的虚拟机架构与物理机架构相同时, 建议使用 KVM 模式下的 QEMU, 此时 QEMU 可以利用 kqemu 加速器, 为物理机和虚拟机提供更好的性能.


当 QEMU 作为仿真器时, QEMU 通过动态转化技术(模拟)为 GuestOS 模拟出 CPU 和其他硬件资源, 让 GuestOS 认为自身直接与硬件交互. QEMU 会将这些交互指令转译给真正的物理硬件之后, 再由物理硬件执行相应的操作. 由于 GuestOS 的指令都需要经过 QEMU 的模拟, 因而相比于虚拟机来说性能较差.

当 QEMU 作为一个虚拟机时, QEMU 能够通过直接使用物理机的系统资源, 使虚拟机能够获得接近于物理机的性能表现.

这里写图片描述


KVM 作为 Linux 的内核模块, 需要被加载后, 才能进一步通过其他工具的辅助以实现虚拟机的创建. 但需要注意的是, KVM 作为运行于 CPU 内核态 的内核模块, 用户是无法直接对其进行操作的. 还必须提供一个运行于 CPU 用户态 的对接程序来提供给用户使用. 而这个对接程序, KVM 的开发者选择了已经成型的开源虚拟化软件 QEMU.

KVM 开发者在对 QEMU 稍加改造之后, QEMU 可以通过 KVM 对外暴露的 /dev/kvm 接口来进行调用, 官方提供的 KVM 下载有 QEMU 和 KVM 两大部分, 包含了 KVM 模块、QEMU 工具以及二者的合集 qemu-kvm 三个文件.

这里写图片描述


在 Linux 全虚拟化解决方案 中, KVM 负责提供 CPU 虚拟化和内存虚拟化, 但是 KVM 对于一些计算机硬件设备还是无法进行完美的虚拟(如: 网卡/磁盘/ IO 设备…). 于是就引入了 QEMU, QEMU 负责提供硬件设备的虚拟化, 以此弥补来 KVM 的缺陷. 同时, 为了提高 QEMU 虚拟出来的虚拟硬件设备性能, 于是产生了 pass through 半虚拟化设备virtio_blk/virtio_net. KVM + QEMU 才能实现真正意义上虚拟化. 而 qemu-kvm 就是将两者整合到了一起的媒介.

qemu-kvm 通过 ioctl 调用 KVM 的 /dev/kvm 接口, 将 KVM 内核模块相关的 CPU 指令传递到内核模块中执行.

这里写图片描述

在 RHEL6/CentOS6 系统中, qemu-kvm 存放在 /usr/libexec 目录下, 由于 PATH 环境变量默认不包含此目录, 所以用户无法直接使用 qemu-kvm. 这样做是为了防止 QEMU 替代了 KVM 作为物理机 Hypervisor 的角色. 如果希望使用 QEMU 虚拟机, 可以通过将 /usr/libexec/qemu-kvm 链接为 /usr/bin/qemu 来实现.


Libvirt 是目前使用最为广泛的异构虚拟化管理工具及 API, 其具有一个 Libvirtd Daemon, 可供本地或远程的 virsh 调用.

libvirt 由 应用程序编程接口库、libvirtd 守护进程、virsh CLI 组成. 其中 libvirtd 守护进程负责调度管理虚拟机, 而且这个守护进程可以分为 root 权限的 libvirtd和普通用户权限的 libvirtd 两种. 前者权限更大, 可以虚拟出物理主机的各种设备.
开启 root 权限 libvirtd: sudo libvirtd --daemon

这里写图片描述


Libvirt 本质上是一些被提供的库函数(C语言), 用于管理物理机的虚拟机. 它引用了面向驱动的架构设计, 对所有的虚拟化技术都提供了相应的驱动和统一的接口, 所以 Libvirt 支持异构的虚拟化技术. 同时 Libvirt 提供了多种语言的编程接口, 可以通过程序调用这些接口来实现对虚拟机的操作. 由此可见, Libvirt 具有非常强的可扩展性, OpenStack 就与该库联系得相当密切.

这里写图片描述

在 KVM 中, 可以使用 virsh CLI 来调用 libvirtd, libvirtd 再通过调用 qemu-kvm 来操作虚拟机.

Libvirt的控制方式:


远程控制管理: Management Application 和 Domain 不再同一个 Node 上. 该模式使用了运行于远程节点上的 libvirtd 守护进程, 当在其他节点上安装 libvirt 时 Management Application 会自动启动, 并且会自动确定本地虚拟机的监控程序和为虚拟机安装驱动程序, Management Application 通过一种通用协议从本地 libvirt 连接到远程 libvirtd。

这里写图片描述


OpenStack 原生使用 KVM 虚拟化技术, 以 KVM 作为最底层的 Hypervisor, KVM 用于虚拟化 CPU 和内存, 但 KVM 缺少对 网卡/磁盘/显卡 等周边 I/O 设备的虚拟化能力, 所以需要 qemu-kvm 的支持, 它构建于 KVM 内核模块之上为 KVM 虚拟机提供完整的硬件设备虚拟化能力.

OpenStack 不会直接控制 qemu-kvm, 而是使用 libvirt 作为与 qemu-kvm 之间的中间件. libvirt 具有跨虚拟化平台能力, 可以控制 VMware/Virtualbox/Xen 等多种虚拟化实现. 所以为了让 OpenStack 具有虚拟化平台异构能录, OpenStack 没有直接调用 qemu-kvm, 而是引入了异构层 libvirt. 除此之外, libvirt 还提供了诸如 pool/vo l管理等高级的功能.

这里写图片描述


KVM 初探 KVM 是业界最为流行的 Hypervisor,全称是 Kernel-based Virtual Machine。它是作为 Linux kernel 中的一个内核模块而存在,模块名为 kvm.ko,也可以看作是一个进程,被内核调度并管理,从 Linux 2.6.20 版本开始被完全正式加入到内核的主干开发和正式发布代码中。