本文全面審視了三種利用容器作為虛擬機系統替代方案的方式。
容器已經在網絡領域掀起了一股潮流,其所帶來的輕量化、更為靈活的效果足以作為傳統虛擬機系統的替代方案。容器與虛擬機之間的最大差別在于,單一容器可以共享多個常用文件,而虛擬機則存在著離散性與原子性——即使存儲與網絡資源處于虛擬化及共享狀態。具體來講,虛擬機更像是互不關聯的孤島,而容器之間則更像是群島關系。
我們預計,終有一天大部分操作系統實例會由虛擬機轉向容器環境。事實上,操作系統供應商們已經開始爭先恐后地壓縮自家產品的體積,從而使其新版本更容易適應容器環境下的具體要求。
那么,容器是否已經準備好在我們的網絡體系當中占據核心地位?容器的優勢與短板又分別是什么?帶著這些問題,我們測試了三款容器方案——Docker、Rocket/rkt以及openVZ/Odin(原名為Parallels)。
Docker在容器技術領域屬于當之無愧的龍頭,但其中也存在著不少需要克服的潛在問題。Rocket/rkt解決了其中一部分問題,但卻尚未準備好全面進入大家的生產環境。
OpenVZ/Odin能夠同時提供容器方案外加一套兼容多種主流虛擬機管理平臺的“虛擬環境”,但仍然存在著一些局限。
這三套方案都具備相當出色的實用性,但與傳統虛擬機管理程序及虛擬機系統相比,其實際水平仍然有所欠缺。不過在精心部署與認真打理之下,三者也確實擁有著可圈可點的潛在發展空間。
在對三款產品進行測試時,我們選擇了企業級系統基礎設施作為背景,而非DevOps及持續開發環境。不過容器背后蘊藏的巨大能量意味著其很難脫離系統基礎設施存在,而其控制層也尚不適合或者說無法充分適應持續開發實踐當中的快速部署、規模調整以及設計思路。
此次測試的每一款產品都處于快速轉型的過程當中,其中年紀稍長的OpenVZ/Virtuozzo扮演的角色則略有區別——其更像是一款面向服務供應商的控制層產品。
容器所要解決的實際問題
容器技術的演變主要受到編排流程需求的推動,客戶需要較虛擬機部署更具輕量化優勢的方案,但同時又能夠繼續享受到集群化、快速安裝及移除等機制所帶來的便利。此外,這一切還需要配合可靠性與安全性保障,這是每一套新型平臺需要面對的關鍵性考核標準,同時也是云計算概念發展所帶來的重要副產品之一。
在openVZ/Virtuozzo方案當中,容器執行流程與快速推出能力更多面向負責將基礎設施與設備進行匹配并交付給客戶的服務供應商。具體實例包括網站/電子郵件打包托管、網站營銷、語言高度本地化的設備型產品以及相關服務。在這種情況下,根據操作系統的多種預設置實例提供操控與計費方案將成為拉攏客戶的關鍵所在。
作為Parallels品牌(openVZ贊助方兼Virtuozzo出品方)調整后的產物,Odin長久以來一直肩負著上述任務。它具備更出色的可預測性、更理想的內置功能搭配,而且靈活性水平也足夠作為Docker的托管方案使用。
Docker提供的是一套輕量化操作系統環境,并通過應用操控指令的方式嚴格保證控制措施的推行。其具體操控內容既可立足于基礎性層面,也可以涉及復雜度更高、針對性更強的控制工作。
Rocket/rkt與Docker非常相似,但卻某些方面卻顯得更加原始(而且尚未準備好正式進入生產環境)。不過目前Rocket似乎已經針對這些問題作出了改進,并開始給Docker造成日益嚴重的競爭威脅。在實際測試中,我們發現rkt能夠很好地滿足我們的一部分工程技術需要,而Docker在這些方面卻顯得有些停滯不前。
Odin及其開發成果openVZ將自身標榜成為一套虛擬環境,在這一混合模型當中、經過修改的內核被用于同時承擔起傳統虛擬機管理程序與容器托管環境這兩大任務。舉例來說,大家完全可以將Docker或者Rocket運行在openVZ之上。
我們發現,這三款產品使用的實現方式幾乎完全相同。事實上,這三個項目之間確實存在著交叉支持的現象,當然此外還有很多其他貢獻者參與了進來——就連主要貢獻者的名單都相當驚人。三者似乎都通過多種方式為彼此作出贊助,而它們也代表著同樣的一股新興勢力——即以輕量化為主要特色的實例管理解決方案,旨在摒棄傳統虛擬機管理程序的“沉重”劣勢。
因此,容器托管方案到底能否徹底取代曾經稱霸一時的虛擬機管理程序呢?就我們目前得出的答案來看,暫時還不行——它們的著眼點與既定目標完全不同。不過同時需要指出的是,以CoreOS、Ubuntu Server小型實例甚至紅帽即將推出的Atomic發行版等為代表的輕量化操作系統都已經在設計當中考慮到了作為框架引入容器托管方案的可能性。而相信我們也將在Windows 10當中見到容器技術的普及——雖然Mac OS目前還沒有在容器方面作出任何嘗試。
下面讓我們對這三大主流方案作出一一解析。
OpenVZ/Odin Virtuozzo 6.0
OpenVZ是一款Linux發行版,主要負責對虛擬機以及/或者容器訪客實例進行托管。OpenVZ資源以現代3.X+版本Linux內核為基礎,同時利用OpenVZ內核實現下載。雖然我們可以將大量不同類型的OpenVZ組件服務安裝在Linux 3.X+當中,但只有OpenVZ內核的功能能夠得到全面支持。
OpenVZ訪客實例可以表現為虛擬機或者容器系統。當大家向其中添加操控機制、計費以及管理面板時,則需要用到另一款商用產品——Odin Virtuozzo。順帶一提,Odin是Parallels這家瑞士企業進行品牌調整之后的產物。
我們早在2008年就曾經對Virtuozzo的Windows版本進行過評測。當時Virtuozzo只適用于32位服務器環境,由此帶來的內存容量局限嚴重影響了它的實用性。雖然這款Windows產品目前仍然存在,但Virtuozzo如今已經能夠使用共享內核,從而在Linux平臺之上順暢打理容器系統。
我們下載到openVZ并將其安裝到了一臺聯想ThinkServer RD640設備之上。由于這套方案所使用的Linux內核已經相當古老,所以我們需要盡可能考量其兼容性水平,確保其能夠與硬件設備順利協作。根據說明,我們擁有大量服務器功能可供選擇——雖然尚未在測試中得到證實——而且任何能夠與Red Hat 6相兼容的服務器硬件,都將能支持openVZ或者Odin。
雖然我們已經證實了openVZ與Odin能夠順利使用RAID,但大家仍然只能從HBA以及JBOD磁盤組合當中直接進行選擇。此外,我們通過測試發現其支持“硬”IPv6虛擬機/容器地址,但總體而言IPv6支持能力仍然有所局限。
Virtuozzo是一套虛擬環境,而且在我們的測試當中,托管虛擬機為典型的Windows Server。Linux及FreeBSD最好是以容器的方式處理。Virtuozzo通過一款Web應用實現控制,而且在正常UI之外還提供必要的命令行組件。如果大家愿意,幾乎可以完全通過命令行界面完成全部控制操作。
容器可以由Docker、Rocket或者LinuXContainers/LXC生成。此外,大家也可以使用下載自Odin的OpenVZ/VIrtuozzo容器庫。
OpenVZ的使用方式與Docker以及rkt非常相似。虛擬環境的安裝非常簡便,其硬件性能表現也與VMware 5.5下的同等配置保持一致。我們并沒有使用泛用式基準測試檢查其性能表現,此次選擇的只有作為火狐35性能指標的SciMark瀏覽器測試——這是考慮到其擁有類似的工作負載以及使用背景。
從這個角度來看,OpenVZ在很大程度上類似于虛擬機管理程序,只不過在整體處理強度方面低于VMware——或者說其更接近Windows Hyper-V。值得一提的是,OpenVZ并不具備VMware ESXi 5.X提供的專用功能集——或者成本水平。
測試OpenVZ與Virtuozzo
我們首先嘗試了OpenVZ/OVZ。安裝完成后提供兩套庫,其一面向各類紅帽式發行版,另一套則面向Debian各發行版。下面所使用的分支版本已經過預sysctrl,因此可作為后sysctrl參考。各個分支版本在功能性方面基本一致,因為安裝基礎中的二進制文件非常相近。
相關說明文件適用于熟悉Linux的使用者,不過在新手看來內容似乎還不夠完備。
OpenVZ傾向于配合裸機,但也能夠以虛擬機方式運行。在使用裸機時,其性能水平能夠得到顯著提升。我們強烈建議大家不要使用OpenVZ或者VIrtuozzo作為虛擬機方案,這將導致性能水平急劇下滑——特別是在資源分配過度時,主機整體都會出現卡頓。
OpenVZ容器,或者稱其為“虛擬環境”,的基礎定位為一項cgroup-demoted服務。如果我們利用OpenVZ內核來替代標準Linux內核,則可以使用一套名為ploop的文件系統,并借此降低需要使用的Linux節點數量。
在選定文件系統類型之后,我們隨后需要安裝主容器控制器vzctl,接下來是負責控制容器資源量/配額的vzquota。其中vzctl應用能夠被用于部署來自openvz.org網站的各類容器鏡像。這些容器在初始體積非常小巧,我們能夠以壓縮包的形式將其解壓到緩存目錄當中并加以部署。
在這里我們要提醒大家,Linux 3.x新版本內核中所使用的內核并非全部能夠支持內存與CPU控制(除了OpenVZ的內核)。我們在運行過程中并沒有發現問題,但可以想象肯定會出現某種內核無法由OpenVZ全部實現編譯的情況,這會導致主機內的虛擬機或者容器系統單純依賴于OpenVZ內核。從表面上看,在必要的情況下任意內核都能夠通過重新編譯啟用全部功能,但我們并沒有在測試中加以檢驗。
各容器鏡像在發送中還配合一條GPG密鑰,用于對該鏡像進行驗證。這一點非常重要。根據具體需求,大家可以構建自己的鏡像,當然目前也已經有大量OpenVZ源Linux鏡像供我們選擇。已經下載完成的鏡像可以通過鏡像緩存直接進行部署,不過在我們的測試環境下,其速度并不像Docker配合CentOS那么出色。部署過程的時間差異幾乎可以忽略不計,多次部署之間的時差大約為數秒,這可能是因為ploop需要花點時間創建自己的文件系統。
Odin Virtuozzo 6 SP1
Odin的Virtuozzo屬于OpenVZ的商業檢測版本,其在我們的測試當中擁有非常接近于Red Hat 6的實際表現。Virtuozzo的安裝過程耗時相當長,但最終還是識別出了我們使用的iSCSI存儲機制——雖然我們發現,iSCSI會拖慢Virtuozzo的速度表現。NFS也受到支持,而且在測試當中其速度僅比iSCSI稍微快上一點。
Virtuozzo提供一套網絡頁面,用于對IP配置(IPv4)進行操控,其中包括虛擬網卡及VLAN。其具體方式類似于Xen/XenServer與VMware對網絡機制的處理思路,同時支持多租戶配置方案。
我們可以通過兩種方式創建Odin虛擬環境,其一為采用本地虛擬機管理程序——這意味著任何擁有良好處理器/平臺支持效果的操作系統——另一種則專門針對Linux容器負載所設計。
這些有效載荷可以由ploop文件系統負責承載,但pfcached/ParallelsFileCacheDaemon也可以在自己的ploop文件系統緩存當中對文件執行常見的重復數據刪除操作。其中pfcached利用一套算法選擇如何及何時執行重復數據刪除操作,但我們估計這不太可能帶來顯著的初始性能提升——因為該算法需要經過相當長的適應時間才能帶來明確成效。
OpenVZ/Virtuozzo容器由于由vzctl或者prctl負責控制的實例。大家可以通過各種常見方式與之進行對接,包括ssh、RDP或者控制臺。反過來,容器會自主執行相關任務,包括處理工作、處理并存儲數據,或者生成一套網絡頁面等。
容器或者虛擬機可以通過虛擬以太網進行隔離,而且不支持內部容器或者虛擬機通信連接; 要實現這些功能,大家需要自己想辦法完成,包括使用Puppet、Chef或者其它方案。虛擬USB、磁盤驅動器以及DVD一應俱全,不過只支持原始視頻。我們可能需要構建起多臺硬件服務器并加以對接,才能實現高可用性目標,不過此次測試并沒有就此進行嘗試。
我們安裝了四套測試Windows及Linux ISO庫(使用是我們自己的ISO源)來充當訪客虛擬機,全部獲得成功。我們并沒有嘗試高級圖形處理、虛擬USB端口以及音頻端口。我們還測試了幾套來自同一套Linux發行版的Odin鏡像,并發現不同發行版之間的安裝過程并無差別(我們使用的實例為Ubuntu 14.04與Odin提供的Ubuntu 14.04)。
在OpenVZ當中,用戶可以隨時下載鏡像,并將其部署在主機之上。使用預格式化模板、由用戶制作或者OpenVZ/Parallels/Odin提供的鏡像都能夠充分享受內存優化帶來的效果,不過周期性出現的負載峰值可能導致虛擬機或者容器出現運行緩慢狀況——當然,此類情況在其它預設有性能上限的虛擬機管理程序當中也很常見。
CPU MHz(即時鐘頻率)、性能峰值以及CPU數量皆可隨意分配。OpenVZ不提供CPU親和力選項,這可能是因為我們很難在Linux內核那孱弱的CPU任務親和水平之上實現此類效果。
在使用ploop的情況下,我們能夠輕松實現文件系統快照保存,而這也是VIrtuozzo實現虛擬機或者容器實時遷移的前提所在。事實上,虛擬機或者容器文件系統被打包成為一個巨大的對象,而非一系列由各類sysctl操作控制的分散文件、文件夾以及索引節點。不過我們并沒有測試其實時遷移效果。
使用感受
我們可以在Virtuozzo當中塞進數量驚人的容器及虛擬機系統。訪問操作起效正常,而且該操作系統能夠識別出主機上的全部24個CPU計算核心,并允許我們將其分配給虛擬機或者容器。由于我們的存儲資源只有數TB、內存則為128 GB,因此我們不清楚運行當中到底是哪種資源先達到瓶頸——處理器還是存儲機制。我們可以對磁盤及內存進行過度分配,并在測試當中發現部分虛擬機因此出現了異常。
我們在測試當中收到了一條來自虛擬機或者容器的異常狀態通知消息。雖然有些失落,但這類問題其實并不罕見。我們無法在虛擬機已經停機的情況下通過設置最低CPU閾值來觸發警報,因為其只適用于追蹤CPU的使用量峰值。IPMI消息收發或者負責向檢測機制發送主機狀態的類似API集能夠起到很好的提示作用,而且我們應該能夠在必要時將nagios或者其它監控工具嵌入到虛擬機/窗口負載當中。然而,我們發現磁盤作為資源類型之一也面臨著同樣的問題——我們會在磁盤被寫滿之后收到消息,但其連續24個小時未進入活動狀態卻不會提供任何通知(這可能意味著主機已經發生故障)。盡管Virtuozzo在定位上不同于VMware XenServer或者Hyper-V,但我們仍然有必要提供這類功能以滿足多租戶內部云或者將其作為云平臺的小型/中型服務供應商的實際需求。
OpenVZ的容器也可以采取Docker形式并在Docker環境下運行,這就使其能夠與Docker生態系統順利對接。由于Parallels擁有自己的多種容器形式,我們發現Docker容器格式的存在有些多余,但我們仍然在CentOS系統之下測試了主機平臺與Docker的協作效果。在原始SciMark基準測試當中,執行時間大概要比原生容器運行時間長18%,但與運行同類虛擬機比較時耗只長15%。所以,大家可以選擇使用Docker,但我們并不推薦這么做,因為這相當于硬性弄出了一套影響性能的套娃結構。
Docker 1.6
Docker能夠運行在數量繁多的Linux發行版、Mac OS版本以及實驗性微軟平臺之上。我們在測試中嘗試中四個Linux主機版本外加一臺Mac OS主機。這種強大的兼容能力其實有好處也有壞處。畢竟Docker之所以具備這么高的人氣,主要是由于其便捷性以及通過同一套控制機制對各類相似及差異化容器加以編排的能力。
大部分現有Linux內核以及MacOS都能夠運行Docker容器。我們可以將Docker安裝在主機平臺之上,而后再在Docker控制“之內”啟動一套操作系統實例。Docker在托管操作系統實例時擁有諸多便捷特性,換句話說,我們可以輕松將Docker編排之下的虛擬機資源進行拆分。
Docker的價值之一在于,我們可以從Docker庫中規模龐大的實例類型中作出選擇。大家可以從Docker.com網站處獲取庫及容器選項,其中不少都擁有搶眼的知名應用開發商“官方”標記。其中一部分由Docker網站托管,也有一部分可以通過GitHub獲得。總體而言,陳列在我們面前的是數量繁多的開發平臺以及經過打包的應用方案(包括WordPress衍生版本以及Hadoop集群組件等等)。
Ubuntu 14.04服務器可以算是一類典型的Docker實例了,其使用的主機資源相對比較有限。容器當中運行的可以是Linux/Apache/MySQL/PHP/Perl(LAMP)等實例,而且此類可選實例數量繁多且類型多樣。我們現在能夠從Canonical或者紅帽公司那里得到大量經過體積縮減的鏡像,其中一部分鏡像甚至通過刻意精簡來防止未使用進程從容器中搶奪CPU計算周期。
只需要使用docker run命令,我們就能輕松讓一切運轉起來。這條命令會將容器/虛擬機實例化,并使用目錄用于數據存儲——與會對安全水平造成影響的Linux chroot命令不同,這更接近于OpenVZ/Virtuozzo。
Docker容器鏡像使用union文件系統,或者簡稱unionfs,其會為容器制作出文件夾基礎體系。與OpenVZ/VIrtuozzo類似,Docker會通過unionfs為每套利用Docker運行的容器提供分層結構。這就使得類似的鏡像之間能夠通過一次更新就共享到同樣的基礎文件,而且會在需要保存鏡像快照或者更新鏡像時節約存儲空間。舉例來說,我們可以一次性更新openssh并將效果推廣到20套容器當中,因為它們依賴于同一套已完成更新的鏡像。
使用unionfs能夠顯著提高Docker的執行效率,但這同時也可能由于源鏡像損壞而令大量容器陷入癱瘓——業界對此一直提出尖銳的批評。我們也可以利用RESTful put/get在user-initiator命令當中對Docker的容器鏡像加以控制。不過這條命令與root user一樣,非常強大但也非常危險。通過這種方式,我們能夠實現對訪問、密碼、SSH密鑰安全庫以及其它強烈推薦使用的標準安全機制的控制。這種控制方式有限松散但卻速度很快,而且充滿樂趣。
ISO鏡像也能夠以自動化方式構建,這樣企業用戶就能夠更為高效地維護自己的鏡像結構并在符合安全要求的前提下實現鏡像控制。
我們可以通過ssh通信或者其它API訪問Docker內部,包括使用Puppet等通信結構。存儲經過降級,而且可以通過user security加以進一步控制(例如chroot、chmod或者其它規定的文件限制/元數據控制機制)。在某些情況下,大家也可以使用ploop或者其它文件系統來享受到我們之前在OpenVZ/Virtuozzo章節中提到的便利效果。
利用Docker生成容器環境
Docker并不像OpenVZ/VIrtuozzo那樣專注于幫助常規容器節約存儲空間,例如對常規存儲文件進行重復數據刪除。在理論上講,OpenVZ/Virtuozzo能夠以更為緊湊的方式對容器進行打包。也就是說,在同樣的硬件平臺之上,我們可以利用OpenVZ/Virtuozzo承載大量Docker容器實例,而且實現方式也很簡單。
而且Docker也不像Virtuozzo那樣提供控制層檢測機制。Docker要求我們使用控制腳本及密鑰完成管理工作,相比之下Virtuozzo的方式顯然更為便捷。目前市面上存在大量能夠完成此類任務的第三方應用產品,但我們并沒有在測試中加以嘗試。
管理大量容器主機并不是什么難事,不過這對于管理員的評估技能提出了一些要求。Docker Swarm是一款API,允許大家將一組Docker容器視為單一對象加以操作,這意味著整套容器集群都能夠實現單點控制。這不僅將實例的快速向外擴展變為可能,同時也為實例預留了更為可觀的運行空間。
測試流程里最讓我們樂在其中的部分,就是嘗試利用自己的命令保證容器步調一致。這部分功能還不夠完善,而且我們需要提醒大家,即使能夠輕松玩轉Docker Swarm、您也有可能在調度工作中使一部分容器進入休眠狀態。
將大量容器匯總成單一托管對象會給管理員帶來巨大的職責壓力。值得一提的是,我們可以利用Apach Mesos之類的應用對集群化容器這樣的大規模數據集進行嚴格控制。從企業安全的角度出發,大家必須非常謹慎地處理這方面工作,否則資源暴露的直接后果就是發生資源劫持。
Rocket/rkt 0.5.4
Rocket的出現與發展幾乎一直伴隨著CoreOS的前進腳步。CoreOS是一款經過嚴格修整的操作系統,專注于減少攻擊面并為Docker提供高效的運行基礎。CoreOS在GitHub的項目描述中將自己形容為一套App容器運行時(系統),這是一套體積小巧但穩定性極高的應用平臺。
Rocket lacks some key components and requires more construction savvy than either Docker or Virtuozzo. We were pleased to see that it focuses on security with source image provenance and payload control.
立足于Linux內核,CoreOS的發展速度稍微落后于Docker,這是因為它更多作為一款集群操作系統存在、而非控制層。CoreOS是rkt項目的贊助商之一,但該項目目前還沒有作好進入生產環境的準備。從原則角度講,我們一般不會在審查當中對這類產品提出太高的要求,因為技術業界普遍認為beta測試版本并不適用于實際生產。
由于這三款容器解決方案都采用幾乎同樣的成熟Linux組件,我們會更多地關注rkt的設計思路而非其實踐表現。平心而論,rkt同樣非常復雜,但考慮到其在各個層級采用的嚴格安全措施,我們認為它的潛在安全風險更低一些。
Rocket在容器實例構建管理機制當中納入了嚴格的監控手段,這意味著鏡像在由rkt加以啟動之前,必須以特定方式進行構建。這一點與OpenVZ以及Docker的管理方式有所不同,因為二者所使用的容器控制器都能夠直接使用現成的ISO鏡像——包括來自當前正在運行的系統、容器控制器庫/注冊庫或者隔壁好友的鏡像。但這些在Rocket當中都無法實現。
在測試當中,我們發現rkt在容器運行時控制方面的基礎效果與Docker及OpenVZ非常接近:使用守護程序控制容器數量,并在整個生命周期之內對容器實例加以管理。由于執行標準更為嚴格,因為rkt的安全性水平要比Docker更高。
從歷史角度看,業界對于Docker安全性/可靠性的質疑催生了Rocket/rkt的出現乃至發展。事實上,rkt所遵循的原則體現了其不同于其它容器技術方案的核心價值觀。由此產生的App Container(簡稱appc)正是一項專門的規范,用于解決Docker安全性薄弱的問題。而系統內在可靠性也必須被納入優先級考量,無論實際接受管理的容器數量是多是少——盡管rkt允許重載,這一前提也絲毫沒有動搖。
考慮到以上原則,appc規范專注于確保所下載的鏡像擁有可靠的簽名出處以及正確的組裝方法完整性。下面我們引述幾條來自GitHub的appc規范要求:
這項規范的核心目標包括:
設計出下載及啟動速度更快的App Container
確保鏡像擁有加密驗證以及理想的可緩存能力
通過設計確保實現手段的可組合性與獨立性
使用常見技術進行加密、歸檔、壓縮以及傳輸
利用DNS命名空間對鏡像進行命名與發現
Rocket將自身作為上述規范的典型實現機制,而其它多家廠商也對這一定位表示認同,具體包括紅帽、谷歌、VMware以及Apcera等。而且盡管CoreOS+rkt這一組合與appc規范要求基本屬于同一含義,但rkt在實現方案角度的地位同VMware(Lightwave/Photon)以及Apcera(Continuum)等同——雖然截至測試之時,后兩者尚未正式推出。
Rkt遵循appc方法生成tar(即Tape Archive)格式的鏡像文件而非ISO,因此其GPG密鑰會同ISO本身一同進行散列處理,從而保證容器底層鏡像經過嚴格驗證。通過這種方式,源文件的完整性與安全性更具保障(幾乎不可能出現文件替換、補丁等級錯誤、惡意軟件、軟件包損壞以及其它可能影響ISO使用的情況)。而且每套鏡像都擁有一個獨一無二的ImageID。
我們可以創建一個文件夾,并將其作為rkt的rootfs或者頂層文件系統。我們并未對鏡像進行壓縮,如果大家需要采取這種處理方式,請記得預先在未壓縮的鏡像當中插入JSON格式的鏡像manifest。大家也可以根據需求選擇其它的壓縮步驟,包括在鏡像在解壓/解密時擁有密鑰作為保護(我們推薦使用AES-256)。我們還在等待能夠直接完成上述操作而無需使用命令行界面的控制層機制——不過直接使用命令行也不是很復雜。
一旦完成了加密過程并將JSON manifest插入到鏡像當中,我們即可將其投入執行。鏡像在啟動后會作為pod存在,其本質上也就是容器,但“pod”這個語用來形容鏡像似乎更為形象。
所謂pod當中包含有一整套擁有自己ID的可執行文件,并會作為單一對象使用UUID(遵循IETF RFC 4122)對所執行pod的功能進行操作。該UUID擁有自己的命名空間,由rkt創建并進行持續管理; 通過這種方式,也就實現了實例控制。隨后rkt會通過初始化操作為該UUID創建一個rootfs,其中包含與JSON manifest相關文件夾的一份白名單。每一次容器對象開始啟動,它都會創建一個一次性的新文件系統,從而確保不存在痕跡殘留。
我們發現,manifest在其中起到了關鍵性作用。如果manifest存在問題,那么整套方案都無法正常起效。不過在創建完成之后,它會重新審查該源的真實性。在最新版本當中,其適用范圍更是將Docker鏡像涵蓋于其中。總體而言,我們覺得這樣嚴格的制度還是物有所值的,而檢測監控機制的效果將成為決定其未來發展的核心所在。
測試Rkt
我們使用OpenVZ/Virtuozzo章節中提到過的同一套聯想平臺建立起一臺CentOS 6測試主機,為了方便起見這次我們使用了最低主機環境而非CoreOS。我們制作了兩套鏡像,其一是來自TrunKeyLinux的WordPress鏡像——我們特意選擇了WordPress 4.2.2版本,另一套則是通用型Ubuntu 14.04服務器鏡像——其經過一次更新,專門用于建立最小化服務。接下來,我們找到了幾套適用于這兩套平臺的庫鏡像。
我們可以通過基于命令行的rkt命令對資源(例如pod所需要的內存分配機制)、帶寬等進行分配。由于rkt不具備檢測機制,因此目前我們必須使用腳本——為此我們還專門復習了一下JSON語法。
此次接受測試的版本允許我們通過簡單的http用戶名/密碼下載來自Docker(或者類Docker)注冊庫中的鏡像。這也意味著整套庫都可以供我們使用,并通過安全覆寫方式修改優先級鏈,從而擺脫審計/合規的相關要求——當然,除非日志嚴格監控我們的行為并執行錯誤修正。
我們編寫出的這些腳本隨后被快速復制到我們的聯想主機服務器之上。我們開始運行這些用于生成實例的腳本,利用嵌入其中的偽指令啟動系統,并在創建實例的同時為這臺聯想設備設定了用于應對暫時性卡頓的解決方案——接下來要做的就是專注觀察其反應了。
但我們忘記設定CPU資源分配策略了,因此在啟動全部實例的同時,巨大的啟動資源需求量直擊主機計算核心。沒有任何一臺服務器能夠在這樣的沖擊之下幸存。但幸運的是,我們通過重啟修正了腳本當中的錯誤。
在實踐過程中,我們從Docker那邊獲得了兩套鏡像,并經過一系列調整使其能夠在rkt運行時中執行。我們還以腳本方式設定了多套容器的啟動流程,并得以執行了一次向外擴展執行實驗——但這同樣耗費了我們大量精力。而且值得強調的是,第三方工具確實能夠為rkt提供幫助。
批評意見
這三款應用都以root方式運行,因為它們需要直接從內核獲取處理速度。三套方案的說明文檔中只是稍微提到了AppArmor與SELinux,但三者都能夠利用這些沙箱機制將容器隔離起來,從而避免其破壞或者大量占用系統資源。
用于承載容器系統的集群/主機硬件平臺無法避免某套受到感染的容器利用其安全權限接入其它存在于同一平臺上的容器,同樣的情況也會發生在立足于同一安裝基礎的不同容器之間。因此,容器的安全保障只作用于其內部工作流程當中。
從集群/主機的層面出發,由守護程序負責控制容器進程,而其它負責控制這些守護程序的進程必須得到嚴格保護——這種作法在大部分企業當中已經成為安全工作的核心要點。接下來則要提到密鑰控制,在這方面Virtuozzo的表現非常不錯,但仍然不夠全面。我們需要的是一套能夠妥善管理SSH密鑰,同時對各容器運行進程所需要的通信層加以控制的整體架構。Virtuozzo無疑帶來了良好的開端。當然,對這三套方案來講,還需要配合其它內部軟件定義網絡機制才能真正步入成熟。
不過在目前的主流虛擬機管理程序當中,還沒有密度與效率兼備的先例出現,特別是同時對存儲文件及執行文件進行重復數據刪除處理。從這個角度看,容器屬于裸機實例與虛擬化技術相結合的混合產物。基于虛擬機管理程序的虛擬機系統彼此相互隔離,通常屬于離散實例,但容器則無需受到此類限制。虛擬機管理程序能夠從底層角度出發,保護實例免受資源劫持的困擾。而虛擬機對于沙箱技術的應用在理論上遠高于容器——當然,安全失誤同樣有可能輕易摧毀這兩類實例苦心構建而成的防御體系。
總結
容器技術確實非常便捷,而且允許操作系統實例與可執行文件以簡單的方式進行交換,并實現資源共享(在操作系統層級)。容器在根源上講,包括補丁/修復級別,并非完全不透明,但除非采用嚴格的方法來進行審計及日志記錄,否則其很容易為惡意人士所利用。
不過我們必須承認,容器技術讓實例的快速向外擴展/向上擴展成為可能,而這也將成為其沖擊市場的主要賣點。在我們看來,OpenVZ是目前容器領域最為成熟的解決方案,而且其采用的完全虛擬化或者容器化混合模式也足以在目標市場上——即互聯網服務供應商及托管服務供應商——受到追捧。
Docker則是一套值得認真考量的方案,其發展背后擁有極為強大的推動力量。從GitHub參與者數量的角度看,Docker開發工作中擁有著大量活躍技術支持者群體。但我們同時注意到,大量參與者的涌入讓Docker注冊庫中的源鏡像出現了一些問題,這甚至體現在了我們所選擇的測試樣本當中。這種狀況讓我們非常緊張,因為容器本身非常難于探測,其組合與獨立組件很難直接查看、權威來源也很難得到審計——即使對大型企業來說也是如此。
這反過來讓我們更加專注于appc規范的發展以及rkt項目的前進走勢。毫無疑問,rkt的嚴格監管與appc合規機制的出現值得我們為之鼓掌,不過rkt本身并沒有作好從實驗階段走向實踐部署的萬全準備。
容器技術是什么?其與虛擬機有何區別?
容器化應用能夠擺脫虛擬機管理程序的束縛。容器當中的實例執行方式與傳統虛擬機管理程序的執行方式有所差別,其中每一套容器都能夠共享通用文件,而非各自擁有獨立的離散操作系統/應用組合。
從概念上講,容器中的實例構成元素包括操作系統、應用程序代碼、通信連接以及臨時及永久性數據存儲。
與半虛擬化虛擬機實例類似,容器利用接口通過容器管理器的管理設置將通信及存儲需求(必要時)同外部環境相連。
容器環境被介入式安全墻同主機的計算核心及root進程隔離開來,且通常與其它容器共同運作在同一臺主機之上。
容器可以包含獨立的指定主機操作系統,同時也能夠以可互換機制構建,這就讓采用Ubuntu、Red Hat Atomic、CoreOS以及SUSE乃至其它操作系統建立容器混合體變成可能。除非有意連接,否則容器主機對于容器內的運行狀況一無所知。
反過來,這就使得設備與進程分別存在于彼此隔離的世界,并能夠以對象的方式在主機之間往來遷移。此類主機通常采用Linux操作系統,但Docker也能運行在蘋果、BSD等環境當中。微軟公司最近演示了利用微軟.Net將Docker鏡像由Windows服務器平臺遷移至Linux主機的過程——前提是各主機所使用的CPU為同一類別(是的,我們還不能將在ARM上開發出的容器運行在英特爾/AMD平臺當中)。主機平臺的這種互換能力正是系統設計師們所追求的目標,他們希望把容器像樂高積木那樣隨意調遣。
我們的主要批評意見是:目前容器系統能夠接受未知來源或者不具備權威創建者信息的容器鏡像。作為大量共享源應用的平臺方案,一款應用遭受滲透或者突破有可能讓容器之上的所有實例出現問題。
這是因為除非由注冊庫發布的某套容器鏡像能夠從零開始依次組裝,或者擁有權威可信的來源,否則我們必須首先將其視為可疑對象。而對基于容器的通用文件進行更新管理也需要配合更為嚴格的控制手段。
而在另一方面,我們的一次操作即可恢復、升級或者重新配置一組容器的功能甚至特性——這種能力同樣有利有弊。
原文標題:Docker vs. Rocket vs. Odin: Containers compared