概念解释
虚拟化(技术)是什么
虚拟化技术是一种资源管理(优化)技术,将计算机的各种物理资源予以抽象、转换,然后呈现出来的一个可供分割并任意组合为一个或多个(虚拟)计算机的配置环境。
(以上摘自《虚拟化技术发展编年史》)
计算机虚拟化技术简单说来就两点:虚拟化(抽象)+ 复用(转换);
虚拟化设备功能的实现最终要依靠硬件来承载(有例外),可以理解为是对硬件的复用技术;当然也有纯虚拟化设备比如tap类型的网口实现不依赖硬件,当然tap这个虚拟化设备能叫设备我理解也是一个泛型叫法。
计算机的物理资源有CPU、内存、I/O设备等其它硬件资源,比如地址译码器、HOST主桥、总线等,虚拟化技术是在有些硬件之上(硬件无关)实现,有些硬件模拟很简单;因此现在对虚拟化技术的讨论都围绕CPU虚拟化、内存虚拟化、IO虚拟化在说,在具体展开这三块之前先说下虚拟化系统的目标是什么。
虚拟化技术实现的虚拟化系统目标
资源控制、等价、高效
资源控制:虚拟化系统对于物理资源的访问要在hypervisor(VMM)监督下执行。为啥要在VMM监控下执行,为啥物理机上面的操作系统就不需要,虚拟机操作系统会被改,物理机有些操作系统也是从其它地方获取的,这怎么就不一样?
个人理解原因:一台物理机主人只有一个,物理机上面的虚拟机可能有多个租户,一个GVM出问题确实可能会伤及更多无辜;可能出现灰产通过GVM获取更多物理资源的使用,花小钱办大事走自己的路让别人无路可走。
等价:虚拟机上面的程序和物理机上面的程序应该是一样的(资源使用事实有区别)
高效:性能不能太差,大部分能力还得依靠硬件直接完成
CPU虚拟化
CPU虚拟化要解决的问题是什么
CPU是运算单元,从主存中取出指令执行,指令有特权指令、非特权指令;按照虚拟化系统目标要求来说捕获特权指令交由hypervisor来监督执行,非特权指令正常执行就可以了,问题就来了,非特权指令里面有一种叫敏感指令(很想举个具体例子,但是和zhuyifei沟通后有个例子很绕)也得监督执行,所以CPU虚拟化要解决问题就是:特权指令监督执行、敏感非特权指令也要监督执行。
特权指令监督执行其实一直就存在了,比如我们常说的进程上下文切换就是内核态用户态切换的机制,虚拟化技术也是一样,有了执行权限切换就可以hook指令监督执行了。敏感非特权指令就比较麻烦,因此也出现了多种不同的技术,CPU虚拟化实现其实更多是围绕敏感非特权指令监控方式展开的。
CPU虚拟化实现方式
纯软件全虚拟化、半虚拟化、硬件支持虚拟化
纯软件虚拟化
纯软件虚拟化实现方式,先出现了解释执行,一行行的翻译指令,把所有想关注的指令都可以接管,再后面又依次出现了二进制翻译、扫描与修补这两个应该是对第一个的优化,具体实现区别没有深究。
半虚拟化
修改下虚拟机操作系统里面敏感非特权指令调用方式实现,改为能让hypervisor监督到的方式,比如主动陷入hypervisor做CPU权限切换,这种实现方式就要改操作系统源码,闭源的没法做
硬件支持虚拟化
敏感非特权指令都改为“特权指令”,能被hypervisor捕获到,改变后有哪些问题:
向前兼容怎么办?
没有什么问题是adapter做不了的,加入一种模式:虚拟化模式;也就是说要使用硬件虚拟化的前提是得开启虚拟化模式(intel处理器就是Intel VX-x,AMD处理器是AMD-V)这里就有个点,如果不用虚拟化技术,就不要开启虚拟化模式,会增加部分指令的处理流程进而影响程序性能,比如在专用设备可以关注下,但是开着功能不会有影响,毕竟目标就是为了向前兼容嘛。
上下文切换怎么办?
对比没开启虚拟化模式肯定不一样了,引入了VMCS这种结构,又引出了读写指令等来支持虚拟化。
中断
CPU虚拟化除了指令还有中断也需要,中断这块先留着吧,还没有细看。
IO设备虚拟化
IO设备(硬件)简单介绍
IO设备就是用来和外界交互的输入输出设备,CPU和外部设备交互方式就是访问外部设备的寄存器或者外部设备内存等外部设备提供的资源。
IO设备(硬件)都干了啥
以网卡DMA方式为例,收方向:从光纤等链路上接收报文(物理帧)在CPU控制下把报文拷贝到主内存,发方向:在CPU控制下从内存取出报文生成对应物理帧,通过光纤等链路发送;看得出活基本都是IO设备在干,CPU对于IO设备来说就是指挥者,IO设备指哪打哪;对比DMA方式,其它方式CPU和IO设备的配置交互也是通过寄存器做,只是对数据的读取有区别,需要CPU参与度更高。
IO设备虚拟化要干什么
虚拟+复用
虚拟机操作系统里面看到的都是虚拟的设备,虚拟的设备要能复用物理设备才能完成具体功能,比如在虚拟机上面发http请求到百度,只有通过物理网卡报文才能发到百度;对IO虚拟化要做的是:把虚拟机的IO转为物理IO;
细一点描述就是:截获所有虚拟机的IO、转化成物理IO,促使这两条IO有条不紊的工作,需要返回的虚拟IO能正确返回。
IO虚拟化技术实现方式
纯软件全虚拟化、半虚拟化、硬件辅助
纯软件全虚拟化
也可以叫设备模拟,hypervisor要提供类比物理环境使用IO时和IO硬件初始化、配置交互的接口,虚拟机BIOS捕获该虚拟设备直到可以透明使用全流程模拟支持。
hypervisor捕获到IO请求后,再转换成物理IO请求,数据返回方向相反;
该实现方式下hypervisor可以跑在用户态,也可以在内核态。
可以跑在用户态的原因是:虚拟机的IO可以通过hypervisor调用系统调用使用物理IO,跑在内核态可以直接使用物理IO;
这两种都有弊端,跑在用户态会有大量上下文切换,跑在内核态要在内核做的事情有点多,跟操作系统强关联移植性又是个问题。
纯软件IO虚拟化的好处是虚拟机和物理机上面的原始IO驱动都不需要修改。
半虚拟化
和CPU半虚拟化思路一样,让虚拟机知道自己是虚拟机,本身驱动可以热拔插,也没有像CPU支持的那样需要修改操作系统源码,IO半虚拟化不牵扯内核代码开不开源的问题,新实现IO设备驱动就不是原来的实现方式了,和hypervisor直接交互,形成了一套交互协议就是现在的virtio,hypervisor拿到IO请求转化为物理IO,半虚拟化相比全虚拟化(尤其是全虚拟化的hypervisor)的改变是:可以支持批量IO(代码怎么实现的?),协议实现就和操作系统无关或者说依赖的就少了。
硬件辅助IO虚拟化
为什么不叫硬件IO虚拟化,虚拟机看到的IO设备还是需要通过hypervisor软件模拟的,纯硬件做不到完全支持IO虚拟化。
硬件辅助IO虚拟化的两种实现方式:VT-d和SR-IOV,这两种在问题回复里面有对应的一些细节。
VT-d的d就是直通的意思,虚拟机直接使用物理机上面的IO设备,比如一个虚拟机直接独占使用物理机的一张物理网卡,带来的问题也很明显设备要很多才够分(我认为一定程度上背离了虚拟化技术的定义)这种技术我认为在对一些IO要求高内部实现对操作系统有要求但某些时候又不能以硬件形式部署的场景,比如运营商采购某某软件产品金额较大的时候可以使用这种方式。
SR-IOV是对VT-d的改进吧,VT-d一张网卡只能对应一个虚拟机,SR-IOV技术可以让一张网卡对应多个虚拟机,在物理机的驱动层面和VT-d走的是不一样的流程,我理解在hypervisor应该是基本一样的。
内存虚拟化
内存虚拟化要解决什么问题
虚拟机对内存的访问最终会落到物理内存上,虚拟机有GVA、GPA,宿主机有HVA、HPA,GVA到HPA是最终的映射,这中间如何转换、转换实现方式是内存虚拟化要解决的主要问题。
内存虚拟化实现方式
纯软件虚拟化、硬件支持虚拟化、半虚拟化(和上面保持一致叫法)
纯软件虚拟化
GVA-GPA-HVA-HPA,Hypervisor虚拟机隐藏了内部转换,在使用MMU查询陷入Hypervisor时,把GVA-HPA的映射替换上去,这个映射对应关系起了个名字就影子页表。
硬件支持虚拟化
多引入一个寄存器,两个阶段的页表来查询,第一阶段GVA-GPA,第二阶段GPA-HPA
半虚拟化话
这个还没有太清楚