Docker學習筆記之淺談虛擬化和容器技術

0x00 概述

相信全部對 Docker 有所耳聞的朋友都知道,它是一款以容器虛擬化技術爲基礎的軟件,所以在瞭解有關 Docker 的概念知識和使用方法以前,虛擬化和容器技術是咱們不可或缺的基礎知識。在本小冊的第一個小節裏,咱們就先來嘗一嘗這道有關虛擬化和容器技術的開胃菜吧。微信

 

0x01 虛擬化技術

若是要用簡單的語句來闡述虛擬化技術的話,那麼能夠這麼解釋:網絡

# 虛擬化技術是一種將計算機物理資源進行抽象、轉換爲虛擬的計算機資源提供給程序使用的技術。

這裏所指的計算機資源,就包括了 CPU 提供的運算控制資源,硬盤提供的數據存儲資源,網卡提供的網絡傳輸資源等。工具

 

0x02 爲程序跨平臺兼容而生

虛擬化這個概念並非什麼新事物了,早在 20 世紀 60 年代,IBM 就用它來描述一套可以抽象硬件資源的實驗性系統。性能

在計算機技術發展的早期,各種計算平臺、計算資源所提供的接口、調用方式十分雜亂,沒有像今天這樣相對統一的標準。因爲要適配不一樣的平臺,寫各類兼容代碼,這無形給開發者帶來了不少的困擾。這種混亂甚至都出如今 IBM 這一家公司下不一樣機型的機器上,因此 IBM 的工程師們創造了虛擬化技術,用來幫助程序快速適配不一樣平臺的物理機器。spa

熟悉計算機原理的朋友應該知道,程序對計算機資源的調用主要依賴於操做系統所給出的接口。咱們的程序經過操做系統提供的接口,向物理硬件發送指令。操作系統

因此,要實現程序跨平臺兼容的方法其實很簡單,只要操做系統或者物理硬件所提供的接口調用方式一致,程序便不須要兼容不一樣硬件平臺的接口,而只須要針對這一套統一的接口開發便可。虛擬化技術正是經過其自己適配不一樣平臺的硬件,而加以抽象成統一的接口,來實現程序跨平臺運行這一目的的。設計

時至今日,咱們之因此關注和使用虛擬化技術,實現跨平臺運行應用程序依然是很大一部分的緣由。3d

 

 0x03 將虛擬化應用於資源管理

在虛擬化技術的發展過程當中,人們逐漸發現了虛擬化的另外一大用途,也就是將之應用於計算機資源的管理。code

這其中的道理其實並不複雜,虛擬化技術自己就是抽象計算機的物理資源進而加工成虛擬的計算資源的,它天然很容易從中作「手腳」,來告訴應用程序一些虛假的資源數據。例如,咱們只要告訴程序計算機只有 4GB 內存,那麼無論真實的物理機是 8GB、16GB 仍是 32GB,應用程序都會按照 4GB 這個虛假的值來處理它的邏輯。blog

經過虛擬化技術來管理計算機資源的方式,不但讓咱們對計算機資源的控制變得更加靈活,也大幅提升了計算機資源的使用率。

部分同窗一直有一個誤解:實現虛擬化的程序自己就要佔用計算機的資源,而運轉在其中的程序也不會下降它們對資源的消耗,怎麼又會產生 1 + 1 < 2 的效果呢。

這裏要注意了,咱們所說的是提升計算機資源使用率,而非減小程序資源的佔用率,這二者看似很相近,其實並不是是同一個概念。虛擬化技術可以提升計算機資源的使用率,是指利用虛擬化,咱們能夠將原來程序用不到的一些資源拿出來,分享給另一些程序,讓計算機資源不被浪費。

例如,這裏咱們有一臺運行 Nginx 的機器,因爲 Nginx 運行對系統資源的消耗並不高,這就讓系統幾乎 95% 以上的資源處於閒置狀態。這時候咱們經過虛擬化技術,把其餘的一些程序放到這臺機器上來運行,它們就可以充分利用閒置的資源。這帶來的好處就是咱們不須要再爲這些程序單獨部署機器,從而節約很多的成本。

 

部分讀者讀到這裏就會產生疑惑了,我自己就能夠在操做系統裏安裝這些程序而且同時運行,爲何還要把它們分別裝到不一樣的虛擬環境中去呢?

其實道理很簡單,雖然咱們可以在操做系統裏同時運行多個程序,但前提得是這些程序自己不存在衝突。這裏的衝突體如今不少的方面,例如不一樣的程序同時使用了同一個端口;不一樣程序依賴於同一個工具庫的不一樣版本;程序自己限制了同時開啓的進程數等。虛擬化技術經過資源隔離的方式,無形地也能夠把這些程序隔離在不一樣的虛擬環境中,既然虛擬環境不一樣,天然運行在不一樣環境中的程序就不會互相干擾或爭搶資源了。

 

 0x04 虛擬化的分類

 

說完虛擬化的起源和應用,咱們得說說虛擬化的分類了。所謂虛擬化的分類,其實主要指的是咱們在實現虛擬化的方式上的區別。

對於虛擬化技術的分類,有不少種不一樣的方式,有的之間也有互相重合的部分,但整體來講能夠區分爲兩大類:硬件虛擬化、軟件虛擬化。

所謂硬件虛擬化,指的是物理硬件自己就提供虛擬化的支持。舉個例子來講,某個平臺的 CPU,可以將另一個平臺的指令集轉換爲自身的指令集執行,並給程序徹底運行在那個平臺上的感受。又或者說,CPU 可以自身模擬裂變,讓程序或者操做系統認爲存在多個 CPU,進而可以同時運行多個程序或者操做系統。這些都是硬件虛擬化的體現。

而軟件虛擬化則指的是經過軟件的方式來實現虛擬化中關鍵的指令轉換部分。依然用 CPU 的例子來講話,在軟件虛擬化實現中,經過一層夾雜在應用程序和硬件平臺上的虛擬化實現軟件來進行指令的轉換。也就是說,雖然應用程序向操做系統或者物理硬件發出的指令不是當前硬件平臺所支持的指令,這個實現虛擬化的軟件也會將之轉換爲當前硬件平臺所能識別的。

固然,在實際場景中,虛擬化還能進行更加細化的分類,例如:

  • 平臺虛擬化:在操做系統和硬件平臺間搭建虛擬化設施,使得整個操做系統都運行在虛擬後的環境中。
  • 應用程序虛擬化:在操做系統和應用程序間實現虛擬化,只讓應用程序運行在虛擬化環境中。
  • 內存虛擬化:將不相鄰的內存區,甚至硬盤空間虛擬成統一連續的內存地址,即咱們常說的虛擬內存。
  • 桌面虛擬化:讓本地桌面程序利用遠程計算機資源運行,達到控制遠程計算機的目的。
  • ……

因爲虛擬化的分類實在太多,且不是這本小冊關注的重點,這裏就不所有羅列了。總之,從實現上來講,皆是硬件虛擬化和軟件虛擬化兩個方案的相互組合、組裝而得。

 

0x05 虛擬機

在這些虛擬化分類或者說是虛擬化實現中,咱們要着重講一下虛擬機 ( Virtual Machine )。所謂虛擬機,一般來講就是經過一個虛擬機監視器 ( Virtual Machine Monitor ) 的設施來隔離操做系統與硬件或者應用程序和操做系統,以此達到虛擬化的目的。這個夾在其中的虛擬機監視器,經常被稱爲 Hypervisor。

之因此咱們在這裏單獨談談虛擬機,是由於它對於咱們開發者來講是個再熟悉不過的概念了。從咱們習慣用來搭建虛擬操做系統環境的 VMware Workstation、Xen 等軟件,到 Java 虛擬機 JVM,PHP 虛擬機 HHVM 等等,都充活躍在咱們程序開發到程序運行的過程當中。

這時候有的讀者可能會眼前一亮,發現原來 JVM、HHVM 等特定語言運行環境中的核心部分,也是虛擬化的一種實實在在的實現。沒錯,只要你們仔細分析和思考一下就會發現,它們正是基於虛擬化的思想來實現的。它們經過隔離程序和操做系統,將程序的指令轉換爲當前所在操做系統平臺所能執行的指令,達到了不用對程序進行任何修改便可執行的目的。也正是這個緣由,這些語言的程序都具備很是強的跨平臺性。

雖然虛擬機技術得益於 Hypervisor 的加持,使得應用程序或者操做系統能夠在無任何修改的狀況下運行在另外一平臺上,但你們很容易發現,其有一個致命的缺陷,就是全部的指令都必須通過虛擬機監視器的處理。這也就意味着,虛擬機的性能是低下的,例如運行在 ZendVM 或者 HHVM 中的 PHP 程序,全部代碼雖然編譯成了 Opcode 碼,但其依然是經過虛擬機才最終轉換爲機器所能識別的機器碼去執行。

這種效率的低下有時候是沒法容忍的,爲了解決這個問題,真實的虛擬機程序經常不徹底遵循 Hypervisor 的設計結構,而是引入一些其餘技術來解決效率問題。

例如,在 VMware Workstation、Xen 中咱們可以看到硬件輔助虛擬化的使用,經過讓指令直達支持虛擬化的硬件,以此避開了效率低下的 Hypervisor。而如 JRE、HPHP 中,除了基於 Hypervisor 實現的解釋執行機制外,還有即時編譯 ( Just In Time ) 運行機制,讓程序代碼在運行前編譯成符合當前硬件平臺的機器碼,這種方式就已經不屬於虛擬化的範疇了。

 

 0x06 容器技術

容器技術是一種全新意義上的虛擬化技術,按分類或者實現方式來講,其應該屬於操做系統虛擬化的範疇,也就是在由操做系統提供虛擬化的支持。

所謂容器技術,指的是操做系統自身支持一些接口,可以讓應用程序間能夠互不干擾的獨立運行,而且可以對其在運行中所使用的資源進行干預。固然,目前來講容器技術尚未一個嚴格的定義,其實現方式也各有不一樣,因此這裏只能算是個人一點小小總結概括。

因爲應用程序的運行被隔離在了一個獨立的運行環境之中,這個獨立的運行環境就好似一個容器,包裹住了應用程序,這就是容器技術名字的由來。

容器技術近年來已是一個火遍大江南北的概念了,其之因此能名聲大噪,很重要的一個緣由是其在運行性能上要遠超虛擬機等其餘虛擬化實現。更甚一步說,運行在容器虛擬化中的應用程序,在運行效率上與真實運行在物理平臺上的應用程序不相上下。

爲何容器技術可以造就近乎完美的運行效率呢?這就得從容器技術如何實現應用程序的指令轉換開始提及。下面這張圖展現了容器技術如何進行指令轉換的。

 

實在無奈,沒有找到容器技術進行指令轉換的圖片,由於容器技術壓根沒有作指令轉換。是的,你沒有聽錯,有時候解決問題的最佳方法就是不解決它

因爲沒有指令轉換,運行在容器中的應用程序自身必須支持在真實操做系統上運行,也就是必須遵循硬件平臺的指令規則。

不少同窗這時候就有疑問了,指令都不轉換,也沒有解決程序跨平臺兼容的問題,這算哪門子虛擬化技術。

沒錯,正是這種緣由,不少人並不認同容器技術屬於虛擬化技術的範疇。不過另外一派觀點認爲,容器技術提供了相對獨立的應用程序運行的環境,也提供了資源控制的功能,因此咱們依然能夠概括其爲一種實現不徹底的虛擬化技術。

 

 0x07 虛擬機 VS 容器

這裏咱們直接經過虛擬機和容器技術的剖析圖來分析,就更容易看出容器虛擬化是如何在效率上完勝虛擬機的

因爲沒有了虛擬操做系統和虛擬機監視器這兩個層次,大幅減小了應用程序運行帶來的額外消耗。

更準確的來講,全部在容器中的應用程序其實徹底運行在了宿主操做系統中,與其餘真實運行在其中的應用程序在指令運行層面是徹底沒有任何區別的。

 

 0x08 參考

以上內容源自本人自購的掘金小冊 https://juejin.im/books 開發者必備的 Docker 實踐指南

 若是您以爲能夠,請微信掃碼購買原做者小冊

 

相關文章
相關標籤/搜索