容器存儲架構(gòu)比較:Kubernetes、Docker和Mesos Compare
任何應(yīng)用程序都需要數(shù)據(jù)支撐,這也是我們商業(yè)存在基石。最初,容器應(yīng)運(yùn)而生的主要目的之一也是為了解決無狀態(tài)服務(wù)。但短期時(shí)間內(nèi),隨著技術(shù)的不斷成熟,允許容器化應(yīng)用程序直接訪問數(shù)據(jù)的需求也在不斷的增加?,F(xiàn)代化的應(yīng)用程序和傳統(tǒng)的應(yīng)用程序都需要諸如文件、塊,或者工具化文件存儲對象、關(guān)系型數(shù)據(jù)庫、流媒體文件等這些不同類型的存儲。
虛擬機(jī)也可以管理應(yīng)用程序,但是這種方法對硬件仿真有一定的要求,容器可以保證應(yīng)用程序的可移植性遠(yuǎn)大于虛擬化的實(shí)現(xiàn)。實(shí)際應(yīng)用程序的可移植性的能力,還依賴于個(gè)容器編排工具的互操作性。對于當(dāng)前的原生云應(yīng)用程序,存儲也是一個(gè)很關(guān)鍵的組件,因?yàn)閼?yīng)用程序可以利用持久存儲平臺以及圍繞其特性進(jìn)一步開發(fā)特性功能。
容器的協(xié)調(diào)者和運(yùn)行時(shí)對存儲服務(wù)發(fā)起特定的請求,可以實(shí)現(xiàn)諸如創(chuàng)建/刪除、檢查/清單、附加/分離、安裝/卸載等操作。這是解決容器協(xié)調(diào)者之間存儲問題的一種獨(dú)特的嘗試,不過在行業(yè)中也是有分歧的。對外存儲編排請求API分為兩種情況:首先,是in-tree驅(qū)動程序,它是直接將原生代碼編譯到容器協(xié)調(diào)器;第二,是out-of-tree,借助于外部插件驅(qū)動。每一種方式都有自己的優(yōu)缺點(diǎn):in-tree驅(qū)動器受制于容器協(xié)調(diào)器的發(fā)布周期;而out-of-tree插件式驅(qū)動可能無法提供與容器協(xié)調(diào)器綁定的增強(qiáng)特性集。
Docker
Docker是在1.7的實(shí)驗(yàn)版本中通過創(chuàng)建Docker Volume 驅(qū)動接口首次解決了外部存儲的問題。1.13版本中Docker又引入了插件模型,也就是Docker Store(http://t.cn/RCvBExq)。通過查找目錄/run/docker/plugins,Docker發(fā)現(xiàn)并可使用UNIX插件(.sock文件),這是一個(gè)使用out-of-tree模型的例子。
UNIX域套接字( Unix domain socket)文件必須在相同的Docker主機(jī)上運(yùn)行。但如果指定了遠(yuǎn)程訪問URL,插件也可以通過spec和json配置文件實(shí)現(xiàn)在不同的主機(jī)上運(yùn)行。實(shí)現(xiàn)存儲功能的集中化,這也是插件職責(zé)之一。該接口接受JSON、RPC類型的HTTP請求。out-of-tree模型公開的接口提供了完整的Volume生命周期,也為Docker CLI提供了編排功能。但是,如快照或復(fù)制等高級存儲功能,還未提供暴露給Docker CLI。
Mesos
Mesos直到v0.23版本才開始支持本地存儲。Mesos-Module-Dvdi(https://github.com/codedellemc/mesos-module-dvdi)就是為這個(gè)問題而提出的方案,隨后它的特性被合并到Mesos,直到Mesos 1.0+版本方能使用。DVDCLI(https://github.com/codedellemc/dvdcli)是將Docker Volume Driver CLI打包封裝到Mesos中,允許在所有的Mesos容器內(nèi)使用任何Docker Volume驅(qū)動,Mesos-Module-Dvdi就是利用正在實(shí)施中的DVDCLI實(shí)現(xiàn)了本地存儲。與Docker類似,框架與DVDCLI互聯(lián)通信支持JSON格式,并且也提供使用JSON/RPC通過HTTP與Docker Volume Driver Interface通信。
正如前面所提及的,由于它使用了Docker Volume 驅(qū)動,因此它是一個(gè)out-of-tree插件,并且具有和Docker CLI相同的Volume生命周期和限制。
Kubernetes
Kubernetes的獨(dú)特之處在于它既有in-tree又有out-of-tree驅(qū)動。我們已經(jīng)在《Kubernetes存儲說明》(http://t.cn/RCvBDnV)和《Kubernetes 1.6版本中關(guān)于存儲的新功能》(http://t.cn/RCvrPrr)這兩篇文章中詳細(xì)說明,我們再次回顧下:
in-tree驅(qū)動來自于Kubernetes源碼,也是其標(biāo)準(zhǔn)發(fā)行版的一部分。通過這些驅(qū)動,可以根據(jù)Kubernetes提供的接口(如Mount/Umount、Create/Delete等)向其存儲平臺暴露API,Kubernetes執(zhí)行所有功能,并向驅(qū)動程序執(zhí)行特定的API調(diào)用,從而執(zhí)行所需的操作。這也可以充分利用Kubernetes的特性,比如:動態(tài)供應(yīng)的存儲類。這樣也是有缺點(diǎn)的,如果系統(tǒng)BUG或增加需要新增一些平臺特性,則依賴于Kubernetes的發(fā)布周期。發(fā)布周期可能意味著3-6個(gè)月的等待修復(fù)、持續(xù)維護(hù)、回合代碼等流程。
Out-of-tree驅(qū)動使用Flexvolume接口。Flexvolume允許用戶編寫自己的驅(qū)動程序,并在Kubernetes中添加對其Volume的支持。供應(yīng)商的驅(qū)動應(yīng)該被安裝在在每個(gè)Kubelet節(jié)點(diǎn)和主節(jié)點(diǎn)上,Volume插件的路徑:usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/。這使得驅(qū)動程序可以在核心的Kubernetes代碼之外運(yùn)行,并且可以根據(jù)自己的時(shí)間節(jié)點(diǎn)表發(fā)布更新或者修復(fù)BUG。Flexvolume接口預(yù)期Volume的創(chuàng)建和刪除可以基于外部插件進(jìn)行。因此,F(xiàn)lexvolume只使用Attach/Detach 和 Mount/Unmount功能,而不是整個(gè)Volume的生命周期。
當(dāng)前總概
把所有的存儲功能結(jié)合在一起,我們可以看到這是一個(gè)非常碎片化的空間,以及三者之間各有千秋。
而所有這一切都意味著存儲供應(yīng)商需要創(chuàng)建多層次封裝集成,從而支持整個(gè)容器生態(tài)系統(tǒng)。容器存儲接口(CSI)項(xiàng)目處于早期階段,但最終將會成為存儲和容器成功的關(guān)鍵因素。
與此同時(shí),我們已經(jīng)將所有的功能整合,并且集成了針對每一種容器協(xié)調(diào)者功能的存儲方法。我們深知當(dāng)前和未來的容器化應(yīng)用程序依賴存儲,而且這個(gè)解決方案適應(yīng)每一個(gè)場景:Docker和Mesos中的REX-Ray,F(xiàn)lexREX和Kubernetes,Docker中的REX-RAY插件,Kubernetes的本地ScaleIO驅(qū)動程序。