virtualization
OS将对硬件资源的使用都虚拟成system call,某个进程只要与硬件打交道都要经过kernel提供的接口(system call)
rss(进程启动后必须要位于内存中,绝对不可以被交换出去(不被清出去))
page cache(进程运行时打开的文件,可放到交换分区中(可被清出去))
anon page(进程运行过程当中产生的数据,如堆中的一部分数据)
第一个进程运行打开一个很大的文件,第二个进程运行没有足够的内存时,内核会将第一个进程打开的文件(page cache)统统清出去,之后CPU又切到第一个进程时发现打开的文件没了,产生缺页异常,再重新从硬盘上调取
MMU(线性地址-->物理地址,MMU每次转换都要一级页目录查找、二级页目录查找,再平移计算才得到内存,为加速这个过程有TLB
CPU通过IO port知道在某时刻与哪个IO打交道(CPU与IO设备交换数据通过IO port实现),IO设备在启动时要向CPU注册它使用的IO port,一个IO设备可使用一片连续的IO port,并注册使用中断号(让IO设备通知CPU有紧急事件要处理)以实现当IO设备上有信号让CPU知道哪个IO设备有信号,而且要通过IO port与这个设备打交道,CPU通过可编程中断控制器让每一个IO设备注册使用中断线上的中断设备号,如网卡上有人ping来一个报文,要将产生的电信号读下来放在内存网络缓冲区,若是disk IO放在disk缓冲区(每个设备都有缓冲区)
站在OS内核角度,kernel认为自己可使用所有硬件:CPU(全量CPU时间片),内存(连续,全部的内存空间0x0000-max,32bitOS内存最开始1M给BIOS,16M留给DMA;64bitOS有1G给DMA,这1G内核也能用),I/O(全部可用IO)
VA(virtual address线性地址)
PA(physical address)
虚拟化(将一个物理硬件平台虚拟成多个)
vmware(模拟出一堆硬件设备,每一个硬件设备都是独立平台)
虚拟化要解决的问题(硬件之上的OS,有用户空间、内核空间;vmware虚拟机所模拟出的多个硬件平台上的每一个OS也有用户空间、内核空间;每个内核都意识不到其它主机存在,直接使用硬件设备(内存),这将会覆盖掉其它的正在使用的内存空间,产生资源争用会使系统崩溃,硬件之上的这个OS将内存留一部分给kernel用,其它的给进程用,vmware虚拟机及其它进程使用的内存是高地址内存空间(非0地址空间),关键是每个内核都要使用从0开始的内存地址空间)
guestOS(虚拟出来的虚拟机,内存地址转换要有两次,效率低,多个guest OS要与IO设备(网卡、磁盘)交互)
hypervisor(虚拟机管理程序)
CPU虚拟化(将时间片再分细点,指令分普通指令和特权指令,ring{0,1,2,3},ring0,privileged ring特权环是能运行敏感指令(特权指令)的,进程运行只能运行普通指令(进程在cpu上运行无非将进程的代码转换为cpu上运行的指令),要想用特权指令,如要访问硬盘、访问内存中的数据时通过system call,这时进程要退出,内核在cpu的ring0上运行;guest OS的kernel中同样有普通指令、特权指令,当guest OS上的进程需要运行特权指令(实际上管理虚拟机软件vmware的运行是在用户空间的,所以guest OS是不能运行敏感指令的,不能让虚拟机的内核运行在ring0上,只能运行在ring3上,否则它会将硬件资源视为可全量使用,会清空其它进程的内存、重启系统等操作)又不能运行这显然不合适,每一个kernel都认为自己在ring0上,通过模拟让guest OS认为自己在ring0上,保留一些关键的特权指令(如重启系统等),否则无法保证整个OS的安全性,实际上guest OS并不真正运行特权指令,每次guest OS的进程-->guest OS的内核-->host OS的内核,ring0就是一堆特权指令集来保证各guest OS间是隔离的,当host OS要关机就能控制整个系统关机,不管guest允不允许,host OS的内核才是真正意义的特权阶层,host OS要能监控每一个guest OS执行的指令并判定它能否运行)
X86平台要实现CPU的虚拟化面临的挑战(特权级压缩ring compression,VMM,virtual machine monitor必须要运行在ring0上,为避免guest OS控制系统资源,guest OS不得不降低自身的运行级别在ring3上(特权级不够使用),VMM使用分页或段限制的方式保护物理内存的访问,但64bit模式下段限制不起作用,而分页又不区分ring{0,1,2},为统一和简化VMM的设计,guest OS只能和用户进程一样运行在ring3上,VMM必须监控guestOS对GDT、IDT(CPU寄存器)等特权资源的位置,防止guest OS运行在ring0,同时又要保护降级后的guest OS不受guest进程的主动攻击或无意破坏;特权级别名ring alias,搞一些假的特权指令集告诉guest OS这就是ring0;地址空间压缩address space compression;非特权敏感指令;静默特权失败silentprivilege failure;中断虚拟化interrupt virtualization)
classicalvirtualization的基本需求(1974,Popek、Goldberg,真正意义的VMM至少需要三个方面的标准:等价执行equivalient execution,除资源可用性及时间上的不同之外,程序在虚拟化环境中及真正环境中的执行是完全相同的;性能performance,指令集中的大部分指令要能直接运行在CPU上;安全safety,VMM要能完全控制系统资源,某个guest OS运行不能影响到其它的guest OS,各guest OS间要实现隔离,且任何一个guest OS要执行特权指令,host OS要能提前捕获对其处理,任何一个guest OS都不能越过host OS对整个物理硬件发出任何特权控制指令)
注:Intel和AMD的CPU(X86)上有模糊地带(普通指令与特权指令间)
CPU硬件虚拟化(Intel:VT-x;AMD:AMD-V;特权级别加入ring-1,guestOS在ring0上,事实上ring0是空出来的一环没有指令,当guest OS试图要在ring0上运行时会触发ring-1,由ring-1决定执行指令、转换并翻译这个指令运行)
内存虚拟化(将离散的内存地址空间在hypervisor上再整合在一起分给guest OS,guest OS的VA-->guest OS的PA-->host OS的PA(HA))
IO设备虚拟化(网卡、硬盘等大多数的IO设备是通过软件(如vmware)模拟(假网卡、假硬盘),guest OS的网卡往外发报文(IP报文本身是独立的),来的报文哪个主机收(guest OS还是host OS),是根据MAC接收报文的,假硬盘上存的数据最终都要到物理硬盘上,在物理硬盘上建立本地回环镜像文件(如用dd命令创建的文件,格式化后能充当swap分区用)与模拟的磁盘建立关联关系,guest OS就把假硬盘当硬盘用,但真正在物理机上表现的是个文件,虚拟的磁盘没物理硬盘性能好,IO要转换两次,若要让guest OS的IOdisk性能好点,使用共享存储(iSCSI),guest OS作为client直接使用共享存储;网卡也是这样,模拟一个假网卡与本地的文件建立关联关系,guestOS A同guest OS B之间经网卡通信(或guestOS同host OS通信)借助于OS通过IPC解决(vmware中有虚拟通道),无论使用什么MAC都无所谓,若与外部网络通信,通过bridge、NAT,NAT这种方式是将物理机网卡上的MAC当作网关,源地址转换,类似各guest OS组成网络,要与外部网络通信时将报文发至网关,物理机通过地址转换送到外部网络,外部网络是看不到guest OS的,bridge这种方式将guest OS的虚拟网卡绑定在物理网卡上且让物理网卡运行在混杂模式下(无论目标MAC是不是它都要接收,接收下来转给guest OS,二层代理机制,在二层就转了),bridge这种方式可将物理网卡理解为是switch,host OS的网卡可理解为也是虚拟网卡,guest OS上的网卡也是虚拟网卡,物理网卡接收到报文目标MAC是哪个虚拟网卡就转发到对应的虚拟网卡上(桥接就是网桥,模拟的是switch))
Intel(EPT,extended page tables)和AMD(NPT,nested pagetables)分别通过EPT、AMD为虚拟化应用提升shadow MMU(完成VA-->HA一步到位)的性能,并通过标记tagged TLB来避免虚拟机切换时频繁清写flush TLB以提高TLB缓存的命中率(用TLB保存MMU的转换结果)
半虚拟化PV(IO设备虚拟化,guestOS的kernel-->vmware-->host OS的kernel-->物理网卡,性能不好,若直接与host OS的内核打交道则性能会好很多,将中间那步绕过去,模拟的文件该存在让它存在直接绕过它,将host OS网卡的驱动程序做成system call直接输出给虚拟机使用(guest OS-->host OS的system call),这违反虚拟化原则,guest OS就知道它在虚拟化环境中,这种技术叫半虚拟化paravirtualization,性能好,直接与硬件打交道速度要快)
完全虚拟化full virtualization(guest OS不认为它在虚拟化环境中;CPU不支持硬件虚拟化技术,要模拟特权指令)
硬件辅助的虚拟化HVM,hardware-assistant VM(CPU支持硬件虚拟化技术,VMM运行在ring-1,guest OS运行在ring0,HVM,hardware-assistant VM,硬件辅助的虚拟化)
PV和HVM整合(guest OS知道自己在虚拟化环境中,只要与硬件打交道,host OS都向guest OS输出systemcall(将特权指令集也输出为system call)或叫hypercall(hypervisor call),这样性能会好很多,要求在PV下的OS必须要改内核才能使用hypercall(win不能改内核)
PVon HVM (基于HVM的PV技术,把PV中的CPU不用了而用HVM,用IO的PV,这样既利用了CPU的HVM,又利用IO的PV技术,性能会很好)
注:cpu、memory、io都可用PV,有了HVM,cpu的PV将用不着,io的PV能用得上,硬件再辅助,某一种IO设备就那一个,有资源争用
IO穿透技术passthrough I/O( guest OS直接使用独立的网卡)
常见的虚拟化模型:
有宿主机的VMM,VMM要借助于内核才能完成虚拟化(hosted VMM)
硬件之上直接是VMM,这种模型下的VMM称为hypervisor,VMM具备OS的管理机制(VMM自带对CPU、memory等的管理),可理解为是精简的OS只提供虚拟化服务,VMM具备驱动底层硬件的能力(安装前要查看VMM所支持的硬件类型)
注:vmware workstation,vmware server,vmware ESX商业(hypervisor),vmware ESXi(免费,简易版)
Xen提供对CPU、memory、interrupt这三个关键性硬件管理外,其它功能如驱动等都不提供,Xen它自己驱动不了任何硬件设备,要在Xen之上立即安装一个虚拟机(Linux),这个特权Linux提供驱动,提供管理界面,可直接操作底层硬件,Xen中的虚拟机称为Dom{0,1,2,3……}(domain),Dom0为特权虚拟机,通过Dom0来管理其它的Dom{1,2,3}(称为DomU),Dom0要使用CPU、memory、interrupt这三个关键性硬件要通过Xen,而其它的IO设备可直接使用,在Dom0上创建一模拟设备,要通过Xen关联至Dom1上(Dom0将半虚拟化的硬件驱动程序通过Xen的hypercall送给Dom1),Dom1要使用网卡向外发数据要先发至Dom0由Dom0访问硬件网卡,Xen不管理IO等硬件设备,Dom1要使用CPU(或memory或interrupt)则直接由Xen管理,这样一部分要交由Xen管理,一部分交由Dom0管理,Xen是一种半虚拟化的解决方案,就算cpu、memory不支持HVM,Xen照样可高性能运行,若cpu、memory支持HVM,Xen也可使用fullvirtualization,各硬件是模拟的性能较差,完全虚拟化FV和PV的最大区别,FV中的guest OS的kernel不用修改了,那Xen之上的虚拟机可使用win了(FV的好处),若Dom1是Linux可使用PV on HVM(CPU不虚拟化了使用HVM,而对于其它的IO硬件使用PV))
Qemu(模拟器,1M,虚拟化软件,跨平台虚拟,如将硬件CPUx86的模拟成苹果的arm或IBM的power pc,可帮助程序员提供测试环境,好处如底层是X86的CPU,可在guest OS上也使用X86的CPU并进行优化,让其接近硬件CPU的性能运行)
注:通常Xen和Qemu结合使用,Qemu主要实现为其它guest OS基于软件方式模拟硬件(虚拟网卡、虚拟硬盘等)、本地回环文件(用文件充当虚拟硬盘用),Qemu-img支持众多的格式,包括vmware的格式
Xend/xm(在Xen上创建虚拟机,安装OS并引导,Xen提供了专门的管理工具Xend/xm,Xend是管理服务,xm是命令(可start、pause、suspend某个虚拟机,完全在CLI下),Xen将其对硬件的管理功能通过API输出给xm这个管理工具,创建好硬件好不用重启直接附加在虚拟机上并能让虚拟机识别出来,Xen可虚拟CPU,用xm通过Xen的API创建多个CPU,虚拟机可直接使用,比vmware workstation要强大灵活,通过Xen的API可开发出图形管理工具,有数十种管理工具(CLI下和GUI下),如openstack、cloudstack,这些云平台就是利用虚拟机(Xen)的API提供了能指管理虚拟机进程的管理程序
注:如redhat为Xen提供的管理工具virsh比xm更强大且易用,virsh支持众多虚拟化技术且更通用
KVM(kernel-based VM,基于内核的虚拟机,KVM是内核模块,没有这个模块OS还是本来的OS,这个模块一旦被kernel装载了,OS就摇身变成了hypervisor,KVM可让OS成为hypervisor,KVM取巧利用内核提供的各种驱动,在OSkernel的基础上成为hypervisor,在hypervisor之上跑的是虚拟机(实际上是进程),用ps也能看到,内核自身管理硬件,在内核之上还要提供OS用来管理虚拟机,在硬件之上的OS之上的OS可启动额外的进程(虚拟机),所有的虚拟机都表现为进程,在guest mode(来宾模式)下有user space和kernel space)
KVM如何使用硬件(kernel将CPU时间片分给虚拟机;memory,kernel虚拟化一部分即可;io device,管理的OS模拟硬件,虚拟机用网卡时,虚拟机的kernel-->管理的OS模拟的硬件-->真正的kernel-->硬件(类似Xen);模拟硬件借助Qemu,它可虚拟化任何硬件,乍看KVM是多余的,没有KVM,Qemu照样可虚拟化,KVM有Qemu没有的优势,Qemu对CPU的虚拟是在user space通过软件模拟加速实现的,性能再好也无法与kernel性能相比,而KVM是内核模块比Qemu模拟出的硬件性能要好,更能接近硬件性能)
注:通常使用KVM+Qemu,KVM要求只能装在支持硬件虚拟化的CPU上,而且只能在X86_64平台(Xen若硬件不支持虚拟化可半虚拟化);KVM在2.6.20中直接整合进kernel上,Xen没有;2.6.37以后Xen也加入kernel(注意是运行在Xen上的DomU);3.0以后的kernel运行在Dom0上的Xen也收入内核(也就是3.0以后的kernel可直接使用Xen,3.0之前的kernel要使用Xen得打补丁);redhat2008年收购了KVM(以色列公司的KVM),redhat6.0之后只支持KVM;Xen比KVM强大、稳定,Xen(英国剑桥大学)被Citrix思杰(仅次于vmware第二大虚拟化提供商)收购
redhat(KVM)、citrix(Xen)、vmware(vmware)、microsoft(hyper-V)
注:KVM(redhat引入virtio(将IO实现PV),支持passthroughI/O
container(在kernel之上提供了user space(有对网卡、硬盘的配置程序,可理解为是VM),kernel是公共的,性能比FV和PV要好,对于FV和PV要运行两个kernel,若任何一个VM管理不慎将kernel搞崩溃了,其它VM将不能正常运行,VM间隔离效果没FV和PV好)
openVZ(Linux上的container技术,很多IDC提供VPS(virtualprivate server)时使用openVZ或Xen)
wine(虚拟出win的库,这样win的所有程序都能运行,cywin在win下虚拟linux的库运行linux程序)
注:只要底层有真正硬件,所有硬件都能模拟,Qemu还可跨平台模拟
常见的虚拟化技术(virtualization products at a glance):
IO虚拟化(Intel和AMD在主板上创建芯片组时,这个芯片组可完成IO虚拟化(在硬件级别上),如Intel:IOMMU,IO设备要映射到当前OS上,为IO分配缓冲区,在passthrough技术上要借助IOMMU)
X86平台虚拟化技术(Intel:VT-x、EPT、IOMMU)
虚拟化中的网络模型(如vmware下的NAT、host-only、bridge、vmnet{1,2,3},NAT模型下可自动分配IP):
可理解为VMM用软件模拟了一个switch,创建的虚拟机VM1只要关联到虚拟网络上,就意味着关联到虚拟的switch上,这个虚拟的switch是连到host OS的虚拟网卡上的(网上邻居可看到vmnet1);host-only,VM1通过虚拟网卡可与物理机通信,不能同外部网络通信,若在物理机上有一dhcp服务指定在物理网卡上,switch不隔离广播报文,那VM{1,2,3}均可获取到地址;虚拟通道是专用网络,如vmnet2是仅模拟了一个switch,物理机上没有对应的虚拟网卡,仅能让在此虚拟通道上的VM{1,2,3}通信;NAT模型下VM{1,2,3}可访问外网,而外网主机不能主动访问VM{1,2,3}除非做DNAT规则要定义在物理主机上(win下的vmware会自动生成规则,而linux下要自己写规则);bridge模型下可理解为物理网卡成为了模拟的switch,所有的报文都通过switch出去,对于发来的报文switch会全部接收下来,再根据MAC判断是哪个网卡上的,是物理网卡还是VM{1,2,3}的网卡,桥接时是不提供dhcp服务的
虚拟机多时,彼此间通信要统一管理会比较麻烦,openstack和cloudstack提供了一种平台,能让物理机随时能加进来,如当前的物理机不够用再加几台进来,正在运行的虚拟机流动的在不同的物理机上运行(实时迁移),某一物理机出问题,其上的虚拟机会迁移到其它物理机上运行,不影响虚拟机的使用,云还能管理网络,虚拟机加进来后要给这个虚拟机分配IP,如何与其它公司的虚拟机隔离,云还要提供存储,云为虚拟机更方便的使用提供了统一管理的接口(IaaS基础架构即服务)