天天看點

懂了!VMware/KVM/Docker原來是這麼回事兒

原文連結

雲計算時代,計算資源如同小馬哥當年所言,已經成為了網際網路上的水和電。

懂了!VMware/KVM/Docker原來是這麼回事兒

虛拟主機、web伺服器、資料庫、對象存儲等等各種服務我們都可以通過各種各樣的雲平台來完成。

而在雲計算欣欣向榮的背後,有一個重要的功臣,那就是虛拟化技術。可以毫不客氣的說,沒有了虛拟化技術,雲計算無從談起。

說起虛拟化你會想到什麼?從我們常用的虛拟機三件套VMware、VirtualPC、VirutalBox到如今大火的KVM和容器技術Docker?

懂了!VMware/KVM/Docker原來是這麼回事兒

這些技術是什麼關系,背後的技術原理是怎樣的,又有什麼樣的差別,各自應用的場景又是什麼樣的?

看完這篇文章,相信大家都能回答上面問題。

曆史背景

什麼是虛拟化技術?

維基百科中的解釋是這樣的:

虛拟化(技術)是一種資源管理技術,是将計算機的各種實體資源(CPU、記憶體、磁盤空間、網絡擴充卡等),予以抽象、轉換後呈現出來并可供分割、組合為一個或多個電腦組態環境。

對于一台計算機,我們可以簡單的劃分為三層:從下到上依次是實體硬體層,作業系統層、應用程式層

懂了!VMware/KVM/Docker原來是這麼回事兒

1974年,兩位計算機科學家Gerald Popek 和 Robert Goldberg發表了一篇重要的論文《虛拟化第三代體系結構的正式要求》,在這篇論文中提出了虛拟化的三個基本條件:

  • 等價性

    :程式在本地計算機執行和在虛拟機中執行應該表現出一樣的結果(不包括執行時間的差異)
  • 安全性

    :虛拟機彼此隔離,與宿主計算機隔離
  • 性能

    :絕大多數情況下虛拟機中的代碼指令應該直接在實體CPU中執行,少部分特殊指令可由VMM參與。

那如何實作對計算機底層的實體資源的虛拟化分割呢?在計算機技術的發展曆史上,出現了兩種著名的方案,分别是I型虛拟化和II型虛拟化

懂了!VMware/KVM/Docker原來是這麼回事兒

I型虛拟化

懂了!VMware/KVM/Docker原來是這麼回事兒

II型虛拟化

圖中的VMM意為Virtual Machine Monitor,虛拟機監控程式,或者用另一個更專業的名詞:HyperVisor

從圖中可以清楚的看到兩種虛拟化方案的差別:

Type I: 直接淩駕于硬體之上,建構出多個隔離的作業系統環境

Type II: 依賴于宿主作業系統,在其上建構出多個隔離的作業系統環境

我們熟知的VMware事實上有兩個産品線,一個是VMware ESXi,直接安裝在裸金屬之上,不需要額外的作業系統,屬于第一類虛拟化。另一個是我們普通使用者更加熟知的VMware WorkStation,屬于第二類虛拟化。

如何實作上述的虛拟化方案呢?

一個典型的做法是——

陷阱 & 模拟

技術

什麼意思?簡單來說就是正常情況下直接把虛拟機中的代碼指令放到實體的CPU上去執行,一旦執行到一些敏感指令,就觸發異常,控制流程交給VMM,由VMM來進行對應的處理,以此來營造出一個虛拟的計算機環境。

不過這一經典的虛拟化方案在Intel x86架構上卻遇到了問題。

全虛拟化:VMware 二進制翻譯技術

不同于8086時代16位實位址工作模式,x86架構進入32位時代後,引入了保護模式、虛拟記憶體等一系列新的技術。同時為了安全性隔離了應用程式代碼和作業系統代碼,其實作方式依賴于x86處理器的工作狀态。

這就是衆所周知的x86處理器的Ring0-Ring3四個“環”。

懂了!VMware/KVM/Docker原來是這麼回事兒

作業系統核心代碼運作在最高權限的Ring0狀态,應用程式工作于最外圍權限最低的Ring3狀态,剩下的Ring1和Ring2主流的作業系統都基本上沒有使用。

這裡所說的權限,有兩個層面的限制:

  • 能通路的記憶體空間
  • 能執行的特權指令

來關注一下第二點,特權指令。

CPU指令集中有一些特殊的指令,用于進行硬體I/O通信、記憶體管理、中斷管理等等功能,這一些指令隻能在Ring0狀态下執行,被稱為特權指令。這些操作顯然是不能讓應用程式随便執行的。處于Ring3工作狀态的應用程式如果嘗試執行這些指令,CPU将自動檢測到并抛出異常。

回到我們的主題虛拟化技術上面來,如同前面的定義所言,虛拟化是将計算資源進行邏輯或實體層面的切割劃分,建構出一個個獨立的執行環境。

按照我們前面所說的

陷阱 & 模拟

手段,可以讓虛拟機中包含作業系統在内的程式統一運作在低權限的Ring3狀态下,一旦虛拟機中的作業系統進行記憶體管理、I/O通信、中斷等操作時,執行特權指令,進而觸發異常,實體機将異常派遣給VMM,由VMM進行對應的模拟執行。

這本來是一個實作虛拟化很理想的模式,不過x86架構的CPU在這裡遇到了一個跨不過去的坎。

到底是什麼問題呢?

回顧一下前面描繪的理想模式,要這種模式能夠實作的前提是執行敏感指令的時候能夠觸發異常,讓VMM有機會介入,去模拟一個虛拟的環境出來。

但現實是,x86架構的CPU指令集中有那麼一部分指令,它不是特權指令,Ring3狀态下也能夠執行,但這些指令對于虛拟機來說卻是敏感的,不能讓它們直接執行。一旦執行,沒法觸發異常,VMM也就無法介入,虛拟機就露餡兒了!

這結果将導緻虛拟機中的代碼指令出現無法預知的錯誤,更嚴重的是影響到真實實體計算機的運作,虛拟化所謂的安全隔離、等價性也就無從談起。

怎麼解決這個問題,讓x86架構CPU也能支援虛拟化呢?

VMware和QEMU走出了兩條不同的路。

VMware創造性的提出了一個二進制翻譯技術。VMM在虛拟機作業系統和宿主計算機之間扮演一個橋梁的角色,将虛拟機中的要執行的指令“翻譯”成恰當的指令在宿主實體計算機上執行,以此來模拟執行虛拟機中的程式。你可以簡單了解成Java虛拟機執行Java位元組碼的過程,不同的是Java虛拟機執行的是位元組碼,而VMM模拟執行的就是CPU指令。

懂了!VMware/KVM/Docker原來是這麼回事兒

另外值得一提的是,為了提高性能,也并非所有的指令都是模拟執行的,VMware在這裡做了不少的優化,對一些“安全”的指令,就讓它直接執行也未嘗不可。是以VMware的二進制翻譯技術也融合了部分的直接執行。

對于虛拟機中的作業系統,VMM需要完整模拟底層的硬體裝置,包括處理器、記憶體、時鐘、I/O裝置、中斷等等,換句話說,VMM用純軟體的形式“模拟”出一台計算機供虛拟機中的作業系統使用。

這種完全模拟一台計算機的技術也稱為全虛拟化,這樣做的好處顯而易見,虛拟機中的作業系統感覺不到自己是在虛拟機中,代碼無需任何改動,直接可以安裝。而缺點也是可以想象:完全用軟體模拟,轉換翻譯執行,性能堪憂!

而QEMU則是完全軟體層面的“模拟”,乍一看和VMware好像差不多,不過實際本質是完全不同的。VMware是将原始CPU指令序列翻譯成經過處理後的CPU指令序列來執行。而QEMU則是完全模拟執行整個CPU指令集,更像是“解釋執行”,兩者的性能不可同日而語。

懂了!VMware/KVM/Docker原來是這麼回事兒

半虛拟化:Xen 核心定制修改

既然有全虛拟化,那與之相對的也就有半虛拟化,前面說了,由于敏感指令的關系,全虛拟化的VMM需要捕獲到這些指令并完整模拟執行這個過程,實作既滿足虛拟機作業系統的需要,又不至于影響到實體計算機。

但說來簡單,這個模拟過程實際上相當的複雜,涉及到大量底層技術,并且如此模拟費時費力。

而試想一下,如果把作業系統中所有執行敏感指令的地方都改掉,改成一個接口調用(HyperCall),接口的提供方VMM實作對應處理,省去了捕獲和模拟硬體流程等一大段工作,性能将獲得大幅度提升。

這就是半虛拟化,這項技術的代表就是Xen,一個誕生于2003年的開源項目。

懂了!VMware/KVM/Docker原來是這麼回事兒

這項技術一個最大的問題是:需要修改作業系統源碼,做相應的适配工作。這對于像Linux這樣的開源軟體還能接受,充其量多了些工作量罷了。但對于Windows這樣閉源的商業作業系統,修改它的代碼,無異于癡人說夢。

硬體輔助虛拟化 VT / AMD-v

折騰來折騰去,全都是因為x86架構的CPU天然不支援經典虛拟化模式,軟體廠商不得不想出其他各種辦法來在x86上實作虛拟化。

如果進一步講,CPU本身增加對虛拟化的支援,那又會是一番怎樣的情況呢?

在軟體廠商使出渾身解數來實作x86平台的虛拟化後的不久,各家處理器廠商也看到了虛拟化技術的廣闊市場,紛紛推出了硬體層面上的虛拟化支援,正式助推了虛拟化技術的迅猛發展。

這其中為代表的就是Intel的VT系列技術和AMD的AMD-v系列技術。

懂了!VMware/KVM/Docker原來是這麼回事兒

硬體輔助虛拟化細節較為複雜,簡單來說,新一代CPU在原先的Ring0-Ring3四種工作狀态之下,再引入了一個叫工作模式的概念,有

VMX root operation

VMX non-root operation

兩種模式,每種模式都具有完整的Ring0-Ring3四種工作狀态,前者是VMM運作的模式,後者是虛拟機中的OS運作的模式。

VMM運作的層次,有些地方将其稱為Ring -1,VMM可以通過CPU提供的程式設計接口,配置對哪些指令的劫持和捕獲,進而實作對虛拟機作業系統的掌控。

懂了!VMware/KVM/Docker原來是這麼回事兒

換句話說,原先的VMM為了能夠掌控虛拟機中代碼的執行,不得已采用“中間人”來進行翻譯執行,現在新的CPU告訴VMM:不用那麼麻煩了,你提前告訴我你對哪些指令哪些事件感興趣,我在執行這些指令和發生這些事件的時候就通知你,你就可以實作掌控了。完全由硬體層面提供支援,性能自然高了不少。

上面隻是硬體輔助虛拟化技術的一個簡單了解,實際上還包含更多的要素,提供了更多的便利給VMM,包括記憶體的虛拟、I/O的虛拟等等,讓VMM的設計開發工作大大的簡化,VMM不再需要付出昂貴的模拟執行成本,整體虛拟化的性能也有了大幅度的提升。

VMware從5.5版本開始引入對硬體輔助虛拟化的支援,随後在2011年的8.0版本中正式全面支援。于是乎,我們在建立虛拟機的時候,可以選擇要使用哪一種虛拟化引擎技術,是用原先的二進制翻譯執行,還是基于硬體輔助虛拟化的新型技術。

懂了!VMware/KVM/Docker原來是這麼回事兒

同一時期的XEN從3.0版本也加入對硬體輔助虛拟化的支援,從此基于XEN的虛拟機中也能夠運作Windows系統了。

KVM-QEMU

有了硬體輔助虛拟化的加持,虛拟化技術開始呈現井噴之勢。VirtualBox、Hyper-V、KVM等技術如雨後春筍般接連面世。這其中在雲計算領域聲名鵲起的當屬開源的KVM技術了。

KVM全稱for Kernel-based Virtual Machine,意為基于核心的虛拟機。

在虛拟化底層技術上,KVM和VMware後續版本一樣,都是基于硬體輔助虛拟化實作。不同的是VMware作為獨立的第三方軟體可以安裝在Linux、Windows、MacOS等多種不同的作業系統之上,而KVM作為一項虛拟化技術已經內建到Linux核心之中,可以認為Linux核心本身就是一個HyperVisor,這也是KVM名字的含義,是以該技術隻能在Linux伺服器上使用。

懂了!VMware/KVM/Docker原來是這麼回事兒

KVM技術常常搭配QEMU一起使用,稱為KVM-QEMU架構。前面提到,在x86架構CPU的硬體輔助虛拟化技術誕生之前,QEMU就已經采用全套軟體模拟的辦法來實作虛拟化,隻不過這種方案下的執行性能非常低下。

KVM本身基于硬體輔助虛拟化,僅僅實作CPU和記憶體的虛拟化,但一台計算機不僅僅有CPU和記憶體,還需要各種各樣的I/O裝置,不過KVM不負責這些。這個時候,QEMU就和KVM搭上了線,經過改造後的QEMU,負責外部裝置的虛拟,KVM負責底層執行引擎和記憶體的虛拟,兩者彼此互補,成為新一代雲計算虛拟化方案的寵兒。

容器技術-LXC & Docker

前面談到的無論是基于翻譯和模拟的全虛拟化技術、半虛拟化技術,還是有了CPU硬體加持下的全虛拟化技術,其虛拟化的目标都是一台完整的計算機,擁有底層的實體硬體、作業系統和應用程式執行的完整環境。

為了讓虛拟機中的程式實作像在真實實體機器上運作“近似”的效果,背後的HyperVisor做了大量的工作,付出了“沉重”的代價。

雖然HyperVisor做了這麼多,但你有沒有問過虛拟機中的程式,這是它想要的嗎?或許HyperVisor給的太多,而目标程式卻說了一句:你其實可以不用這樣辛苦。

确實存在這樣的情況,虛拟機中的程式說:我隻是想要一個單獨的執行執行環境,不需要你費那麼大勁去虛拟出一個完整的計算機來。

這樣做的好處是什麼?

虛拟出一台計算機的成本高還是隻虛拟出一個隔離的程式運作環境的成本高?答案很明顯是前者。一台實體機可能同時虛拟出10台虛拟機就已經開始感到乏力了,但同時虛拟出100個虛拟的執行環境卻還是能夠從容應對,這對于資源的充分利用可是有巨大的好處。

近幾年大火的容器技術正是在這樣的指導思想下誕生的。

懂了!VMware/KVM/Docker原來是這麼回事兒

不同于虛拟化技術要完整虛拟化一台計算機,容器技術更像是作業系統層面的虛拟化,它隻需要虛拟出一個作業系統環境。

LXC技術就是這種方案的一個典型代表,全稱是LinuX Container,通過Linux核心的Cgroups技術和namespace技術的支撐,隔離作業系統檔案、網絡等資源,在原生作業系統上隔離出一個單獨的空間,将應用程式置于其中運作,這個空間的形态上類似于一個容器将應用程式包含在其中,故取名容器技術。

舉個不是太恰當的比喻,一套原來是三房間的房子,被二房東拿來改造成三個一房間的套間,每個一房間套間裡面都配備了衛生間和廚房,對于住在裡面的人來說就是一套完整的住房。

如今各個大廠火爆的Docker技術底層原理與LXC并不本質差別,甚至在早期Docker就是直接基于LXC的高層次封裝。Docker在LXC的基礎上更進一步,将執行執行環境中的各個元件和依賴打包封裝成獨立的對象,更便于移植和部署。

懂了!VMware/KVM/Docker原來是這麼回事兒

容器技術的好處是輕量,所有隔離空間的程式代碼指令不需要翻譯轉換,就可以直接在CPU上執行,大家底層都是同一個作業系統,通過軟體層面上的邏輯隔離形成一個個單獨的空間。

容器技術的缺點是安全性不如虛拟化技術高,畢竟軟體層面的隔離比起硬體層面的隔離要弱得多。隔離環境系統和外面的主機共用的是同一個作業系統核心,一旦利用核心漏洞發起攻擊,程式突破容器限制,實作逃逸,危及宿主計算機,安全也就不複存在。

超輕虛拟化 firecracker

虛拟完整的計算機隔離性好但太過笨重,簡單的容器技術又因為太過輕量純粹靠軟體隔離不夠安全,有沒有一個折中的方案同時兼具兩者的優點,實作既輕量又安全呢?

近年來,一種超輕虛拟化的思想開始流行開來,亞馬遜推出的firecracker就是一個典型的代表。

懂了!VMware/KVM/Docker原來是這麼回事兒

firecracker将虛拟化技術的強隔離性和容器技術的輕量性進行融合,提出了一個

microVM

的概念,底層通過KVM虛拟化技術實作各個microVM的強隔離,而隔離的虛拟機中運作的是一個個精簡版的微型作業系統,砍掉了大量無用的功能,專為容器設計的微型OS。

超輕虛拟化如今成為一個新的浪潮,除了AWS的firecracker,谷歌的gVisor, Intel主導的NEMU也在向這個領域開始發力。

總結

本文簡單介紹了虛拟化技術的基本概念和基本要求。随後引出由于早期的x86架構不支援經典的虛拟化方案,各家軟體廠商隻能通過軟體模拟的形式來實作虛拟化,其代表是早期的VMware WorkStation和Xen。

不過純粹依靠軟體的方式畢竟有性能的瓶頸,好在Intel和AMD及時推出了CPU硬體層面的虛拟化支援,軟體廠商迅速跟進适配,極大的改善了虛拟化的性能體驗。這一時期的代表有新版本的VMware WorkStation、Hyper-V、KVM等。

懂了!VMware/KVM/Docker原來是這麼回事兒

近年來,随着雲計算和微服務的縱深發展,對虛拟化技術的虛拟粒度逐漸從粗到細。從最早的虛拟化完整的計算機,到後來隻需虛拟出一個作業系統,再到後來虛拟出一個微服務需要的環境即可,以Docker為代表的容器技術在這個時期大放異彩。

技術的發展總是伴随着市場的發展需要而不斷演進,虛拟化的未來是怎樣的,你有什麼樣的看法呢,歡迎評論區留言交流。

來源 | 程式設計技術宇宙

作者 | 軒轅之風