◆郭甲戌 胡曉勤
(四川大學計算機學院 四川 610065)
基于Docker的虛擬化技術研究
◆郭甲戌 胡曉勤
(四川大學計算機學院 四川 610065)
虛擬化作為一種資源抽象管理的技術,在云計算中發揮著重要的作用。新興的容器化解決方案比傳統虛擬機提供了更多的靈活性和更高的效能,已經證明可以成為云計算中虛擬化的輕量級替代。Docker作為輕量級容器管理引擎為新一代云計算平臺提供了支持。本文研究了現有虛擬化技術,并使用通用的基準測試HPL來評估傳統KVM虛擬機和Docker容器的性能差異。結果表明,容器技術在計算能力方面比虛擬化有更多的優勢,而且自身開銷低。但是Docker也有自身的適用場景和隔離安全性方面的不足,大規模地使用Docker時,需要慎重考慮。
虛擬化;容器;Docker
傳統的虛擬化技術[1]比如KVM(Kernel Virtual Machine),通過引入虛擬機監控器,又叫做虛擬化層(Hypervisor)[2],來實現攔截計算元件對物理資源的直接訪問,并將其重新定向到虛擬資源池中。虛擬機監控器運行的環境,也就是真實的物理平臺,稱之為宿主機。而虛擬出來的平臺通常稱為客戶機,里面運行的系統也通常稱為客戶機操作系統。最近諸如 Docker[3]等輕量級虛擬化技術已經得到業界的廣泛關注,作為一種操作系統級的虛擬方法,Docker允許在相同的內核空間中創建不同的命名空間實例,從而緊密地集成到主機操作系統中,減少虛擬機帶來的開銷[4]。
目前來說,主要有兩種模式的虛擬化,分別基于虛擬機監控程序平臺和基于容器技術的輕量級虛擬化平臺[5,6]。圖1比較了基于Hypervisor(a,b)和基于容器(c)虛擬化架構的不同。
圖1.a展示了可以直接在硬件資源上運行Hypervisor的虛擬機,這類產品包括Vmware ESXi,著名的開源虛擬化軟件XEN以及微軟的Hyper-v。從某種意義上說,這種類型的虛擬機監控程序可以視為一個特別為虛擬機而特別優化的操作系統內核。
圖1.b指系統上電后仍然運行一般意義上的操作系統(也就是宿主機操作系統),而虛擬機監控程序作為特殊是應用程序運行在宿主機上,這類虛擬機產品包括開源的 KVM以及 Vmware Workstation和Oracle VirtualBox等。
圖1.c則顯示了容器化虛擬技術的架構,不同于傳統的虛擬機,容器虛擬化不會嵌入自己的內核,而是直接在宿主機的內核上運行,通過刪除虛擬層和客戶機系統來縮短了系統調用的執行消耗,同時,容器還可以共享宿主機的軟件資源(比如一些庫),這使得容器非常的輕量級,提供了接近裸機性能的可能[7]

圖1 不同的虛擬化架構
容器并不是一個完全新興的概念,最早的容器技術可以追溯到1982年Unix系列操作系統上的chroot工具。而最近基于Linux的容器則是依靠內核的支持,根據內核提供的系統調為接口。有兩種基于內核的方式實現的容器:Linux container(LXC)使用cgroups和namespaces,以及OpenVZ分支。
在LXC的基礎上,Docker進一步優化了容器的使用體驗,并且提供了各種容器管理工具,讓用戶無需關注底層的操作,可以簡單明了地管理和使用容器。在Linux上,Docker使用cgroups來實現對進程資源(比如CPU,內存,網絡)的限制,同時使用內核的namespace特性來實現對不同進程的隔離。
Docker容器在主機上創建一個隔離的受控的環境,在其中代碼可以安全地運行(理想情況下)。這種隔離主要通過兩種內核特性kernel namespaces 和control groups。Namespaces用來拆分進程對系統的視圖,目前內核有 6個不同的命名空間--PID,IPC,NET,MNT,UTS,USER--用來隔離系統的各個方面。每一個命名空間中都有與其類型相關的內核對象,并且在/proc和/sys的文件系統來對每個進程進行限制。
Docker Daemon作為一個運行在主機上的守護進程,負責啟動容器,控制它們的隔離等級(cgroups,namespaces,以及SELinux/Apparmor),以及監視它們的觸發動作,比如重新啟動等,并且在運行的容器中生成shell來進行管理。Daemon可以改變主機上的iptables規則來生成相應的網絡接口,還負責鏡像的管理,比如拉取和推送鏡像,根據dockerfiles來創建鏡像,對鏡像簽名等。Daemon本身必須以root運行,獲得所有的權限。主機可以通過Unix 套接字來進行連接,也可以使用TCP套接字進行連接。
Docker hub作為官方的在線鏡像倉庫,允許開發者們上傳鏡像和普通用戶的下載鏡像。開發者可以創建一個免費的賬戶來得到一個公開的個人倉庫,或者使用付費賬戶,使倉庫變為私有。Docker daemon hub、和倉庫類似于一種軟件包的管理工具,一個本地的docker daemon程序從本機和遠程倉庫上都可以下載鏡像,其中一些倉庫是官方的,其余的則是非官方的由第三方機構提供。
Docker的安全問題存在于三個方面:由Docker守護進程管理的用戶空間級別進程的隔離性、內核對隔離的強制性以及網絡安全性。
Docker容器完全依賴于Linux內核,包括namespaces,cgroups和capabilities。namespaces隔離和capabilities默認情況下是啟用的,但是cgroups則需要在啟動每個容器時添加參數-a -c選項來啟用。默認的容器隔離配置的很嚴格的,唯一的缺陷是所有容器共享網橋,會出現網絡的隱患。
但是,Docker的全局安全性可以通過容器啟動時的選項來降低,這會帶來隱患。此外,安全配置可以由Docker daemon啟動時傳入的變量來進行全局設置。例如,可使用-insecure-registry選項,它禁用安全傳輸層(TLS)的證書檢測,會使安全性降低,而-icc=false選項,它禁止容器直接的網絡通信,則會增加安全性,但是它又會阻止多容器應用程序的運行,因此很少使用。
主機加固通過Linux內核安全模塊來強制對容器進行安全相關的限制約束。Docker目前允許使用配置文件來支持SELinux、Apparmor和Seccomp等安全模塊。例如,默認的Apparmor配置文件允許對文件系統、網絡和容器的所有權限。類似地,默認的SELinux策略將所有的Docker容器放在同一個域中,因此,雖然這種主機的加固保護主機免受容器的影響,卻不能保護容器受到其他容器的影響。
Docker使用網絡來進行鏡像的分發和對 docker守護進程的控制。為了分發鏡像,docker使用哈希驗證從遠程倉庫下載的鏡像,通過TLS建立與源的連接。而docker守護進程則通過套接字接口來控制,這使得docker可以被遠程的主機操作。默認的用來監聽的端口號是 unix socket,就是/var/run/docker.sock所有者為root:docker,也可以使用tcp端口。訪問socket使得攻擊者可以拉取和運行任何容器,還能獲得對主機的最高權限。對于 Unix socket來說,在docker用戶組的用戶都可以獲得root權限,對于TCP socket來說,任何連接者都可以獲得主機的最高權限,因此,連接必須使用 TLS進行加固,它對連接的雙發進行加密和認證(還需要額外的證書管理)
大部分人都將 Docker直接與虛擬機做比較,因為兩個技術在設計上是等效的。但其實輕量級容器虛擬化的設計目標是完全不同于虛擬機的。有三種適合Docker的應用。
開發者使用微服務模式來使用 Docker--一個容器必須托管單個服務,在其中運行著單個的進程或者守護進程的子程序。因此,一個容器不應該視為一個虛擬機:沒有包的管理,沒有 init進程,沒有ssh連接。所有的管理操作(容器的停止,重啟,備份,更新,創建等)都應該通過主機來進行操作,這就需要root權限。
使用Docker來可重用和自動部署應用程序。Docker鏡像通過一個通用的構建文件(dockerfiles)隨時隨地的構建,它指定了從基本鏡像構建鏡像的步驟。這種構建鏡像的通用方法使得進程和鏡像構建過程幾乎不受主機影響,只取決于內核,而不是依賴庫。
使用Docker搭建PPAS平臺。現在主流的PaaSs平臺都已經集成了 Docker,比如 Amazon Web Services和 Google Container Engine,創建虛擬機的集群,然后通過編排工具來管理各個虛擬機中的容器。Docker作為一個容器引擎向PaaS提供了基礎的資源隔離和標準化打包部署能力,使基于其上的PaaS平臺構建簡單高效。
虛擬化往往會給系統性能帶來損失,為了顯示 Docker在虛擬化方面的計算性能損失的優勢,我們選擇計算密集型和數據密集型的測試程序進行試驗,本次實驗中,使用 Intel Optimized LINPACK Benchmark[8]來比較容器和虛擬機的性能。
實驗環境:我們在一臺 PC機上進行測試,物理機采用 64位Ubuntu 14.04系統,處理器為Intel Corei5-3210處理,6GB內存。Docker版本為1.12,QEMU/KVM版本為1.0。在Docker容器和KVM虛擬機中都使用Centos7.2系統。為了能夠對比兩者虛擬化對性能帶來的損失,對應于測試的計算規模,我們對測試的容器和虛擬機給定了充足的資源。首先,針對問題的大小,我們的測試系統都可以發揮出最佳的性能從而比較出兩者虛擬化性能的差異。然后,我們限制資源,在資源增加下的條件下對兩者進行基準測試,來比較不同資源下兩者的性能表現。
實驗結果如下圖,圖2顯示了Docker 容器到性能已經很接近宿主機的性能,而KVM虛擬機的性能只達到容器一半左右。圖3顯示了在分配不同CPU核心的情況下,Docker容器和KVM虛擬機的性能比較,從中可以看出容器的性能一直領先于虛擬機。而且在配置比較低的時候領先優勢更為明顯。

圖2 裸機、容器與虛擬機性能對比

圖3 不同cpu核數下的性能對比
本文研究了 Docker容器化虛擬技術和傳統 KVM虛擬化技術,還對于 Docker的使用給出了針對性的建議,并且針對兩者在計算性能上的差別,使用LINPACK基準測試實驗來顯示Docker的性能優勢。但是應用軟件虛擬化的性能評價目前來說缺乏一個統一的標準,我們僅在 CPU計算能力上對兩者進行了測試和比較。還有應用程序的啟動時間、隔離度、安全性以及可靠性等方面都需要進行量化指標進行測試。因此下一步的工作應該在更多的維度對容器進行測試。并且制定標準,給出對不同應用場合下Docker使用的指導。
總體來說,Docker還在處于飛速發展的階段,從簡單的對應用的虛擬化到對各個容器集群的編排,以至于發展到現在以Kubernetes為代表的云平臺,有理由相信,在應用本身越來越成為市場核心的今天,Docker 的應用也將越發廣泛,尤其是在業界的大力支持下,很有可能成為市場的標準化技術。
[1]Wikipedia.Virtualization[EB/OL].https://en.wikipedia.org/wiki/Virtualization.
[2]任永杰.KVM 虛擬化技術[M].北京:機械工業出版社,2013.
[3]Docker[EB/OL].https://www.docker.io/.
[4]汪愷,張功萱,周秀敏.基于容器虛擬化技術研究[J].計算機技術與發展,2015.
[5]劉思堯,李強,李斌.基于 Docker 技術的容器隔離性研究[J].軟件,2015.
[6]伍陽,基于 Docker 的虛擬化技術研究[EB/OL].信息技術,2016.
[7]Minh Thanh Chung,Nguyen Quang-Hung.Using Docker in High Performance Computing Applications[C].IEEE Sixth International Conference on Communications & Electronics.
[8]J. J. Dongarra, P. Luszczek, and A. Petitet. The linpack benchmark:past, present and future,Concurrency and Computation[J].practice and experience,2003.