嘿哈布爾!
我們提醒您,我們發布了另一個非常有趣且有用的 關於 Kubernetes 模式。一切都始於“「 Brendan Burns,順便說一句,我們在這方面有工作 。今天,我們邀請您閱讀 MinIO 部落格中的一篇文章,其中簡要概述了 Kubernetes 中資料儲存模式的趨勢和細節。
Kubernetes 從根本上改變了傳統的應用程式開發和部署模式。現在,團隊可以在幾天內跨多個環境(全部在 Kubernetes 叢集內)開發、測試和部署應用程式。使用前幾代技術的此類工作通常需要數週甚至數月的時間。
這種加速是透過 Kubernetes 提供的抽象實現的——也就是說,因為 Kubernetes 本身與物理機或虛擬機的底層細節進行交互,允許用戶聲明所需的處理器、所需的內存量和容器的數量實例等參數。憑藉支持 Kubernetes 的龐大社群及其不斷擴大的採用範圍,Kubernetes 在所有容器編排平台中遙遙領先。
隨著 Kubernetes 使用的成長,對其儲存模式的困惑也在增加。.
由於每個人都在爭奪 Kubernetes 的一塊蛋糕(即資料儲存),當涉及資料儲存時,訊號被淹沒在大量的噪音中。
Kubernetes 體現了應用程式開發、部署和管理的現代模型。這種現代模型將資料儲存與計算分離。要充分理解 Kubernetes 背景下的分離,您還需要了解什麼是有狀態應用程式和無狀態應用程序,以及資料儲存如何適應其中。這就是 S3 使用的 REST API 方法相對於其他解決方案的 POSIX/CSI 方法具有明顯優勢的地方。
在本文中,我們將討論 Kubernetes 中的資料儲存模式,並特別討論有狀態應用程式和無狀態應用程式之間的爭論,以更好地理解它們之間的區別以及為什麼它很重要。本文的其餘部分將根據使用容器和 Kubernetes 的最佳實踐來研究應用程式及其資料儲存模式。
無狀態容器
容器本質上是輕量級且短暫的。它們可以輕鬆停止、刪除或部署到另一個節點 - 一切只需幾秒鐘。在大型容器編排系統中,這樣的操作一直在發生,而使用者甚至沒有註意到這樣的變化。但是,只有當容器對其所在的節點沒有任何依賴性時,才可能進行移動。據說這樣的容器可以工作 無國籍的.
有狀態容器
如果容器將資料儲存在本地連接的設備(或區塊設備)上,則在發生故障時,其所在的資料儲存必須連同容器本身一起移動到新節點。這很重要,因為否則容器中運行的應用程式將無法正常運行,因為它需要存取儲存在本機媒體上的資料。據說這樣的容器可以工作 有狀態的.
從純粹的技術角度來看,有狀態容器也可以移動到其他節點。這通常是使用附加到運行容器的所有節點的分散式檔案系統或區塊網路儲存來實現的。透過這種方式,容器存取磁碟區以進行持久性資料存儲,並且資訊儲存在位於整個網路的磁碟上。我將這個方法稱為“有狀態容器方法”,為了統一起見,在本文的其餘部分我將這樣稱呼它。

在典型的有狀態容器方法中,所有應用程式 Pod 都附加到單一分散式檔案系統 - 一種所有應用程式資料所在的共用儲存。雖然可能存在一些變化,但這是一種高級方法。
現在讓我們看看為什麼有狀態容器方法在以雲端為中心的世界中是一種反模式。
雲端原生應用程式設計
傳統上,應用程式使用資料庫來結構化資訊存儲,並使用本機磁碟或分散式檔案系統來轉儲所有非結構化甚至半結構化資料。隨著非結構化資料量的增長,開發人員意識到 POSIX 過於繁瑣,開銷巨大,並最終在轉向真正大規模時阻礙了應用程式效能。
這主要促成了一種新的資料儲存標準的出現,即基於雲端的存儲,它主要基於 REST API 工作,並將應用程式從本地資料儲存的繁瑣維護中解放出來。在這種情況下,應用程式實際上會進入無狀態模式(因為狀態位於遠端儲存中)。現代應用程式是從頭開始建立的,考慮到了這個因素。通常,任何處理一種或另一種資料(日誌、元資料、blob 等)的現代應用程式都是根據面向雲端的範例構建的,其中狀態被傳輸到專門用於其儲存的軟體系統。
有狀態容器方法迫使整個範例回到它開始的地方!
透過使用 POSIX 介面來儲存數據,應用程式就像有狀態一樣運行,因此,它們背離了以雲為中心的設計的最重要原則,即根據傳入的情況改變應用程式工作線程大小的能力輸入,當前節點故障後立即移動到新節點,以此類推。
仔細觀察這種情況,我們發現在選擇資料儲存時,我們一次又一次地面臨 POSIX 與 REST API 的困境,而且由於 Kubernetes 環境的分散特性,POSIX 問題進一步加劇。尤其,
- POSIX 很健談:POSIX 語意要求每個操作都與有助於維護操作狀態的元資料和檔案描述子相關聯。這導致了沒有實際價值的巨大成本。物件儲存 API,特別是 S3 API,擺脫了這些要求,允許應用程式啟動,然後「忘記」呼叫。來自儲存系統的回應指示操作是否成功。如果失敗,應用程式可以重試。
- 網路限制:在分散式系統中,這意味著可能有許多應用程式嘗試將資料寫入相同的附加媒體。因此,不僅應用程式會相互競爭資料傳輸頻寬(將資料傳送到媒體),而且儲存系統本身也會透過跨實體磁碟發送資料來競爭此頻寬。由於POSIX的繁瑣,網路呼叫的數量增加了數倍。另一方面,S3 API 明確區分了從客戶端到伺服器的網路呼叫和在伺服器內發生的網路呼叫。
- 安全:POSIX 安全模型專為積極的人類參與而設計:管理員為每個使用者或群組配置特定的存取等級。這種範式很難適應以雲端為中心的世界。現代應用程式依賴基於 API 的安全模型,其中存取權限被定義為指派的一組策略、服務帳戶、臨時憑證等。
- 可控性:有狀態容器有一些管理開銷。我們談論的是同步並行資料訪問,確保資料一致性,這一切都需要仔細考慮使用哪種資料存取模式。必須安裝、監控和配置額外的軟體,更不用說額外的開發工作了。
容器資料儲存介面
雖然容器儲存介面(CSI)對Kubernetes 卷層的普及起到了很大的幫助,並將其部分外包給第三方儲存供應商,但它也無意中促成了這樣一種信念:有狀態容器方法是推薦的方法。
CSI 是作為一種標準而開發的,用於在 Kubernetes 上運行時向遺留應用程式提供任意區塊和檔案儲存系統。而且,如本文所示,有狀態容器方法(以及目前形式的 CSI)唯一有意義的情況是應用程式本身就是一個遺留系統,無法新增對物件儲存 API 的支援。
重要的是要理解,使用當前形式的 CSI,即在使用現代應用程式時安裝卷,我們將遇到與以 POSIX 風格組織資料儲存的系統中出現的大致相同的問題。
更好的方法
在這種情況下,重要的是要了解大多數應用程式本質上並不是專為有狀態或無狀態工作而設計的。此行為取決於整體系統架構和所做的特定設計選擇。我們來談談有狀態應用程式。
原則上,所有應用資料都可以分為幾大類:
- 記錄數據
- 時間戳數據
- 交易數據
- 元數據
- 容器鏡像
- Blob(二進位大物件)數據
所有這些資料類型在現代儲存平台上都得到了很好的支持,並且有幾個專門定制的雲端原生平台可以以每種特定格式提供資料。例如,交易資料和元資料可能駐留在現代雲端原生資料庫中,例如 CockroachDB、YugaByte 等。容器映像檔或blob資料可以儲存在基於MinIO的docker註冊表中。時間戳資料可以儲存在時間序列資料庫中,例如InfluxDB等。這裡我們不會詳細介紹每種資料類型及其應用,但總體思路是避免依賴本機磁碟掛載的持久性資料儲存。

此外,提供一個臨時快取層作為應用程式的臨時檔案儲存通常是有效的,但應用程式不應依賴該層作為事實來源。
有狀態的應用程式存儲
雖然在大多數情況下保持應用程式無狀態很有用,但那些旨在儲存資料的應用程式(例如資料庫、物件儲存、鍵值儲存)必須是有狀態的。讓我們來看看為什麼這些應用程式部署在 Kubernetes 上。我們以 MinIO 為例,但類似的原則也適用於任何其他大型雲端原生儲存系統。
雲端原生應用程式旨在充分利用容器固有的靈活性。這意味著他們不對部署環境做出任何假設。例如,MinIO 使用內部糾刪碼機制為系統提供足夠的彈性,即使一半磁碟發生故障也能保持運作。 MinIO 還使用專有的伺服器端雜湊和加密來管理資料完整性和安全性。
對於此類以雲端為中心的應用程序,本地持久性磁碟區 (PV) 作為備份儲存最方便。本地 PV 提供儲存原始資料的能力,而在這些 PV 之上運行的應用程式獨立收集資訊以擴展資料並管理不斷增長的資料需求。
這種方法比基於 CSI 的 PV 簡單得多,並且可擴展性顯著提高,後者在系統中引入了自己的資料管理層和冗餘層;關鍵是這些層通常與設計為有狀態的應用程式衝突。
將數據與計算分離的強烈趨勢
在本文中,我們討論了應用程式如何重新定位以在不保存狀態的情況下工作,或者換句話說,儲存資料與資料計算分離。總之,讓我們來看看這種趨勢的一些真實例子。
是一個著名的數據分析平台,傳統上是有狀態的並部署在 HDFS 上。然而,隨著 Spark 進入以雲端為中心的世界,該平台越來越多地使用「s3a」進行無狀態使用。 Spark 使用 s3a 將狀態傳送到其他系統,而 Spark 容器本身則完全無狀態運作。大數據分析領域的其他主要企業參與者,特別是 , , 他們還致力於將數據存儲和計算分開。
類似的模式也可以在其他大型分析平台上看到,包括 Presto、Tensorflow to R、Jupyter。透過將狀態卸載到遠端雲端儲存系統,管理和擴展應用程式變得更加容易。此外,它還有助於將應用程式移植到各種環境中。
來源: www.habr.com
