為跨平台而生
在計算機發展的早期,各類計算平台、計算設備所提供的接口、調用方式紛繁復雜,沒有像今天這樣相對統一的標准。由於需要適配不同的平台,需要寫很多繁瑣的兼容代碼,這無形中給開發者帶來了很大的不便。甚至,這種混亂出現在 IBM 這一家公司下不同機型的機器上,所以 IBM 的工程師們創造了虛擬化技術,用來幫助程序快速適配不同平台的物理機器。
我們知道程序對計算機資源的調用主要依賴於操作系統所給出的接口。我們的程序通過操作系統提供的接口,向物理硬件發送指令。
所以,要實現程序跨平台兼容的方法其實很簡單,只要操作系統或者物理硬件所提供的接口調用方式一致,程序便不需要兼容不同硬件平台的接口,而只需要針對這一套統一的接口開發即可。虛擬化技術正是通過其本身適配不同平台的硬件,而加以抽象成統一的接口,來實現程序跨平台運行這一目的的。
時至今日,我們之所以關注和使用虛擬化技術,實現跨平台運行應用程序依然是很大一部分的原因。
虛擬化的定義
虛擬化技術是一種將計算機物理資源進行抽象、轉換為虛擬的計算機資源提供給程序使用的技術。這里所指的計算機資源,就包括了 CPU 提供的運算控制資源,硬盤提供的數據存儲資源,網卡提供的網絡傳輸資源等。
將虛擬化用於資源管理
在虛擬化技術的發展過程中,人們逐漸發現了虛擬化的另一大用途,也就是將之應用於計算機資源的管理。
將虛擬化用於資源管理不難理解,因為虛擬化技術本身就是抽象計算機的物理資源進而加工成為提供統一調用接口的虛擬資源,很顯然在我們虛擬化硬件資源的時候很容易在其中做一些‘手腳’,來告訴應用程序一些虛假的資源數據。例如,我們只要告訴程序計算機只有 4GB 內存,那么不管真實的物理機是 8GB、16GB 還是 32GB,應用程序都會按照 4GB 這個虛假的值來處理它的邏輯。
通過虛擬化技術來管理計算機資源的方式,不但讓我們對計算機資源的控制變得更加靈活,也大幅提高了計算機資源的使用率。注意這里提高的是資源的使用率而不是效率。
其實將虛擬化用於資源管理還有很多優勢,例如我們想要在同一台機器上運行nginx和tomcat,很顯然這兩個應用程序都需要監聽80端口,如果不使用虛擬化,很顯然一台物理機無法同時提供兩個80端口。再比如同一台機器上運行的多個應用程序需要使用同一個工具庫的不同版本,程序本身限制了同時開啟的進程數等,這些都是物理機無法同時提供的資源。然而,虛擬化技術通過資源隔離的方式,無形地把這些程序隔離在不同的虛擬環境中,既然虛擬環境不同,自然運行在不同環境中的程序就不會互相干擾或爭搶資源了。
虛擬化的分類
從虛擬化實現的角度可以大致將虛擬化分為硬件虛擬化和軟件虛擬化,從架構角度又可以將虛擬化分為裸金屬架構和寄居架構,分類的方式多種多樣,在這篇文章中我們主要介紹硬件虛擬化、軟件虛擬化、裸金屬架構虛擬化和寄居架構的虛擬化。
硬件虛擬化是指物理硬件本身提供虛擬化的支持,舉個例子來說,某個平台的CPU可以將另外一個平台的指令轉換成自己平台的指令並執行,且給應用程序一種完全運行在那個平台上的感覺;再如,CPU 能夠自身模擬裂變,讓程序或者操作系統認為存在多個 CPU,進而能夠同時運行多個程序或者操作系統。
軟件虛擬化顧名思義是通過軟件的方式將硬件資源虛擬化成虛擬的資源,其本質是通過一層夾在應用程序和硬件平台之間的軟件層來實現指令的轉換。依然用 CPU 的例子來說,在軟件虛擬化實現中,通過一層夾雜在應用程序和硬件平台上的虛擬化實現軟件來進行指令的轉換。也就是說,雖然應用程序向操作系統或者物理硬件發出的指令不是當前硬件平台所支持的指令,這個實現虛擬化的軟件也會將之轉換為當前硬件平台所能識別的。
虛擬機
在虛擬化的實現中,我們不得不提的就是虛擬機,所謂虛擬機就是通過在應用程序和操作系統之間(寄居架構)或者操作系統與硬件資源之間(裸金屬架構)增加了一層用於指令轉換的虛擬機監視器以此來實現虛擬化,我們通常稱虛擬機監視器為Hypervisor。
從我們習慣用來搭建虛擬操作系統環境的 VMware Workstation、Xen 等軟件,到 Java 虛擬機 JVM,PHP 虛擬機 HHVM 等等,虛擬機都活躍在我們程序開發到程序運行的過程中。大家會很驚奇的發現原來 JVM、HHVM 等特定語言運行環境中的核心部分,也是虛擬化的一種實實在在的實現。沒錯,只要大家仔細分析和思考一下就會發現,它們正是基於虛擬化的思想來實現的。它們通過隔離程序和操作系統,將程序的指令轉換為當前所在操作系統平台所能執行的指令,達到了不用對程序進行任何修改即可執行的目的。也正是這個原因,這些語言的程序都具有非常強的跨平台性。
虛擬機看似實現了虛擬化,可以是的應用程序跨平台運行,那么虛擬機有什么缺點嗎?
很顯然虛擬機在運行應用程序的時候都需要經過虛擬機監視器處理才能執行,這無疑會帶來效率問題,了解決這個問題,真實的虛擬機程序常常不完全遵循 Hypervisor 的設計結構,而是引入一些其他技術來解決效率問題。
例如,在 VMware Workstation、Xen 中我們能夠看到硬件輔助虛擬化的使用,通過讓指令直達支持虛擬化的硬件,以此避開了效率低下的 Hypervisor。而如 JRE、HPHP 中,除了基於 Hypervisor 實現的解釋執行機制外,還有即時編譯 ( Just In Time ) 運行機制,讓程序代碼在運行前編譯成符合當前硬件平台的機器碼,這種方式就已經不屬於虛擬化的范疇了。
關於容器
或許有些人認為不應該把容器歸結為虛擬化的一種,不過另一派觀點認為,容器技術提供了相對獨立的應用程序運行的環境,也提供了資源控制的功能,所以我們依然可以歸納其為一種實現不完全的虛擬化技術。
那么什么是容器,容器到底具有什么優勢才能使其近些年來火遍大江南北呢?
關於容器技術,實現方式多種多樣,我們在此以docker為例進行介紹。docker容器技術指的是操作系統自身支持一些接口,能夠讓應用程序間可以互不干擾的獨立運行,並且能夠對其在運行中所使用的資源進行干預。正是這種資源的隔離使用才使得我們大可以將容器歸納為操作系統虛擬化的技術。也正是因為應用程序運行在一個個獨立的環境,類似於被容器包裹,我們才將這種技術稱之為容器技術。
那么容器技術相對於傳統的虛擬機有什么優勢呢?傳統的虛擬化中,應用程序執行都需要經過Hypervisor層進行指令轉換以達到應用程序跨平台以及硬件資源的分配使用,而在容器技術中,不存在Hypervisor層,應用程序直接運行於宿主機操作系統上,只是操作系統提供的一些功能使得應用程序可以相對獨立的運行並且能控制應用程序對資源的占用量,很顯然容器的執行效率更高。由於容器不存在指令的轉換,運行在容器中的應用程序自身必須支持在真實操作系統上運行,也就是必須遵循硬件平台的指令規則。很多同學這時候就有疑問了,指令都不轉換,也沒有解決程序跨平台兼容的問題,這算哪門子虛擬化技術。沒錯,這就是一些人不把容器歸結為虛擬化的原因。
在之后的文章中我將逐步開始介紹docker。