Gartner IOCS 2018 Conference polling results
最初的容器主要應(yīng)用于無狀態(tài)應(yīng)用,并不需要持久化的存儲,但隨著容器被原來越多的采用,以及其配合 Kubernetes 帶來的強大的自動化管理能力,MongoDB、MySQL 和 PostgreSQL 等有狀態(tài)應(yīng)用被越來多的運行于容器之上,對持久化存儲提出更多需求和更高的要求。
SmartX 分布式塊存儲(內(nèi)部代號:SMTX ZBS)由 SmartX 自主開發(fā),作為 SmartX 超融合的核心引擎,ZBS 已經(jīng)被大量應(yīng)用于金融、制造業(yè)、通信、地產(chǎn)等行業(yè)的私有云建設(shè)、虛擬化整合等場景,承載用戶生產(chǎn)以及開發(fā)業(yè)務(wù)。其穩(wěn)定性、易用性和豐富的存儲特性已經(jīng)經(jīng)過長時間檢驗,并獲得大量行業(yè)頭部認(rèn)可。
日前,SMTX ZBS 的 CSI 驅(qū)動已正式加入到 K8s 官方的驅(qū)動列表,企業(yè)客戶不僅可以繼續(xù)使用 SMTX ZBS 構(gòu)建私有云和超融合系統(tǒng),亦可使用其為 K8s 提供持久化存儲,支持?jǐn)?shù)據(jù)庫等有狀態(tài)應(yīng)用,進一步加速 K8s 在企業(yè)內(nèi)部更多場景落地。
Kubernetes 官網(wǎng)截圖
以下部分概述了 CSI 的機制以及 SMTX ZBS 與 CSI 的接口實現(xiàn)。
概念與定義
1 K8s 的持久化存儲支持
在支持持久化存儲方面,K8s 提供了內(nèi)嵌原生 Driver 的方式連接外部的常見存儲系統(tǒng)例如 NFS、iSCSI、CephFS、RBD 等來滿足不同業(yè)務(wù)的需求。但由于存儲生態(tài)本身也在不斷演進,使用 K8s 內(nèi)嵌的方式來支持不斷變化的存儲系統(tǒng)在成本和時效上都會對 K8s 項目自身帶來巨大的挑戰(zhàn)。
所以和其他服務(wù)管理系統(tǒng)一樣,K8s 逐漸的將存儲系統(tǒng)的具體實現(xiàn)從主項目中分離出來,通過定義接口的方式允許第三方廠商自行接入存儲服務(wù)。在這個道路上也經(jīng)歷了兩個階段:
1. Flex Volume, 自 1.2 版本引入。
第三方存儲服務(wù)提供商直接在 K8s Server 上部署符合 Flex Volume 規(guī)范的 Driver,利用 K8s 暴露出的 mount/unmount/attach/detach 等關(guān)鍵 API 實現(xiàn)存儲系統(tǒng)的接入。這個模式主要的問題是,在這個形態(tài)下第三方廠商的 Driver 有權(quán)限接入物理節(jié)點的根文件系統(tǒng),這會帶來安全上的隱患。
2. Container Storage Interface (CSI), 自 1.9 版本引入,目前已經(jīng)進入 GA 階段(1.13)。
CSI 定義了容器場景所需要的存儲控制原語和完整的控制流程,并且在 K8s 的 CSI 實現(xiàn)中,所有的第三方 Driver 和 K8s 的其他服務(wù)擴展一樣,以服務(wù)容器的形態(tài)的運行,不會直接影響到 K8s 的核心系統(tǒng)穩(wěn)定性。
2 存儲對象
CSI 定義的存儲對象為持久化卷,稱之為 Volume。包括兩種類型:
Mounted File Volume,Node 將會把 Volume 以指定的文件格式 Mount 到 Container 上,從 Container 的角度看到的是一個目錄;
Raw Block Volume, 直接將 Volume 以 Block Device(磁盤)的形態(tài)暴露給 Container,對于某些可以直接操作磁盤的服務(wù),這個形態(tài)可以省去文件系統(tǒng)的開銷獲得更好的性能。
Raw Block Volume 目前還處于 Beta 階段,所以下文的過程描述和 SMTX 的 CSI Driver 目前的實現(xiàn)方式均針對 Mounted File Volume。
3 Plugin
CSI 將一個實現(xiàn)了 CSI 服務(wù)的 Driver 稱之為 Plugin。根據(jù)提供的功能不同將它分為兩種類型:
·Controller Plugin,負(fù)責(zé)存儲對象(Volume)的生命周期管理,在集群中僅需要有一個即可;
·Node Plugin,在必要時與使用 Volume 的容器所在的節(jié)點交互,提供諸如節(jié)點上的 Volume 掛載/卸載等動作支持,如有需要則在每個服務(wù)節(jié)點上均部署。
存儲服務(wù)商可以根據(jù)自身需求實現(xiàn)不同的的 Plugin 組合。例如對于以 NFS 形式提供的存儲服務(wù),可以僅實現(xiàn) Controller Plugin 實現(xiàn)資源的創(chuàng)建和訪問權(quán)限控制,每個節(jié)點均可以通過標(biāo)準(zhǔn)的 NFS 方式獲得服務(wù),無需通過 Node Plugin 來實現(xiàn)掛載/卸載等操作。而以 iSCSI 形式提供的存儲服務(wù),就需要 Node Plugin 在指定節(jié)點上,通過掛載 LUN,格式化,掛載文件系統(tǒng)等一系列動作完成 iSCSI LUN 至容器可見的目錄形式的轉(zhuǎn)化。
4 Volume 生命周期
一個典型的 CSI Volume 生命周期如下圖(來自 CSI SPEC)所示:
1.Volume 被創(chuàng)建后進入 CREATED 狀態(tài),此時 Volume 僅在存儲系統(tǒng)中存在,對于所有的 Node 或者 Container 都是不可感知的;
2.對 CREATED 狀態(tài)的 Volume 進行 Controlller Publish 動作后在指定的 Node 上進入 NODE_READY 的狀態(tài),此時 Node 可以感知到 Volume,但是 Container 依然不可見;
3.在 Node 對 Volume 進行 Stage 操作,進入 VOL_READY 的狀態(tài),此時 Node 已經(jīng)與 Volume 建立連接。Volume 在 Node 上以某種形式存在;
4.在 Node 上對 Volume 進行 Publish 操作,此時 Volume 將轉(zhuǎn)化為 Node 上 Container 可見的形態(tài)被 Container 利用,進入正式服務(wù)的狀態(tài);
5.當(dāng) Container 的生命周期結(jié)束或其他不再需要 Volume 情況發(fā)生時,Node 執(zhí)行 Unpublish Volume 動作,將 Volume 與 Container 之間的連接關(guān)系解除,回退至 VOL_READY 狀態(tài);
6.Node Unstage 操作將會把 Volume 與 Node 的連接斷開,回退至 NODE_READY 狀態(tài);
7.Controller Unpublish 操作則會取消 Node 對 Volume 的訪問權(quán)限;
8.Delete 則從存儲系統(tǒng)中銷毀 Volume。
9.CSI 要求狀態(tài)轉(zhuǎn)化操作是冪等的,并在原則上保證 Volume 的狀態(tài)轉(zhuǎn)化是有序進行的。
根據(jù)存儲使用方式和內(nèi)部實現(xiàn)的不同,狀態(tài)機可以略有區(qū)別,但對應(yīng)操作必須是成對出現(xiàn)的。例如在不需要額外建立 Node 與 Volume 之間連接的 Stage/Unstage 階段時,狀態(tài)機就可以直接通過 Controller Publish/Unpublish 在 NODE_READY 與 PUBISHED 之間轉(zhuǎn)化,而無需經(jīng)過 VOL_READY 階段。Plugin 向 CSI 注冊時必須聲明自身支持哪些語義。
5 RPC
CSI 要求 Plugin 支持的 RPC 包括:
Identity Service:認(rèn)證服務(wù),Controller 和 Node Plugin 均需要支持
GetPluginInfo,獲取 Plugin 基本信息
GetPluginCapabilities,獲取 Plugin 支持的能力
Probe,探測 Plugin 的健康狀態(tài)
Controller Service:控制服務(wù)
Volume CRUD,包括了擴容和容量探測等 Volume 狀態(tài)檢查與操作接口
Controller Publish/Unpublish Volume,Node 對 Volume 的訪問權(quán)限管理
Snapshot CRD,快照的創(chuàng)建和刪除操作,目前 CSI 定義的 Snapshot 僅用于創(chuàng)建 Volume,未提供回滾的語義
Node Service:節(jié)點服務(wù)
Node Stage/Unstage/Publish/Unpublish/GetStats Volume,節(jié)點上 Volume 的連接狀態(tài)管理
Node Expand Volume, 節(jié)點上的 Volume 擴容操作,在 volume 邏輯大小擴容之后,可能還需要同步的擴容 Volume 之上的文件系統(tǒng)并讓使用 Volume 的 Container 感知到,所以在 Node Plugin 上需要有對應(yīng)的接口
Node Get Capabilities/Info,Plugin 的基礎(chǔ)屬性與 Node 的屬性查詢
部署形態(tài)
CSI 使用 Sidecar 的方式實現(xiàn) CSI Plugin 與 K8s 核心邏輯的解耦。Sidecar 代表監(jiān)聽了 CSI 指定 API 的標(biāo)準(zhǔn)容器,它與 CSI Plugin 共同組成一個 Pod 對外提供服務(wù),它們之間通過 Socket 連接。在這個模式下,Sidecar 成為 CSI Plugin 與 K8s 之間連接的中介和隔離帶。理想狀態(tài)下二者可以在不直接交互和影響的情況下共同工作,解決了安全問題。
CSI 定義了如下幾種 Sidecar:
external-provisioner:監(jiān)聽 Volume CRUD API,完成 Volume 的生命周期管理
external-attacher:監(jiān)聽 Controller[Publish|Unpublish]Volume API,實現(xiàn) Node 和 Volume 的可見性控制
external-snapshotter:監(jiān)聽 Snapshot CRD API,完成 Snapshot 的生命周期管理
node-driver-register:監(jiān)聽 Node 基本信息查詢 API,注冊 Node Plugin,每個節(jié)點 Node Plugin 均需要通過 driver-register 注冊自身才可以與 K8s 之間建立連接獲取 Node Volume 相關(guān)請求
cluster-driver-register:用于向 K8s 注冊 Plugin 整體支持的模式,包括是否跳過 Attach 階段/是否在 Node Publish Volume 階段時需要 K8s 提供 Pod 信息
livenessprobe:心跳檢測,用于探測 Plugin 的存活狀態(tài)
適用場景
在容器化發(fā)展的早期階段,Container 多用于承擔(dān)輕量型的無狀態(tài)服務(wù),對數(shù)據(jù)存儲的需求大多通過本地的臨時共享文件,或者用網(wǎng)絡(luò)訪問的方式將數(shù)據(jù)置于遠(yuǎn)端的日志收集或者 DB 等外部存儲上。這種模式業(yè)務(wù)和數(shù)據(jù)之間從程序管理的角度看是松耦合的,互相獨立,沒有嚴(yán)格的依賴。
但是另一方面,這個模式下數(shù)據(jù)本身無法成為服務(wù)的一部分,并不能通過 K8s 統(tǒng)一管理。并且需要為每個應(yīng)用打開通往遠(yuǎn)端存儲服務(wù)的網(wǎng)絡(luò)通道,這在安全性上有時并不是一個好的選擇。
而基于持久化卷,將數(shù)據(jù)服務(wù)提供方也放入 K8s Pod 中(例如掛載持久化卷作為磁盤,上面部署容器運行 DB)作為完整應(yīng)用的一部分,數(shù)據(jù)即可以做到與應(yīng)用無縫的統(tǒng)一管理,所有應(yīng)用內(nèi)部 Pod 間的業(yè)務(wù)數(shù)據(jù)請求均可以在 K8s 提供的虛擬網(wǎng)絡(luò)中進行。而基于 K8s 本身的高可用特性和 CSI Driver 的靈活配置能力也可以獲得不遜色于外部存儲的可靠性與性能。
SMTX ZBS x CSI
1 SMTX ZBS
SMTX ZBS 通過 iSCSI 的方式為 K8s 提供持久化存儲。它的內(nèi)部結(jié)構(gòu)如下圖所示:
SMTX ZBS 內(nèi)部結(jié)構(gòu)
在每個節(jié)點上部署有 Chunk Server 用于管理本地的 SSD/HDD 提供統(tǒng)一的高性能混合存儲服務(wù),在部分節(jié)點上部署 Meta 作為元數(shù)據(jù)管理服務(wù),將 Chunk Server 組成高可靠集群。每個 Chunk Server 提供如 iSCSI Target 這樣的協(xié)議接入服務(wù),他們在接入上是邏輯等價的,即可以從任一一個 Chunk Server 訪問到集群中所有的 Target 和 LUN。
2 ZBS CSI Driver
ZBS CSI Driver 的部署形態(tài)如下圖所示:
ZBS CSI Driver 部署形態(tài)
每個 CSI Volume 與 ZBS iSCSI LUN 一一對應(yīng),它的生命周期如下:
1.Create Volume:Controller Plugin 收到創(chuàng)建請求之后會在 ZBS 中創(chuàng)建一個 iSCSI LUN,如有必要則會自動再創(chuàng)建需要的 Target,ZBS 的實現(xiàn)中,iSCSI LUN 以及所屬的 Target 均為邏輯對象,不與物理磁盤綁定。一個集群中允許創(chuàng)建 4096 個 Target,每個 Target 中最多允許創(chuàng)建 255 個 LUN,多個 CSI Volume 會處在相同的 Target 內(nèi);
2.Controller Publish Volume:目前 Kubernetes 使用 Open iSCSI 作為節(jié)點上的數(shù)據(jù)接入服務(wù),Open iSCSI 在掛載 Target 時,會將所有 Target 內(nèi)的 LUN 均掛載到主機上作為一個 Block Device(例如 /dev/sdx 這樣的磁盤)。為了避免讓主機察覺到不需要也不應(yīng)該訪問的 LUN,ZBS 采用了近似 LUN Masking 的機制來達到這個目標(biāo)。在初始 Volume 對應(yīng)的 LUN 在創(chuàng)建時,不會允許任何 iSCSI initiator?(iSCSI 的協(xié)議客戶端)發(fā)現(xiàn) LUN。在 Controller Publish Volume 階段,ZBS Controller Plugin 會將指定 Node 上的 initiator 注冊到 LUN 上,在這之后,關(guān)聯(lián) Node 的 iSCSI discovery 機制才可以在 Target 內(nèi)發(fā)現(xiàn)并訪問 LUN;
3.Node Stage Volume:ZBS Node Plugin 會將 LUN 通過 Open iSCSI 命令掛載至主機,呈現(xiàn)為一個磁盤;
4.Node Publish Volume:ZBS Node Plugin 對磁盤進行格式化(如果磁盤之前尚未被格式化,如已經(jīng)格式化則為跳過對應(yīng)步驟),將磁盤 Mount 到主機上提供給 Container 使用;
5.Node Unpublish Volume:ZBS Node Plugin 將磁盤上的文件系統(tǒng) Unmount;
6.Node Stage Volume:ZBS Node Plugin 在主機上將斷開磁盤的 iSCSI 鏈接;
7.Controller Unpublish Volume:ZBS Controller Plugin 向 ZBS 后端注銷指定 Node 在 LUN 上的訪問權(quán)限;
8.Delete Volume:ZBS Controller Plugin 請求 ZBS 刪除對應(yīng)的 LUN,LUN 所占用的數(shù)據(jù)空間將會在存儲系統(tǒng)中被回收。
ZBS CSI Driver 支持 Snapshot CRD 操作,Snapshot 的方式為 COW,相關(guān)請求僅涉及簡單的元數(shù)據(jù)操作,所以關(guān)聯(lián)接口會以同步模式快速響應(yīng)。Snapshot 自身或者基于 Snapshot 創(chuàng)建的 Volume 都會立刻處于 Volume Ready 的狀態(tài)。
3 數(shù)據(jù)鏈路
K8s 和 ZBS 之間的 iSCSI 數(shù)據(jù)鏈路如下圖所示:
K8s 和 ZBS 之間的 iSCSI 數(shù)據(jù)鏈路
ZBS 使用 iSCSI Redirector 模式提供 iSCSI 接入服務(wù),CSI Plugin 給 Driver 提供的 iSCSI 服務(wù)端地址為 iSCSI Redirector 地址,initiator 嘗試連接 iSCSI Server(Target 端,ZBS 中由 Chunk 提供 Target 服務(wù))時,Redirector 將會采用的 hash 的方式引導(dǎo) initiator 重新連接向一個可用的 Chunk Server。
在重定向之后,所有的數(shù)據(jù)請求僅在 initiator 與 Chunk 之間進行,無需經(jīng)過 Redirectord。ZBS 集群中所有 Chunk Server 在處理 iSCSI 接入請求時是邏輯等價的,即任一 Chunk 均可以提供集群中的任一個 Target LUN 的數(shù)據(jù)訪問服務(wù)。重定向的方式可以有效的分散數(shù)據(jù)接入壓力,充分利用集群性能。
4 可靠與可用性
SMTX ZBS 在設(shè)計之初就以高可靠、高可用、高性能為目標(biāo),在集群內(nèi)部采用多副本,靜默數(shù)據(jù)檢查自動平衡和恢復(fù)等機制來保證數(shù)據(jù)的安全可靠。在這個基礎(chǔ)之上,K8s CSI 模式獲得比使用本地存儲更高的安全性。
異常處理
K8s 計算節(jié)點異常
Node A 上的 pod 將會被自動在其他節(jié)點(Node B)上拉起,會重新經(jīng)歷 Node B 上 Publish Volume 至掛載的動作。Node B 會接入 Chunk server 提供 Pod 關(guān)聯(lián)的 Volume 的 IO 服務(wù),之前在 Node A 上已經(jīng)寫入 Volume 中的數(shù)據(jù)不會受到損失。
Chunk 節(jié)點異常
如果是計算節(jié)點當(dāng)前連接的 Chunk 異常,則與 Chunk 節(jié)點間的鏈路將中斷,計算節(jié)點會重新向 iSCSI Redirector 服務(wù)尋求一個新的接入節(jié)點迅速恢復(fù)服務(wù)。通常情況下這個影響的時間為秒級。
如果非當(dāng)前連接的 Chunk 異常,可能會因為 IO 副本損失而產(chǎn)生短暫的延遲,iSCSI 鏈路本身不會受到影響,影響時間也為秒級。
iSCSI Redirector 節(jié)點異常
SMTX ZBS 提供 VIP(虛擬 IP)服務(wù),可以保證集群中有且僅有一個節(jié)點會持有該 VIP。iSCSI Redirector 運行在 VIP 節(jié)點上,當(dāng)它異常時。自然會替換到新的 VIP 節(jié)點提供 iSCSI Redirector 服務(wù)。ZBS 保證所有的節(jié)點提供的 Redirector 服務(wù)是等價的。
雙活與異地備份
ZBS 在基本存儲功能的基礎(chǔ)上,還提供雙活集群和異地備份的功能。借助這兩個功能,K8s CSI Volume 可以獲得同城跨數(shù)據(jù)中心的數(shù)據(jù)強一致安全性保證或者是自動的跨城市/數(shù)據(jù)中心的定期備份能力。
5 整體部署形式
目前 SMTX 對 CSI 支持兩種形態(tài)的部署形式,基于 VM 的融合模式與分離模式,后續(xù)將提供 SMTX K8s 原生融合模式的部署支持。
分離模式
K8s 和 SMTX ZBS 分別是獨立的物理集群,他們之間通過接入網(wǎng)絡(luò)互相關(guān)聯(lián)。接入網(wǎng)絡(luò)需要獨立于 K8s 中的業(yè)務(wù)網(wǎng)絡(luò)和 ZBS 使用的存儲網(wǎng)絡(luò)。
融合模式
融合模式下,K8s 運行在 SMTX OS 提供的虛擬機上。通過接入網(wǎng)絡(luò)接入 SMTX OS 上的 ZBS 服務(wù)。這個部署方式可以更高效的利用物理資源。