Openstack前传五(虚拟化技术原理)

来源:互联网 发布:淄博seo外包公司 编辑:程序博客网 时间:2024/05/20 07:19

1. GuestOS 虚拟地址--->Guest物理地址(Hypervisor 虚拟地址)---->宿主机物理地址

1.Vmware模拟出了一堆硬件,所以可以运行OS.但是分到的时间片很少
2.虚拟机的每个进程是连续的线性地址空间,但是Guest不能使用连续物理地址空间,因为Guest实际上拿到的物理内存也是底层虚拟出来的。
3.内存需要两次转换。两次转换,性能很差。 如何解决?
4.IO设备有限,如有很多虚拟机,如何虚拟化IO。 CPU虚拟化是CPU分片,而内存是通过Hypervisor整合成连续的地址以供使用。其实IO很容易实现虚拟化,网卡是如何虚拟的呢?如果是虚拟了网卡和MAC地址的话,物理网卡不会接收,那么虚拟网卡更不会接收。
**其实大多数IO设备都是用的【模拟】。对于硬盘来说,在真硬盘上建立一个本地镜像回环设备,即让dd创建文件和虚拟磁盘相关。而网卡呢,应该也是,模拟网卡,然后以文件的形式绑定。
当然硬盘够多的时候,也可以让虚拟机直接绑定真实硬盘,提升速度。


2.虚拟网卡

Bridge,NAT 都可以和外部通信,而Host—only不行。   NAT是地址转换,宿主机其实就是个网关设备。外部是看不到内部虚拟机地址的,因为转换出去的都是网关地址。
Bridge,将虚拟网卡和物理网卡都绑定到Bridge,并且运行在混杂模式。 只能在二层转给虚拟机,使用的二层代理机制。类似的是交换机。

3.特权指令虚拟(CPU虚拟)

Ring 0运行 的是特权指令(其中还包含了些敏感指令)。敏感指令(可能影响到其他进程的指令)
当进程要使用操作硬件相关的时候,需要执行特权指令,那么这时候就需要系统调用(System Call. )  内核要有捕获敏感指令的能力。
而虚拟机不行,因为虚拟内核捕获的敏感指令,当试图去运行敏感指令的时候,宿主机必须要有能力知道虚拟机试图运行敏感指令,不能让你运行。所以不能让虚拟机内核运行在Ring0上,只能运行在Ring3。  但是又不太合适,因为每个内核都希望运行在Ring0。 所以只能模拟,这样执行特权指令的时候也需要两次转换了。并且同时还要让虚拟机内核认为自己运行在Ring0上,如何解决?
而Ring0就是说有能力去运行特权指令,但是宿主机没说让你运行呀,只说明你有能力,当你要运行的时候,宿主机进行捕获。但是全部捕获还是有难度的。并且Host OS会很麻烦。这也就是x86面临的问题。
当面临特权及不够用的时候,解决办法就是新增了一个Ring -1.特权级更高了。

而这个促成了硬件虚拟化机制的出现:GUest运行在Ring0 上,而Host 运行在Ring -1上。Ring -1上运行的都是特权指令,而Guest上运行的是普通指令。当Guest要运行特权指令的时候,则会转到Ring -1上执行。

4.内存虚拟化

使用影子页表完成了内存虚拟化。 当每一个Guest试图转换成Guest物理地址的时候需要MMU,还会在宿主机上进行转换,这也需要MMU.
而影子MMU完成的就是一步到位转换成了宿主机上的物理地址。EPT (intel),NPT(amd).
最后地址转换后的地址是保存在TLB中的,所以不同的虚拟机切换的时候,TLB本来的效果就没啥用了。如何解决?这样TLB加了个虚拟机编号,称为标记。从而提升了TLB的命中率。

5.半虚拟化和全虚拟化

首先,半虚拟化性能好。 能直接由虚拟机完成系统调用,跳过了Hypervisor的跳转。这个需要使用CPU硬件虚拟化支持。
全虚拟化:如果CPU不支持硬件虚拟化,则只能模拟特权指令。全虚拟化需要各种中间转换,当然性能变差。

Windows没有办法运行在半虚拟化状态,因为需要修改内核。
而出现硬件虚拟化之后了,完全可以让CPU通过硬件虚拟化代替,而I/O虚拟化可以继续使用。


6.IO虚拟化

1.全虚拟化的时候,通过模拟,通过两次转换。
2.半虚拟化,通过系统调用。(前半段是修改了虚拟机内核后能直接调用hypercall,后半段在物理机中) 
3.IO透传,Guest直接管理硬件。前提是硬件很多的情况下才好用。






0 0