天天看點

Docker與虛拟機的差別

概要

Docker

是近年來新興的虛拟化工具,它可以和虛拟機一樣實作資源和系統環境的隔離。本文将主要根據IBM發表的研究報告,論述

docker

與傳統虛拟化方式的不同之處,并比較實體機、docker容器、虛拟機三者的性能差異及差異産生的原理。

docker與虛拟機實作原理比較

如下圖分别是虛拟機與docker的實作架構。

Docker與虛拟機的差別
Docker與虛拟機的差別

比較兩圖的差異,左圖虛拟機的Guest OS層和Hypervisor層在docker中被Docker Engine層所替代。虛拟機的Guest OS即為虛拟機安裝的

作業系統

,它是一個完整作業系統核心;虛拟機的Hypervisor層可以簡單了解為一個硬體虛拟化平台,它在Host OS是以核心态的驅動存在的。

虛拟機實作資源隔離的方法是利用獨立的OS,并利用Hypervisor虛拟化CPU、記憶體、IO裝置等實作的。例如,為了虛拟CPU,Hypervisor會為每個虛拟的CPU建立一個

資料結構

,模拟CPU的全部寄存器的值,在适當的時候跟蹤并修改這些值。需要指出的是在大多數情況下,虛拟機軟體代碼是直接跑在硬體上的,而不需要Hypervisor介入。隻有在一些權限高的請求下,Guest OS需要運作核心态修改CPU的寄存器資料,Hypervisor會介入,修改并維護虛拟的CPU狀态。

Hypervisor虛拟化記憶體的方法是建立一個shadow page table。正常的情況下,一個page table可以用來實作從虛拟記憶體到實體記憶體的翻譯。在虛拟化的情況下,由于所謂的實體記憶體仍然是虛拟的,是以shadow page table就要做到:虛拟記憶體->虛拟的實體記憶體->真正的實體記憶體。

對于IO裝置虛拟化,當Hypervisor接到page fault,并發現實際上虛拟的實體記憶體位址對應的是一個I/O裝置,Hypervisor就用軟體模拟這個裝置的工作情況,并傳回。比如當CPU想要寫磁盤時,Hypervisor就把相應的資料寫到一個host OS的檔案上,這個檔案實際上就模拟了虛拟的磁盤。

對比虛拟機實作資源和環境隔離的方案,docker就顯得簡練很多。docker Engine可以簡單看成對

Linux

的NameSpace、Cgroup、鏡像管理檔案系統操作的封裝。docker并沒有和虛拟機一樣利用一個完全獨立的Guest OS實作環境隔離,它利用的是目前

linux

核心本身支援的容器方式實作資源和環境隔離。簡單的說,docker利用namespace實作系統環境的隔離;利用Cgroup實作資源限制;利用鏡像實作根目錄環境的隔離。

通過docker和虛拟機實作原理的比較,我們大緻可以得出一些結論:

(1)docker有着比虛拟機更少的抽象層。由于docker不需要Hypervisor實作硬體資源虛拟化,運作在docker容器上的程式直接使用的都是實際實體機的硬體資源。是以在CPU、記憶體使用率上docker将會在效率上有優勢,具體的效率對比在下幾個小節裡給出。在IO裝置虛拟化上,docker的鏡像管理有多種方案,比如利用Aufs檔案系統或者Device Mapper實作docker的檔案管理,各種實作方案的效率略有不同。

(2)docker利用的是主控端的核心,而不需要Guest OS。是以,當建立一個容器時,docker不需要和虛拟機一樣重新加載一個作業系統核心。我們知道,引導、加載作業系統核心是一個比較費時費資源的過程,當建立一個虛拟機時,虛拟機軟體需要加載Guest OS,這個建立過程是分鐘級别的。而docker由于直接利用主控端的作業系統,則省略了這個過程,是以建立一個docker容器隻需要幾秒鐘。另外,現代作業系統是複雜的系統,在一台實體機上新增加一個作業系統的資源開銷是比較大的,是以,docker對比虛拟機在資源消耗上也占有比較大的優勢。事實上,在一台實體機上我們可以很容易建立成百上千的容器,而隻能建立幾個虛拟機。

docker與虛拟機計算效率比較

在上一節我們從原理的角度推測docker應當在CPU和記憶體的利用效率上比虛拟機高。在這一節我們将根據IBM發表的論文給出的資料進行分析。以下的資料均是在IBM x3650 M4伺服器測得,其主要的硬體參數是:

(1)2顆英特爾xeon E5-2655 處理器,主頻2.4-3.0 GHz。每顆處理器有8個核,是以總共有16個核。

(2)256 GB RAM.

測試

中是通過運算Linpack程式來獲得計算能力資料的。結果如下圖所示:

Docker與虛拟機的差別

圖中從左往右分别是實體機、docker和虛拟機的計算能力資料。可見docker相對于實體機其計算能力幾乎沒有損耗,而虛拟機對比實體機則有着非常明顯的損耗。虛拟機的計算能力損耗在50%左右。

為什麼會有這麼大的性能損耗呢?一方面是因為虛拟機增加了一層虛拟硬體層,運作在虛拟機上的應用程式在進行數值計算時是運作在Hypervisor虛拟的CPU上的;另外一方面是由于計算程式本身的特性導緻的差異。虛拟機虛拟的cpu

架構

不同于實際cpu架構,數值計算程式一般針對特定的cpu架構有一定的優化措施,虛拟化使這些措施廢棄,甚至起到反效果。比如對于本次實驗的平台,實際的CPU架構是2塊實體CPU,每塊CPU擁有16個核,共32個核,采用的是NUMA架構;而虛拟機則将CPU虛拟化成一塊擁有32個核的CPU。這就導緻了計算程式在進行計算時無法根據實際的CPU架構進行優化,大大減低了計算效率。

docker與虛拟機記憶體通路效率比較

記憶體通路效率的比較相對比較複雜一點,主要是記憶體通路有多種場景:

(1)大批量的,連續位址塊的記憶體資料讀寫。這種測試環境下得到的性能資料是記憶體帶寬,性能瓶頸主要在記憶體晶片的性能上;

(2)随機記憶體通路性能。這種測試環境下的性能資料主要與記憶體帶寬、cache的命中率和虛拟位址與實體位址轉換的效率等因素有關。

以下将主要針對這兩種記憶體通路場景進行分析。在分析之前我們先概要說明一下docker和虛拟機的記憶體通路模型差異。下圖是docker與虛拟機記憶體通路模型:

Docker與虛拟機的差別

可見在應用程式記憶體通路上,虛拟機的應用程式要進行2次的虛拟記憶體到實體記憶體的映射,讀寫記憶體的代價比docker的應用程式高。

下圖是場景(1)的測試資料,即記憶體帶寬資料。左圖是程式運作在一塊CPU(即8核)上的資料,右圖是程式運作在2塊CPU(即16核)上的資料。機關均為GB/s。

Docker與虛拟機的差別
Docker與虛拟機的差別

從圖中資料可以看出,在記憶體帶寬性能上docker與虛拟機的性能差異并不大。這是因為在記憶體帶寬測試中,讀寫的記憶體位址是連續的,大批量的,核心對這種操作會進行優化(資料預存取)。是以虛拟記憶體到實體記憶體的映射次數比較少,性能瓶頸主要在實體記憶體的讀寫速度上,是以這種情況docker和虛拟機的測試性能差别不大;

記憶體帶寬測試中docker與虛拟機記憶體通路性能差異不大的原因是由于記憶體帶寬測試中需要進行虛拟位址到實體位址的映射次數比較少。根據這個假設,我們推測,當進行随機記憶體通路測試時這兩者的性能差距将會變大,因為随機記憶體通路測試中需要進行虛拟記憶體位址到實體記憶體位址的映射次數将會變多。結果如下圖所示。

Docker與虛拟機的差別
Docker與虛拟機的差別

左圖是程式運作在一個CPU上的資料,右圖是程式運作在2塊CPU上的資料。從左圖可以看出,确實如我們所預測的,在随機記憶體通路性能上容器與虛拟機的性能差距變得比較明顯,容器的記憶體通路性能明顯比虛拟機優秀;但出乎我們意料的是在2塊CPU上運作測試程式時容器與虛拟機的随機記憶體通路性能的差距卻又變的不明顯。

針對這個現象,IBM的論文給出了一個合了解釋。這是因為當有2塊CPU同時對記憶體進行通路時,記憶體讀寫的控制将會變得比較複雜,因為兩塊CPU可能同時讀寫同一個位址的資料,需要對記憶體資料進行一些同步操作,進而導緻記憶體讀寫性能的損耗。這種損耗即使對于實體機也是存在的,可以看出右圖的記憶體通路性能資料是低于左圖的。2塊CPU對記憶體讀寫性能的損耗影響是非常大的,這個損耗占據的比例遠大于虛拟機和docker由于記憶體通路模型的不同産生的差異,是以在右圖中docker與虛拟機的随機記憶體通路性能上我們看不出明顯差異。

docker與虛拟機啟動時間及資源耗費比較

上面兩個小節主要從運作在docker裡的程式和運作在虛拟機裡的程式進行性能比較。事實上,docker之是以如此受到開發者關注的另外一個重要原因是啟動docker的系統代價比啟動一台虛拟機的代價要低得多:無論從啟動時間還是從啟動資源耗費角度來說。docker直接利用主控端的系統核心,避免了虛拟機啟動時所需的系統引導時間和作業系統運作的資源消耗。利用docker能在幾秒鐘之内啟動大量的容器,這是虛拟機無法辦到的。快速啟動、低系統資源消耗的優點使docker在彈性雲平台和自動運維系統方面有着很好的應用前景。

docker的劣勢

前面的内容主要論述docker相對于虛拟機的優勢,但docker也不是完美的系統。相對于虛拟機,docker還存在着以下幾個缺點:

1.資源隔離方面不如虛拟機,docker是利用cgroup實作資源限制的,隻能限制資源消耗的最大值,而不能隔絕其他程式占用自己的資源。

2.安全性問題。docker目前并不能分辨具體執行指令的使用者,隻要一個使用者擁有執行docker的權限,那麼他就可以對docker的容器進行所有操作,不管該容器是否是由該使用者建立。比如A和B都擁有執行docker的權限,由于docker的server端并不會具體判斷docker cline是由哪個使用者發起的,A可以删除B建立的容器,存在一定的安全風險。

3.docker目前還在版本的快速更新中,細節功能調整比較大。一些核心子產品依賴于高版本核心,存在版本相容問題

參考文獻

Felter W, Ferreira A, Rajamony R, et al. An Updated Performance Comparison of Virtual Machines and Linux Containers[J]. technology, 2014, 28: 32.

http://www.zhihu.com/question/20848931

原文位址

  http://blog.csdn.net/cbl709/article/details/43955687