Kubernetes 持久化存儲是個難題,解決方案有哪些?

像Kubernetes 這樣的容器編排工具正在徹底改變應用程序的開發和部署方式。隨着微服務架構的興起,以及基礎架構與應用程序邏輯從開發人員的角度解耦,開發人員越來越關注構建軟件和交付價值。

Kubernetes 對管理的物理機器進行抽象。使用Kubernetes,你可以通過描述獲取所需的內存總量和計算能力,而無需擔心底層基礎架構。

在管理Docker 鏡像時,Kubernetes 還讓應用程序變得可移植。一旦使用Kubernetes 開發容器化架構,它們就可以部署在任何地方 - 公有云、混合雲、本地 - 無需對底層代碼進行任何更改。

雖然Kubernetes 在許多方面非常有用,例如可伸縮性、可移植性和管理能力,但它不支持存儲狀態。幾乎所有的生產應用程序都是有狀態的,即需要某種外部存儲。

Kubernetes 的架構是不斷變化的。容器的創建和銷燬,取決於負載和開發人員的規範。容器組和容器可以自我修復和複製。從本質上講,它們的生命週期是短暫的。

但是,持久化存儲解決方案無法承受這種動態行爲。持久化存儲不能綁定到動態創建和銷燬的規則上。

當有狀態應用需要部署在另一個基礎架構,可能是另一個雲提供商、本地或混合模型上時,它們在可移植性方面面臨挑戰。持久化存儲解決方案會綁定到特定的雲提供商。

此外,雲原生應用程序的存儲版圖不容易理解。Kubernetes 存儲術語可能會造成混淆,因爲許多術語都有複雜的含義和微妙的變化。此外,在做出決策之前,開發人員必須考慮許多選項,包括原生Kubernetes、開源框架、託管或付費服務。

在下面的CNCF 版圖中可以看到列出的雲原生存儲解決方案:

首先想到的可能就是在Kubernetes 中部署數據庫:選擇適合你需求的數據庫解決方案,將其容器化並在本地磁盤上運行,然後將其作爲另一個工作負載部署在集羣中。但是,由於數據庫的固有屬性,這種方法不是特別好。

容器是基於無狀態原則構建的。這使得容器很容易進行伸縮。由於不需要保存和遷移數據,通常來說,集羣不需要處理很密集的磁盤讀寫操作。

使用數據庫,需要保存狀態。如果數據庫以容器方式部署在集羣上,不進行遷移或者頻繁伸縮,那麼實際的數據存儲將起作用。理想情況下,將使用數據的容器與數據庫位於同一個容器中。

這並不是說在容器中部署數據庫是一個壞主意 - 在某些用例中,這種方法可能就足夠了。在測試環境中,或者對於不需要生產級數據量的任務,由於所保存的數據規模較小,因此集羣中的數據庫可能是有意義的。

在生產中,開發人員通常依賴外部存儲。

Kubernetes 如何與存儲通信?它使用控制平面接口。這些接口將Kubernetes 與外部存儲相關聯。這些與Kubernetes 連接的外部存儲解決方案稱爲卷插件。卷插件可以抽象存儲並賦予存儲可移植性。

以前,卷插件使用Kubernetes 核心代碼庫構建、鏈接、編譯和發佈。這極大地限制了開發人員的靈活性,並帶來了額外的維護成本。添加新的存儲選項需要更改Kubernetes 代碼庫。

通過引入CSI 和Flexvolume,可以在集羣上部署卷插件,而無需更改代碼庫。

Kubernetes 原生和存儲

Kubernetes 原生如何處理存儲?Kubernetes 自身提供了一些管理存儲的解決方案:臨時選項、持久化存儲卷、持久化存儲卷聲明、存儲類和有狀態副本集。這可能很混亂。

持久化存儲卷(PV)是由管理員配置的存儲單元。它們獨立於任何一個容器組,使它們擺脫容器組的短暫生命週期。

另一方面,持久化存儲卷聲明(PVC)是對存儲的請求,即PVs。使用PVC,可以將存儲綁定到特定節點,使其可供該節點使用。

有兩種處理存儲的方法:靜態和動態。

採用靜態配置,管理員在實際請求之前,爲他們認爲可能需要的容器組提供PVs,並且通過明確指定的PVCs,將這些PV 手動綁定到指定的容器組。

實際上,靜態定義的PV 與Kubernetes 的可移植結構不兼容,因爲正在使用的存儲可能依賴於環境,例如AWS EBS 或GCE Persistent Disk。手動綁定需要更改YAML 文件以指向特定供應商的存儲解決方案。

在開發人員如何考慮資源方面,靜態配置也違背了Kubernetes 的思維方式:CPU 和內存未事先分配並綁定到容器組或容器。它們是動態授予的。

動態配置使用存儲類完成。集羣管理員無需事先手動創建PV。他們改爲創建多個存儲配置文件,就像模板一樣。當開發人員創建PVC 時,根據請求的要求,在請求時創建其中一個模板,並將其附加到容器組。

圖片

這是對外部存儲通常如何使用原生Kubernetes 進行處理的一個寬泛的概述。但是,還有許多其他選擇需要考慮。

CSI - 容器存儲接口

在繼續之前,我想介紹容器存儲接口(CSI)。CSI 是由CNCF 存儲工作組創建的統一工作,旨在定義標準容器存儲接口,使存儲驅動程序能夠在任何容器編排器上工作。

CSI 規範已經適用於Kubernetes,並且在Kubernetes 集羣上有大量驅動程序插件可供部署。開發人員可以Kubernetes 上使用CSI 卷類型訪問CSI 兼容卷驅動程序公開的存儲。

隨着CSI 的引入,存儲可以被視爲另一個工作負載容器化,並在Kubernetes 集羣上部署。

開源項目

圍繞雲原生技術的工具和項目大幅增加。作爲生產環境中最突出的問題之一,有相當多的開源項目致力於解決雲原生架構上的存儲問題。

關於存儲的最受歡迎的項目是Ceph 和Rook。

Ceph是一個動態管理,可水平擴展的分佈式存儲集羣。Ceph 提供了對存儲資源的邏輯抽象。它被設計爲沒有單點故障,可自我管理並基於軟件。Ceph 爲同一存儲集羣同時提供塊、對象和文件系統接口。

Ceph 的架構很複雜,有許多底層技術,如RADOS、librados、RADOSGW、RDB、CRUSH 算法,以及監視器、OSD和MDS等組件。Ceph 是一個分佈式存儲集羣,不需要深入研究其體架構,關鍵在於,它是一個分佈式存儲集羣,可以更輕鬆地實現可擴展性,在不犧牲性能的情況下消除單點故障,並提供了對對象、塊和文件的訪問的統一存儲。

當然,Ceph 已經適應了雲原生環境。可以通過多種方式部署Ceph 集羣,例如使用Ansible。可以從Kubernetes 集羣中使用CSI 和PVC 接口訪問部署的Ceph 集羣。

另一個有趣且頗受歡迎的項目是Rook,一個旨在融合Kubernetes 和Ceph 的工具 - 將計算和存儲集中在一個集羣中。

Rook是一個雲原生存儲編排器。它擴展了Kubernetes。Rook 本質上允許將Ceph 放入容器中,並提供集羣管理邏輯,以便在Kubernetes 上可靠地運行Ceph。Rook 自動化部署、引導、配置、擴展、負載均衡,即集羣管理員需要做的工作。

Rook 允許通過yaml 文件部署Ceph 集羣,就像Kubernetes 一樣。此文件用作集羣管理員在集羣中所需內容的高級聲明。Rook 整合集羣,並開始積極監控。Rook 充當運維人員或控制器,確保yaml 文件中聲明的期望狀態得到保證。Rook 在一個協調循環中運行,觀察狀態並根據檢測到的差異採取行動。

Rook 沒有自己的持久化狀態,也不需要管理。它的確是根據Kubernetes 的原則構建的。

Rook 將Ceph 和Kubernetes 結合在一起,是最受歡迎的雲原生存儲解決方案之一,在Github 上擁有近4000 顆星,1630萬 下載量和100多名貢獻者。

作爲被CNCF 接受的首個存儲項目,Rook 近期已進入孵化階段。

對於應用程序中的任何問題,確定需求,設計系統和選擇相應工具非常重要。雲原生環境中的存儲也不例外。雖然問題非常複雜,但仍有許多工具和方法。隨着雲原生世界的發展,無疑也會出現新的解決方案。

查看英文原文:https://softwareengineeringdaily.com/2019/01/11/why-is-storage-on-kubernetes-is-so-hard/

https://softwareengineeringdaily.com/2019/01/07/stateful-kubernetes-with-saad-ali/

https://i2.wp.com/softwareengineeringdaily.com/wp-content/uploads/2018/05/logo.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章