細述Kubernetes和Docker容器的儲存方式
目前,容器儲存是容器離不開的一個話題,對於無狀態的Docker容器,容器重啟時容器資料會自動清除,一些靜態的資料我們可以通過配置檔案或者在容器build時直接寫死。但是對於資料庫、日誌檔案等可以實時變化的資料,我們不能夠通過這種方法存取,容器的儲存大多支援Docker或Kubernetes的Volume(資料卷),因此我們下文先介紹這兩種Volume的原理。 |
Docker的容器卷外掛
Docker V1.8正式釋出了容器卷外掛 (Volume Plugin) 的規範,允許第三方廠商的資料卷在Docker引擎中提供資料服務,使得外接儲存可以超過容器的生命週期而獨立存在。這意味著各種儲存裝置只要滿足介面API的標準,就可以接入Docker容器的執行平臺中。Volume Plugin的介面規範定義了5中操作,如下表所示:
這個規範定義非常簡潔,現有的各種儲存可以通過簡單的驅動程式封裝,從而實現和Docker容器的對接。可以說,驅動程式實現了和容器引擎的北向介面,底層則呼叫後端儲存的功能完成資料存取等任務。還有不少儲存方案實現了額外的高階功能,如容器資料卷遷移等,這部分功能不在Docker的卷外掛規範當中,可通過儲存自身的管理工具來使用。目前已經實現的Docker Volume Plugin中,後端儲存包括常見的NFS, CIFS, GlusterFS和塊裝置等。
Kubernetes的容器卷
Kubernetes是開源的容器叢集管理平臺,可以自動化部署、擴充套件和運維容器應用。Kubernetes的排程單位稱作“Pod”(豆莢),每個Pod代表一個應用,包含一個或多個容器。Pod可部署在叢集的任意節點中,儲存裝置可以通過資料卷(Volume)提供給Pod的容器使用。Kubernetes底層支援Docker的容器執行引擎,為了不繫結在特定的容器技術上,Kubernetes沒有使用Docker的Volume機制,而是重新制定了自己的通用資料卷外掛規範,以配合不同的容器執行時來使用(如Docker和rkt)。
資料卷一般可以貫穿Pod的整個生命週期,當Pod被平臺刪除的時候,在不同的資料卷實現中,資料可能會被保留或移除。如果資料被保留的話,其他Pod可以重新把該卷的資料載入使用。資料卷分為共享和非共享兩種型別,其中非共享型只能被某個節點掛載使用(如iSCSI,AWS EBS等網路塊裝置),共享型則可以讓不同節點上的多個Pod同時使用(如NFS,GlusterFS,CephFS等網路檔案系統,以及可支援多方讀寫的塊裝置)。對有狀態的應用來說,共享型的卷儲存能夠很方便地支援容器在叢集各節點之間的遷移。
Kubernetes的資料卷可把外部預建立的資料卷接入Pod裡面,在這個過程中,Pod無法對資料卷配置引數(如卷大小,IOPS等),因為這些引數是由提供資料卷的儲存預先設定的,這有點象傳統儲存先劃分資料卷,再供給應用掛載使用。為了給容器提供更細粒度的卷管理,Kubernetes增加了持久化卷PV(Persistent Volume)的功能,把外接儲存作為資源池,由平臺管理並提供給整個叢集使用。每個PV具有一些可被平臺感知的儲存能力,如卷容量(storage size),讀寫訪問模式(access mode)等。當Pod需要儲存時,可以向平臺請求所需要儲存資源,該請求稱作PVC (Persistent Volume Claim)。PVC內容包括訪問模式、容量大小等資訊。平臺根據請求的資源屬性(如卷大小等)匹配合適的資源並分配給Pod,並把資料卷掛載到Pod所在的主機中供Pod使用(如下圖所示)。
Kubernetes的Persistent Volume功能還在不斷髮展中,目前PV僅支援儲存容量(storage size)的能力(capacity),今後還可能支援IOPS,吞吐量等儲存能力,以便配置更豐富的儲存策略。Kubernetes的卷管理架構使得儲存可用標準的接入方式,並且通過介面暴露儲存裝置所支援的能力,從而在容器任務排程等方面實現了自動化管理。
Flocker
為了給容器應用提供檔案卷儲存,比較簡單的方式是在重用傳統儲存的基礎上,加上適配容器規範的相應介面。使用這種方式的容器儲存很多,如適配Docker的GlusterFS, NFS, CIFS的卷外掛。下文介紹的Flocker也是這種模式的開源容器卷管理器,它提供了在叢集中管理和編排容器資料卷的方案,並依靠後端的共享塊儲存提供資料卷跨主機的能力。
如上圖所示,Flocker由控制服務作為總控制器,對外提供REST API介面,負責維持和更新系統的狀態。Flocker Agent安裝在叢集的每個節點上,負責確保每個節點上的本地狀態符合系統期待的狀態,如果發現本地狀態和期待狀態不符,Flocker Agent將採取必要的糾正措施,使得節點上的資料卷與集群系統的配置實現最終一致性(eventual consistency)。Flocker Plugin也部署在每個節點上,主要以外掛形式與Docker、Kubernetes等容器平臺的整合,不僅讓容器可以使用Flocker提供的資料卷,還能夠支援容器的遷移。
例如,在Kubernetes中,當Pod所在的主機失效之後,Kubernetes會把Pod重新排程(遷移)到另一臺主機上,相應地,Flocker把Pod在原主機上的資料卷釋放出來,並且在新主機中重新掛載給該Pod。這樣,有狀態容器在遷移主機的時候,其資料卷也能夠跟隨著容器一起移動。
Flocker後端可採用各種常見的網路塊裝置,包括AWS EBS,OpenStack Cinder,EMC、DELL、NetApp、VMware VSAN/vVOL等,這些塊裝置配上驅動程式,即可由Flocker生成資料卷(檔案目錄形式),掛接到任意的主機上,再通過卷外掛的介面,把資料卷提供給容器應用。
Portworx
Portworx開發了容器感知的軟體定義儲存系統,稱為CDS (Container-Defined Storage)。在Portworx的CDS儲存中,採用的是計算和儲存融合的架構,把叢集中所有節點的本地儲存聚合成大的資源池,使得每個節點既提供計算能力,也提供本地磁碟作為儲存,這樣執行在節點中的容器可從本地直接訪問資料。
任何儲存都要保證資料的完整性和可靠性,由於Portworx採用分散式儲存架構,與Ceph、VMware Virtual SAN等類似,需要在多節點之間進行資料複製。如上圖所示,當資料在本地寫入的時候,根據儲存設定的引數,可以把資料複製到其他若干個節點中,從而在叢集中存有多個數據副本,確保了資料的可用性和可靠性。如果某個節點出現故障或進行下線維護,該節點上的容器可以被上層的排程器重新排程到其他節點上。因為資料已經複製到了多個節點,容器在新節點上可直接使用本地資料,提高了資料訪問的效率(如下圖所示)。
Portworx還設計了面向容器卷的儲存策略,在建立資料卷的時候可以動態設定,這些策略如下所示:
通過設定上述儲存屬性的配置,容器卷的QoS等需求可以動態滿足,與傳統的SAN等塊儲存有很重要的區別:這些策略是以容器卷的粒度進行配置的,能夠很好地符合容器應用的需求,所以稱為容器定義的儲存(Container Defined Storage),是為容器應用量身定製的軟體定義儲存。目前,Portworx在架構上實現了軟體定義儲存的控制平面和資料平面。儘管許多功能還在不斷完善之中,但是我們還是可以看出下一代面向容器的軟體定