目前,容器存儲是容器離不開的一個話題,對於無狀態的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的卷管理架構使得存儲可用標準的接入方式,而且經過接口暴露存儲設備所支持的能力,從而在容器任務調度等方面實現了自動化管理。ui
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在架構上實現了軟件定義存儲的控制平面和數據平面。儘管許多功能還在不斷完善之中,可是咱們仍是能夠看出下一代面向容器的軟件定義存儲的雛形。