基本概念
虚拟化是指在一个物理上运行多台虚拟机,各虚拟机之间共享cpu、内存等资源,但在逻辑上是相互隔离的。这样的物理机被称为是宿主机,各个虚拟机被称为是客户机
虚拟化的本质是资源抽象化,将资源最小化,按需使用,从而提高资源利用率
Hypervisor(VMM)是虚拟机管理器,是虚拟化的核心,例如VMware Workstation就是一种Hypervisor,将物理机的硬件资源分给各个客户机,并保证彼此间的隔离
虚拟化的三种架构
1型:“裸机”型。宿主机不具有自己的操作系统,Hypervisor运行于硬件之上,相当于一个小型操作系统,负责管理和调动硬件资源。此时Guest OS需要进行一定修改,如添加驱动等;
2型:“托管”型。Hypervisor管理虚拟机,并将请求发送给宿主机的操作系统。这一架构性能差,请求指令需要依次经过Guest OS内核,Hypervisor,Host OS内核。例如,VMWare Workstation
3型:如容器技术,客户机不再拥有自己的操作系统,它将直接调用宿主机的实际资源,而不是虚拟化出的硬件资源。我的理解是指,在这种类型中,客户机不再像是一个独立计算机,而是一个个应用程序和运行这个程序的环境。将环境一起打包之后,就可以在任意机器上运行。
可结合后面的虚拟机分类一起理解
根据Hypervisor的虚拟机分类
前提知识:x86架构提供4个运行等级给操作系统和应用程序来调用硬件资源,其中Ring0为最高等级,Ring3为最低等级。以Linux+x86为例,操作系统内核需要直接调用硬件,因此它的代码运行在最高等级的Ring0上,而应用程序运行在Ring3上。这也是运行态和用户态需要切换的原因。
半虚拟化
Hypervisor运行在最高等级Ring0上,而Guest OS则运行在次等级Ring1上。客户机知道自己是在Ring1,并将修改自己的部分特权指令,以适应Hypervisor。
代表:Xen,VMware vSphere,Huawei FusionSphere
全虚拟化
同样的,Hypervisor运行在最高等级Ring0上,而Guest OS则运行在次等级Ring1上。但此时Guest OS不知道自己是虚拟机,而会像普通OS那样当作自己工作在Ring0上,因此不会进行修改。Hypervisor将捕获它的每一天指令,再交给宿主机OS
代表:KVM,VMware Workstation
操作系统虚拟化(容器)
不再有Guest OS,每个进程就像一个单独的虚拟机,拥有隔离出来处理的资源,根目录和内存空间等。此时应用程序及其依赖构成了一个可以独立运行的环境,能在任意宿主机上执行。这基于Linux内核中的namespace和cgroup实现
软件全虚拟化
用软件模拟任意硬件,但性能差,一般只用于研究测试。如QEMU
硬件辅助虚拟化
通过硬件实现的全虚拟化,通过修改CPU指令,Hypervisor仅捕获部分指令,加上是硬件上的修改,效率很快。常与全虚拟化结合形成硬件辅助全虚拟化,与全虚拟化相似但效率更高
虚拟机和容器
云平台中的虚拟机称为云主机
在传统虚拟化技术中,客户机被称为虚拟机,拥有自己的操作系统。容器技术中,虚拟机被容器替代
容器将应用程序及其依赖打包,以实现彼此隔离。容器不需要单独的操作系统,它本身就是一个运行应用程序的环境,不同容器共享宿主机的操作系统
容器更加轻量,启动迅速,更适合用在持续集成和持续部署(CI/CD)
Hypervisor管理工具对比
QEMU
软件模拟虚拟化,能够模拟出各种硬件
一种可以单独运行的软件,能够独立模拟出整个计算机。有两种工作模式,系统模式能够模拟出整个电脑系统,用户模式能够运行不同平台上的应用程序
KVM
KVM概念
KVM(Kernel-Based Virtual Machine)是一种基于Linux内核,采用硬件辅助的全虚拟化解决方案
KVM是一种轻量级的Hypervisor,它作为一个内核模块被集成在Linux内核中,主要负责虚拟机调度和内存管理两个方面
通过部署KVM,宿主机可以实现虚拟化功能,即能够在宿主机上创建多个虚拟机。但KVM不提供硬件模拟(即模拟出每一个虚拟机的内存、硬盘等)的功能,如无法模拟I/O外设,因此需要借助其他工具来模拟硬件设备,目前这个工具是QEMU。qemu能够模拟任意硬件,它经过修改与KVM结合,形成kvm-qemu,完成虚拟化功能。
KVM内核模块包括实现虚拟化的kvm.ko和处理相关的kvm_intel.ko(如果是AMD处理器,那就是kvm_amd.ko)两个部分。KVM本质上是一种管理虚拟机硬件设备的驱动,它将设备文件 /dev/kvm 暴露给宿主机,负责vCPU(虚拟机CPU)创建、内存分配、vCPU运行等
KVM的实现需要硬件支持,Intel VT 和 AMD -V 分别是intel和amd用于支持x86架构下虚拟化技术的相关cpu指令集,这些指令集在CPU硬件中引入。
KVM虚拟化组成
KVM由两个部分组成,分别是KVM Driver(内核态)和QEMU(用户态)
KVM Driver:负责CPU和内存的虚拟化,包括虚拟机创建、vCPU运行、内存管理等。它将拦截客户机的I/O请求,然后交给QEMU处理
QEMU:在KVM中作为一个普通的Linux进程,未客户机模拟出各种硬件设备,包括BIOS、PCI/PCIE总线、磁盘、网卡、显卡、声卡、键盘、鼠标等,并于KVM Driver交互
三种工作模式
1. 客户模式:执行非I/O的客户代码,虚拟机运行在这个模式下
2. 用户模式:用户执行I/O代码,QEMU运行在这个模式下
3. 内核模式:CPU调度和内存管理相关,KVM内核模块运行在该模式下
KVM属于宿主机的一部分,KVM与QEMU通过ioctl系统调用接口文件 /dev/kvm 进行交互
KVM工作原理
1. KVM内核模块被加载时(以Intel为例):
初始化内部数据结构
KVM模块检测当前CPU,打开虚拟化模式开关(通过虚拟化相关寄存器CR4),然后执行通过VMXON指令将宿主机置于虚拟化的根模式(什么是根模式?)之下
创建特殊设备文件 /dev/kvm,并等待来自用户空间的命令
2. 虚拟机的创建和运行依赖于KVM和QEMU的交互,这种交互是通过ioctl调用 /dev/kvm 文件实现。创建虚拟机时,KVM会返回一个文件句柄代表所创建的虚拟机。一个虚拟机就是一个kvm-qemu进程,与一般的Linux进程一样受Linux进程调度器管理
libvirt
Hypervisor例如kvm-qemu在使用时十分繁琐,加上Hypervisor种类众多,运用难度大。
libvirt是一个C语言库,其实质就是针对不同的Hypervisor命令做出了封装,并针对不同开发语言提供了api接口。libvirt运行在Hypervisor之上,能够管理包括XEN、KVM在内的多种Hypervisor,应用广泛。
目前主流Linux平台上的虚拟化管理工具都是基于libvirt开发的,例如virt-manager,virsh等
libvirt主要由三个部分组成,分别是API库,守护进程libvirtd,以及默认的命令行管理工具virsh
个人理解是虚拟机管理(命令行模式下)依赖于一系列Hypervisor命令,libvirt对这些命令进行封装并提供接口实现更加简洁的使用。更深入的理解可能需要在动手实践之后