一台PC机的组成包括:Keyboard(键盘)、Monitor(显示器)、CPU、RAM、I/O(Disk,Network),这是基本的五大部件。
虚拟化就是在这些基础物理设备上运行多个OS。
注:通过抽象系统资源(计算、存储、网络),在原有物理设备上模拟OS,来方便使用管理;
比如将服务器抽象为计算池、存储池、网络池,创建虚拟机时从其中抽取相关资源。
虚拟化和云计算:
虚拟化是一种技术,云计算是一种使用模式。 虚拟化是指将物理的实体,通过软件模式,形成若干虚拟存在的系统,其实真是运作还是在实体上,只是划分了若干区域或者时域划分。 云计算的基础是虚拟化,但虚拟化只是云计算的一部分,云计算其实就是在虚拟化出若干资源池以后的应用,但虚拟化并不是只对应云计算的。 虚拟化是云计算的重要支撑技术。是基于互联网的相关服务的增加、使用和交付模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。通过虚拟化,可以将应用程序和数据在不同层次以不同的方式展现给客户,为使用者和开发者提供便利的虚拟化过程,为资源带来了灵活性,从而改善IT运维和减少成本支出。
概念:
Guest OS:虚拟机操作系统
Guest Machine:虚拟出来的虚拟机
Hypervisor:虚拟化软件层/虚拟机监控机(Virtual Machine Monitor,VMM)
Host OS:运行在物理机之上的OS
Host Machine:物理机
CPU虚拟化------Ring0
在x86架构中CPU为了保护特权指令的运行,提供了指令的4个不同Privilege特权级别,术语称
为Ring,从Ring 0~Ring 3。Ring 0的优先级最高,可运行所有特权指令,Ring 3最低。而对于一个OS来说它必须是运行在Ring0上的,当然对于GuestOS来说也是如此,因此对于VMM就必须模拟让GuestOS认为自己是运行在Ring0上;这样当GuestOS向CPU发送一个特权指令时,VMM(虚拟机监控器,或叫Hypervisior)必须监测到并调用BT捕获这个特权指令,在BT进程内部将特权指令转换为非特权指令,然后,由VMM向宿主OS发起请求进行处理。
BT(Binary Translation): 二进制翻译器,它的作用是将GuestOS发出的特权指令转换为非特权指令,并交由宿主OS执行。它最早是由VMware采用的一种动态翻译技术,它将捕获的GuestOS发出的特权指令直接在其进程内部进行转换翻译,最终达到VMM所允许执行的指令,再交由宿主OS执行。
由于VMM并不是所有特权指令都可捕获,且有些特权指令执行失败后,并不会返回给GuestOS任何信息,还有在中断虚拟化带来的诸多问题VMM都不能很好的解决,因此,后来Intel和AMD分别通过硬件实现了直接由CPU自身来实现虚拟化,即VT-x(intel) 和 AMD-V;这两种解决方案的原理是一样的,在原先4个CPU等级执行环的基础上新增量一个Ring-1的环,将所有CPU的特权指令放到Ring-1中,并让宿主机的Kernel可运行于Ring-1中,这就将Ring0空闲出来,接着让GuestOS的Kernel可运行在Ring0中,GuestOS执行的特性指令直接有CPU进行翻译并交给Ring-1中 执行,这就是VT-X 和 AMD-V实现的硬件虚拟化。
注:即从四环变为五环,-1来放置特权指令,空出0给虚拟化使用。
KVM虚拟机:Kernel based Virtual Machine,系统内核中的一个模块,负责CPU虚拟化+内存虚拟化,实现了CPU和内存的虚拟化,但KVM不能模拟其他设备;
KVM:KVM代表着键盘(Keyboard)、显示器(Video)和鼠标(Mouse),即利用一组键盘、显示器或鼠标实现对多台设备的控制,在远程调度监控方面发挥着重要作用。KVM技术可以向远程终端发送调度信息网中的各项数据资料,为下一级调度机构提供方便,这样即便下级调度机构没有建立调度数据网,也能够实现信息的共享。
QEMU:开源的虚拟化模拟软件,能够模拟IO设备(网卡,磁盘),KVM加上QEMU之后就能实现真正意义上服务器虚拟化。
Libvirt:Libvirt是用于管理虚拟化平台的开源的API,后台程序和管理工具。它可以用于管理KVM、Xen、VMware ESX,QEMU和其他虚拟化技术。这些API在云计算的解决方案中广泛使用。
裸金属型虚拟化:性能好、开发难度大,不需要OS,实现困难 如:VMvare ESXi
宿主型虚拟化:性能差、开发难度小,依赖宿主OS,实现简单 如:VMvare Workstation
全虚拟化:虚拟机不知道自己是个虚拟机:修改VMM:让VMM主动找OS(改软件)
半虚拟化:虚拟机知道自己是个虚拟机:修改OS:让OS实现超级调用VMM(改软件)
硬件辅助虚拟化:(Intel、AMD改CPU硬件,让硬件支持虚拟化)
从服务器组件维度,分为CPU虚拟化、内存虚拟化、以及I/O虚拟化。
CPU虚拟化的目标是保障CPU资源的合理调度以及VM上的指令能够正常高效的执行,第4部分已对CPU虚拟化原理进行说明。
内存虚拟化目标保障内存空间的合理分配、管理,隔离,以及高效可靠地使用。全虚拟化中为每个VM维护一个影子页表(Shadow Page Table),记录虚拟化内存与物理内存的映射关系,VMM将影子页表提交给CPU的内存管理单元MMU进行地址转换,VM的页表无需改动。半虚拟化采用页表写入法,为每个VM创建一个页表并VMM注册。VM运行过程中VMM不断管理和维护该页表,确保VM能直接访问到合适的地址。硬件辅助内存虚拟化有Intel扩展页表EPT(Extend Page Table)和AMD 嵌入页表NPT(Nested Page Table)。EPT/NPT是内存管理单元MMU的扩展, CPU硬件一个特性,通过硬件方式实现GuestOS物理内存地址到主机物理内存地址的转换,比影子页表的系统开销更低,性能更高。
I/O虚拟化的目标是保障VM的IO隔离与正常高效的执行。全虚拟化通过对磁盘和网卡IO设备模拟,每次IO通过异常陷入Trap到VMM来执行,如ESXi。半虚拟化中可通过前端Front-end和后端Back-end驱动的方式实现,比如Xen在Dom U(Guest OS)中安装前端IO驱动,同时在管理虚拟机Dom 0中安装后端IO驱动。硬件辅助IO虚拟化有Intel VT-d与AMD IOMMU。VMM将IO 设备分配给特定GuestOS,数据直接写入设备,减少VMM参与IO处理,提升了性能。同时每个设备在系统内存中都有一个专用区域,只有对应的GuestOS才能访问,增强了系统安全性与可用性。
该方式采用软件模拟真实硬件设备。一个设备的所有功能或者总线结构(如设备枚举、识别、中断和DMA)等都可以在宿主机中模拟。而对客户机而言看到的是一个功能齐全的“真实”的硬件设备。其实现上通常需要宿主机上的软件配合截取客户机对I/O设备的各种请求,通过软件去模拟。比如:QEMU/KVM虚拟化中QEMU就可以通过模拟各种类型的网卡。
这种方式的好处是灵活,不需要专有驱动,因此能实现既不需要修改客户机、也无需考虑底层硬件,对客户机透明地使用网络资源。但是缺点在于,很多中断信号的处理需要让客户机感觉到自己运行在一个“真实环境”,因此QEMU软件模拟的很底层,效率低下。
在这种虚拟化中,客户机操作系统能够感知到自己是虚拟机,I/O的虚拟化由前端驱动和后端驱动共同模拟实现。在客户机中运行的驱动程序称之为前端,在宿主机上与前端通信的驱动程序称之为后端。前端发送客户机请求给后端,后端驱动处理完这些请求后再返回给前端。而在不同的虚拟化机制中,这一过程的实现手段也有所区别,例如:Xen中的共享内存、授权表,KVM中的virtio。它相比于全虚拟化的好处在于,不再需要宿主机上专门的软件去模拟实现I/O请求,因此不会有VM-exit,性能会有所提升。
半虚拟化中的virtio是IBM于2005年提出的一套方案[1],经过了十多年的发展,其驱动现在基本已经被主流的操作系统接纳编入内核,因此virtio也已经成为半虚拟化的一套事实标准。其主要结构如下图所示,前后端驱动通过虚拟队列通信,虚拟队列中又包含used ring、avail ring和desc ring。其具体接口标准参见IBM网站https://www.ibm.com/developerworks/cn/linux/1402_caobb_virtio/
对于性能的追求是永无止境的,除了上述全虚拟化、半虚拟化两种I/O虚拟化以外,还有一种非常极端的做法。让物理设备穿过宿主机、虚拟化层,直接被客户机使用,这种方式通常可以获取近乎native的性能。
这种方式主要缺点是:
1.硬件资源昂贵且有限。
2.动态迁移问题,宿主机并不知道设备的运行的内部状态,状态无法迁移或恢复。
DPDK针对这两点问题都做了一定程度的解决。另外还提供了一种基于硬件的PF(物理功能)转VF(虚拟功能),这相当于在网卡层面上就已经有了虚拟化的概念,把一个网卡的PF虚拟成几十上百个VF,这样可以把不同的VF透传给不同的虚拟机,这就是我们最熟悉的SR-IOV。
对于I/O透传在虚拟化环境中最严重的问题不是性能了,而是灵活性。客户机和网卡之间没有任何软件中间层过度,也就意味着不存在负责交换转发功能的I/O栈,也就不会有软件交换机。那么如果要想有一台server内部的软件交换功能如何实现呢。业界的主要做法是把交换功能完全下沉到网卡,直接在智能网卡上实现虚拟交换功能。这又带来了另一个问题,成本和性能的权衡。
而DPDK 18.05以后的版本似乎也解决了这一灵活性问题,为了充分发掘标准网卡(区别于智能网卡)在flow(流)层面上的功能,推出了VF representer。可以直接将OVS上的流表规则下发到网卡上,实现网卡在VF之间的交换功能,这样就实现了高效灵活的虚拟化网络配置。
参考:虚拟化原理介绍 - 张朝锋 - 博客园
参考:云计算及虚拟化必备知识 - 简书
参考:计算虚拟化详解 - 知乎
参考:浅谈网络I/O全虚拟化、半虚拟化和I/O透传 - 简书