虛擬化技術基礎原理
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.什么是叫虛擬化
將底層的計算機資源給它抽象(或虛擬)為多組彼此之間互相隔離的計算平台,每一個計算平台都應該具有計算機五大基本部件中的所有設備。
其實虛擬化有很多種類型,虛擬出一個完整的計算機只是其實現方式之一,目前為止,還有很多其他常見的虛擬化技術。比如說,像用戶空間的虛擬化,還有像庫級別的虛擬化等等。
二.CPU的虛擬化
CPU虛擬化有兩種方式:
1>.模擬(emulation,通過軟件實現【需要模擬環0,環1,環2,環3】,效率低);
2>.虛擬(virtulization,比如我們常用的VMwore workstation【只需要模擬環0】的軟件就是一款完全虛擬化平台)。
CPU執行時會有所謂的環的的概念,X86的CPU架構大概分成了四個層次,由內之外共有四個環,被稱為環0,環1,環2,環3。我們知道環0的都是特權指令,環3的都是用戶指令。環1和環2是為被使用的。
環0是特權環,所有的特權指令,包括直接操作硬件的,操作CPU當中某些敏感的寄存器的,尤其是跟硬件管控有關寄存器的都必須用環0的指令才能運行。而我們開發操作系統時,這個操作系統在研發時就明確知道自己是直接在特權級別的。也就意味着內核空間是在環0上執行。而用戶空間的進程它明確知道自己要使用任何特權資源都必須發起系統調用,是不可以直接執行特權指令的。
一般而言,對於虛擬機來說,CPU是通過軟件模擬出來的。我們用一個進程(也可能是一個線程)來模擬一顆CPU,供Guest使用。所以,虛擬化就是在我們虛擬機環境中要能創建一個用軟件生成的CPU供給guest使用。所以這個CPU也有自己的環0,環1,環2,環3等等,這個虛擬機運行在這個假的CPU中。這顆假的CPU同樣也擁有特權指令,只不過它執行時需要將指令傳給guest內核,guest內核並無權限執行特權指令(因為它是軟件虛擬出來的,並不是直接操作硬件的操作系統。)它
需要執行解碼,模擬等操然后轉換成host的特權指令的調用。整個過程是相當消耗時間的,所以基於這種方式實現虛擬化性能是非常低的。
那如何提示其性能呢?VMware公司引入了一個新的技術,即BT(Binary Translation )技術,它是一種直接翻譯可執行二進制程序的技術。它能夠讓Guest各虛擬機對特權指令的調用直接翻譯成對host主機的特權指令的調用,這就不用再軟件級別多次進行解碼操作,而是邊運行,邊調用,邊轉換。使得早起模擬的技術大大的提升了,簡單的將如果一個虛擬機所能夠獲取到的性能相當於硬件的60左右的話,基於引入BT技術的話,性能會提升到80~85%。

擴展小知識:
一般虛擬機模擬出來的硬件設備最好不要超過宿主機的配置,盡管我們的虛擬機是可以實現模擬的硬件設備高於宿主機的配置,但是運行起來效果並不是很好,它的配置要低於宿主機本身的配置效果最佳。即:如果虛擬機和底層的硬件架構一樣的話,Guest個各非特權指令就可以直接在CPU上運行。·
關於BT技術要注意的是:當宿主機操作系統是64位的時候,虛擬機可以是32位的也可以是64位的操作系統,但是當宿主機的操作系統是32位的時候,想要虛擬機是64位的操作系統,則CPU必須支持硬件虛擬化。
三.完全虛擬化(full-virtulization)
完全虛擬化的主要目的就是讓各個Guest並不能意識到自己是運行在虛擬化環境中的。
1>.BT:二進制翻譯(軟件虛擬化)
2>.HVM:硬件輔助的虛擬化(硬件虛擬化)
所謂硬件虛擬化就是讓CPU具有5個環,分別是:環3,環2,環1,環0,環-1。如下圖:

所以,我們稱之為環-1位虛擬化的根環(區域),這就意味着HOST主機內核運行在環-1上的(因為此時的它是特權指令環),各個Guest主機運行在環0上,此時環0雖然存在,但並沒有特權指令的,只是一個空殼而已。虛擬機的用戶空間一人是運行在環3上的。由於虛擬機內核運行在環1上,它會認為自己就擁有了特權指令,但是當他調用特權指令的時候,會HTOS內核是可以捕獲到各個Guest對於特權指令的調用,最后由CPU硬件自己轉換成(需要HOST內核的參與)-1環中的特權指令。這就叫硬件輔助的虛擬機,簡稱HVM。
四.半虛擬化(para-virtulization)
半虛擬化也有人稱之為准虛擬化,當操作系統發現需要調用操作系統的特權指令時,內核不是直接調用cpu的特權指令了,而是自己乖乖的去找宿主機的內核去請求,而不是茫然無知的調用硬件的特權指令。(它是明確知道自己是在虛擬化環境中的。)
VM monitor也叫hypervisor,它其實就是HOST宿主機。hypervisor直接管理硬件,它就相當於Host的內核,hypervisor可以管理底層核心硬件(一般而言指的是CPU和內存,不包括IO設備)設備。hypervisor把CPU和內存的使用分配過程給它虛擬成“hyper call”(可以理解成hypervisor調用)
hypervisor的好處就是當虛擬機在實現要執行特權指令時,只要調用的特權指令不會影響到其他的虛擬機或是hypervisor的就直接用虛擬機自己的內核去執行,如果會對其他的虛擬機有影響的話,會將這個特權指令發給“hyper call”,然后由“hyper call”自己到硬件上去執行,這個過程就省去了中間的翻譯的過程,即直接調用而非翻譯。
一旦使用了半虛擬化技術就必須要修改操作系統內核了,不然的話它就並不會知道對“hyper call”進行調用。hypervisor明顯比BT的翻譯技術更強了。半虛擬化是為了提高模擬轉換效率的,但是由於硬件的輔助的虛擬化出現,基本上半虛擬化可用武之地也少了。
五.內存虛擬化
Memory本身就是虛擬化的,因為進程使用的是線性地址空間,內核使用的才是物理地址空間。
1.在沒有安裝虛擬機的環境中,如果你只有一個操作系統,也沒有安裝虛擬化軟件。
當一個進程想要拿到一個數據,比如你用Golang語言定義了一個變量,如果你想要拿到這個變量所對應的數據,首先會將線性地址傳給CPU,我們知道線性地址是虛擬的,並不真實存在,這個時候CPU不會去這個線性地址取數據,而是將這個線性地址交給MMU,然后由MMU進行計算,將這個線性地址的對應的物理地址給找出來。並將這個對應關系在TLB中緩存。

2.如果在宿主機上安裝了虛擬化軟件,並在這個虛擬化新建了Guest。
我們知道上面沒有安裝虛擬機的內存轉換過程,那么推算出有虛擬機的內存轉換想必對家也不是難事,就是虛擬機的線性地址轉換成虛擬機的物理地址,但是宿主機而言,它仍然不是真正的物理地址,因此在虛擬機中的線性地址經過虛擬機的MMU的轉換得到的虛擬機的內存地址是不可用的,還需要讓宿主機的MMU再一次進行計算,才能得到真正的物理內存。這種效率那是相當的低啊。這樣頻繁的轉換也就罷了,在虛擬機來回切換時,也會存在一個坑,就是當宿主機由虛擬機A切換到虛擬機B時,必須將TLB的【轉換后援緩沖器(緩存頁表的查詢結果)】緩存清空,這樣TLB的功能基本上就起不到太大的作用了,這種實現虛擬化的方式我們稱之為:Shaow Page Table。
由於上述實現內存的虛擬化很低小,因此我們出現了一系列支持硬件虛擬化。
A.需要對MMU做虛擬化(MMU Virtulization):虛擬機將GVA轉換成GPA的同時,MMU虛擬化會自動將GVA轉換成HPA的,省略了GPA到HPA轉換的過程。
Intel:EPT(Extended Page Table)
AMD:NTP(Nested Page Table)
B.也需要對TLB做虛擬化(TLB virtulization):操作系統將TLB進行打標簽處理,表明是哪個虛擬機主機的線性地址對應着真正物理內存地址。
tagged TLB

六.I/O設備虛擬化
最基本的I/O設備有外存(硬盤,光盤,U盤),網絡設備(網卡),顯示設備(圖形設備器,即VGA),鍵盤鼠標(PS/2或者USB接口)。
I/O虛擬化的方式有三種:
1>.模擬(Hosted or Split):完全使用軟件來模擬真實硬件。
一個虛擬化軟件可以安裝多個Guest,如果這些Guest想要想外面發送數據的話,他們轉發的機制是什么呢?外面以一台Guest為例進行說明,首先,Guest的進程需要進行I/O請求,讓IO stack(棧)進行調度,通過網卡驅動將數據傳遞給虛擬機的模擬網卡,但是數據並不會被真正的發送出去,而是將數據發送到hypervisor(宿主機)上的虛擬化軟件(例如:VMware Workstation Pro)的虛擬化軟件網卡,然后通過hypervisor的IO Stack調用物理網卡驅動,最終將數據發送給真正的物理網卡,最終數據完成了發送。

我們知道模擬的網卡的工作模式之后,會發現數據在發送的時候,需要經過兩次的調用系統內核,一次是Guest自己調用虛擬機的物理網卡,另一次是在hypervisor上的再一次調用,效率是很低低下的。據說,模擬方式實現的虛擬化可以利用到物理網卡的70%就已經很不錯了。
2.半虛擬化(Hypervisor Direct ):
半虛擬化中,Guest的內核是明確知道自己是運行在虛擬化環境中的,所以在網絡數據傳輸時,通過前端驅動(IO Frontend,但是在用戶看來還是一塊物理網卡)將數據直接轉發給后端驅動(IO backend)。這樣就省去了模擬是Guest調用其內核驅動的步驟。很顯然這是一種很好的性能實現,在半虛擬化的確能使用到接近其物理設備95%左右的性能。

擴展小知識:
這種所謂的前端,后端驅動通常只適用於硬盤和網卡設備。所以存儲設備和網絡設備可以通過這種方式來虛擬。但是虛擬顯示設備是不可用這樣虛擬的,顯示設備的虛擬是通過Frame buffer(幀緩沖) 機制給每個虛擬機一個獨立的窗口來實現的。虛擬一個顯示設備是非常麻煩的,因為顯示是要通過顯卡來支持的,所以當虛擬機A切換到虛擬機B時:虛擬機A使用的顯卡的顯存內容會被清空。很多顯卡都有硬件加速功能在虛擬機上顯卡功能實現效果都不會特別好。你也不要妄圖在虛擬機上安裝一個大型的游戲(比如:魔獸世界,英雄聯盟等等)。
鍵盤鼠標都是通過完全模擬實現的,通過所謂的當前的焦點捕獲的方式來實現將模擬的設備和物理設備建立關聯關系。例如:當我們將鼠標移動到虛擬機里面是,並點擊虛擬機的界面,焦點被虛擬機捕獲到,我們輸入的所有的內容都會被虛擬機捕獲到(此時物理機是捕獲不到的)。所以我們可以說它是臨時建立關聯關系的方式來實現的。
3.IO-through,也叫IO透傳(Passthrough I/O)
在hypervisor的協調下讓虛擬機直接使用物理設備,它幾乎接近於硬件設備性能來使用硬件。
以上三種技術可用圖形表示為:

擴展小知識:
要實現I/O透傳技術的話((Passthrough I/O),一般也要求硬件必須有相應透傳功能的支持,也就是說你的主板上的一般實現I/O橋的功能要支持透傳技術。比如Intel的VT-d的技術,實現了I/O MMU.
4,.為什么要使用硬件虛擬化技術?
事實上,在我們傳統的PC(或是PC server x86)系統架構上,所有的I/O設備通常有一個共享的(或集中式)DMA(直接內存訪問)。在DMA中其實實現的是IO MMU,即IO 內存地址映射(當然你也可以叫IO 內存管理單元)。我們知道每個IO設備都是有寄存器的,每一個寄存器都有相應的IO端口(IO 地址)。因此,IOMMU就是實現從IO總線到IO端口轉換的的一個自動轉換設備,也在類似於主機上實現。很顯然,如果你能直接將一個IO設備直接分配一個某一個虛擬機使用的話,那么也就意味着,這個hypervisor級別的對於某個IO端口的調用就只能接受某一個虛擬機來進行了,因此我們必須在IO MMU界別上進行隔離的,而Intel的VT-d就是實現這種功能的。簡單的講:VT-d是基於北橋的硬件輔助的虛擬化技術。
擴展小知識:
Intel硬件輔助虛擬化:
第一類:跟處理器相關:vt-x;
第二類:跟芯片相關:vt-d;
第三類:跟IO相關:VMDq和SR-IOV;
七.虛擬化的兩種實現方式(兩種模型)
1.Type-I型
不需要在硬件安裝操作系統,讓虛擬化軟件(hypervisor,你可以理解它是一個虛擬機監控程序 )直接運行在硬件上,它可以直接接管CPU,內存等等,所有運行在當前物理硬件上的主機都是虛擬機。
典型代表有:xen,vmware ESX/ESXi.
2.Type-II型(易於管理,方便借助HOST的管理工具)
需要在硬件上安裝一個操作系統,在操作系統上安裝一個虛擬化軟件,通過虛擬化軟件創建各個虛擬機。
典型代表:kvm,VMware Workstation,Virtualbox
八.虛擬化技術分類
1.模擬
所謂模擬是指:在硬件之上安裝操作系統,在操作系統上安裝虛擬化軟件(也可以叫做虛擬環境模擬器[Emulator]),這個模擬器完全使用軟件模擬出來一套或多套硬件環境,這個模擬出來的每一套硬件環境都是不同的虛擬機。Emulator即使一個Emulator工具,也是一個虛擬機健康器,我們也可以稱之為虛擬機監控器(VMM).
著名的模擬器:
a>.PearPC;
b>.Bochs;
c>.QEMU;
2.完全虛擬化(Full virtualization)
也稱為原生虛擬化(native virtulization)。說白了就是我們CPU和內存不做模擬,只對它做相應的分配和管理,但是I/O等需要做模擬,內存由MMU進行管理。從某種意義上來講,它類似於模擬但也有別於模擬,完全虛擬化所虛擬的CPU架構跟底層物理平台的架構要保持一致。完全虛擬化要比模擬要高一點。有兩種加速方式我們上文已經提到了,即BT與HVM.
完全虛擬化的相關產品:
a>.VMware Workstation
b>.VMware Server
c>.Parallels Desktop
d>.KVM
e>.Xen(HVM)
3.半虛擬化(Para-Virtualization)
所謂的半虛擬化是因為我們必須要求其Guest OS內核是明確知道自己是運行在虛擬化環境中的,因此虛擬化的架構與底層的架構必須完全相同,而Guest OS還必須修改其內核,基於“hyper call”的ABI(因為Hyper call在hypervisor的運行環境中,所以叫做應用二進制接口,簡稱ABI,而在開發環境中我們稱之為API)調用來完成的。在半虛擬化中,虛擬出來的架構也必須和底層的架構保持完全一致。半虛擬化也有人稱之為准虛擬化。
半虛擬化相關的產品:
a>.xen;
b>.uml(user-mode linux)
4.OS級別的虛擬化
在底層硬件上運行一個內核,並在內核上運行一個虛擬化管理器,然后在虛擬化管理器上運行各個用戶空間的虛擬機,每個用戶空間都共享使用底層內核。相比以上幾種虛擬化化而言,這種性能是最好的(因為相比之下,中間少了一個轉換的層次),但是穩定性的話就相對弱一點(比如一個虛擬機將內核搞掛掉了,那么其他的虛擬機將無法使用了,因為他們是共用一個內核的)。被IDC很青睞.
OS級別的虛擬化相關產品:
a>.OpenVZ;(大型的IDC提供VPS使用的就是它)
b>.lxc
c>.Solaris Containers
d>.FreeBSD Jails
5.庫虛擬化
在Linux模擬出來一種Windows庫(Windows的ABI),所以,在Windows下安裝的軟件在Linux上都是可以安裝的,在Linux上跑windows程序,如安裝一個搜狗輸入法,安裝一個魔獸世界,英雄聯盟等等。性能也是相當不錯的。所以你可以大膽的將你的宿主機換成Linux版本的啦~哈哈
庫虛擬化的相關產品:
a>.wine,
6.應用程序虛擬化
給一個應用程序提供一個虛擬化環境。
應用程序虛擬化的相關產品:
a>.jvm
九.虛擬化網絡
1.橋接(bridge mode)
橋接模式其實就是將宿主機的網卡當成交換機來使用,然后自己再虛擬出來一塊橋接設備(用來接收真正發往本機的數據包的),其MAC地址和物理網卡的MAC是一致的,如果目標MAC是發往宿主機的就將數據包轉發給這個宿主機虛擬出來的物理網卡,如果目標MAC是發往虛擬機的,就將數據轉發給虛擬機網卡。存在的缺陷就是宿主機和虛擬機的數據包都通過宿主機的物理網卡進行收發包,這樣就很可能導致一台虛擬機不斷地往外部發包,而其他虛擬機的數據包發送不出去的情況。
2.僅主機(host-only mode)
通過軟件模擬的方式,在宿主機上虛擬出來一個交換機,然后讓各個虛擬機都連接到這同一個交換機且他們要再同一個網段,專業就實現了虛擬機之間的相互通信,但是為了讓宿主機也能和這些虛擬機通信,還需要在宿主機上虛擬出來一塊網卡,這個虛擬網卡也要連接到之前虛擬的交換機上,這樣我們只需要把這個虛擬網卡的IP配成和虛擬機一個網段就可以輕松實現宿主機和各個虛擬機的互聯啦。也就是說,僅主機能夠讓虛擬機之間進行通信,也能夠讓各個虛擬機和本機通信。但是虛擬機是和外部網絡是完全隔離的。
3.路由模式(routed mode)
其實路由模式和僅主機模式就是隔了一道門了,只要我們登門一腳就能讓他能夠輕松愉快的訪問到互聯網了,我們知道僅主機模式其實需要在宿主機中虛擬出來一塊網卡,讓其與虛擬機進行通信。說明虛擬機的數據包是可以到達宿主機的,這個時候我們虛擬網卡的數據包轉發給物理網卡就可以將數據輕松的發送給互聯網啦。
4.NAT模式(nat mode)
宿主機虛擬出來一個NAT服務器,虛擬機將數據發送到宿主機的虛擬網卡時,如果想要將數據發送出去,先將數據包的源IP地址(虛擬機的網卡地址)通過NAT服務器修改為物理網卡地址,然后再將數據發送出去,這樣將數據發送到目的端后,目的端發現發送來的源地址是其發送來的宿主機的物理網卡地址,而看不到真正的虛擬機的IP,從而實現了對虛擬機IP的一種保護機制。
5.隔離模式(isolation mode)
虛擬化軟件虛擬一個交換機,然后各個虛擬機都連接到這個虛擬交換機上,這樣就輕松實現了各個宿主機之間的互通,這個時候宿主機並沒有創建虛擬網卡連接到這個交換機上來,這樣就導致了虛擬機之間可以互相通信,並且宿主機無法連接到這個虛擬機的。
擴展小知識:
在計算機網絡中,TUN與TAP是操作系統內核中的虛擬網絡設備。不同於普通靠硬件網絡板卡實現的設備,這些虛擬的網絡設備全部用軟件實現,並向運行於操作系統上的軟件提供與硬件的網絡設備完全相同的功能。
TAP等同於一個以太網設備,它操作第二層數據包如以太網數據幀。TUN模擬了網絡層設備,操作第三層數據包比如IP數據封包。
操作系統通過TUN/TAP設備向綁定該設備的用戶空間的程序發送數據,反之,用戶空間的程序也可以像操作硬件網絡那樣,通過TUN/TAP設備發送數據。在后種情況下,TUN/TAP設備向操作系統的網絡棧投遞(或"注入")數據包,從而模擬從外部接收數據的過程。
關於橋接網卡的基本配置,可參考:http://www.cnblogs.com/yinzhengjie/p/7446226.html