容器化 RDS:藉助 CSI 擴充套件 Kubernetes 儲存能力
-
現有 Kubernetes 儲存外掛系統問題
-
Container Storage Interface(CSI)
-
基於CSI 和分散式檔案系統實現在 MySQL 的 Volume 動態擴充套件
-
對 CSI 的展望
原名 | 簡稱 |
容器編排系統 | CO. |
儲存提供者 | SP. |
儲存外掛介面 | Volume Plugin Interface |
儲存驅動 | Volume Driver |
容器儲存介面 Container Storage Interface |
CSI |
如有遺漏,不吝賜教。
現有 Kubernetes 儲存外掛系統問題
可供選的容器編排系統(後面簡稱 CO.)不少,除去 Kubernetes 還有 Mesos、Swarm、Cloud Foundry。以 Kubernetes 為例,其通過 PersistentVolume 抽象對以下儲存的支援:
-
GCEPersistentDisk
-
AWSElasticBlockStore
-
AzureFile
-
AzureDisk
-
FC(Fibre Channel)**
-
FlexVolume
-
Flocker
-
NFS
-
iSCSI
-
RBD(Ceph Block Device)
-
CephFS
-
Cinder(OpenStack block storage)
-
GlusterFS
-
VsphereVolume
-
Quobyte Volumes
-
HostPath
-
VMware Photon
-
Portworx Volumes
-
ScaleIO Volumes
-
StorageOS
-
VolumePlugin
-
PersistentVolumePlugin
-
DeletableVolumePlugin
-
ProvisionableVolumePlugin
-
ExpandableVolumePlugin
-
Provisioner
-
Deleter
以上介面並不需要全部實現,其中 VolumePlugin[1] 是必須實現的介面。
系統架構圖如下:
這種方式為 Kubernetes 提供了豐富的儲存支援列表,但是在具體實現上,SP. Volume Driver 程式碼也在 Kubernetes 程式碼倉庫(又叫in-tree),它帶來幾個顯著的問題。
從 Kubernetes 的角度看:
-
需要在 Kubernetes 中給各個 SP. 賦權以便他們能夠提交程式碼到倉庫;
-
Volume Driver 由各個 SP. 提供,Kubernetes 的開發者並不瞭解每個細節,導致這些程式碼難於維護和測試;
-
Kubernetes 的釋出節奏和各位 SP. Volume Driver 的節奏並不一致,隨著支援的 SP. 增多,溝通、維護、測試成本會越來越高;
-
這些 SP. Volume Driver 並不是 Kubernetes 本身需要的。
從 SP. 的角度看:
-
提交一個新特性或者修復 bug,都需要提交程式碼到 Kubernetes 倉庫,在本地編譯 Kubernetes 的都知道,這個過程是很痛苦的,這對 SP. 而言是完全不必要的成本。
Container Storage Interface(CSI)
基於這些問題和挑戰,CO 廠商提出 Container Storage Interface 用來定義容器儲存標準,它獨立於 Kubernetes Storage SIG,由 Kubernetes、Mesos、Cloud Foundry 三家一起推動。個人理解它有如下2個核心目標:
-
提供統一的 CO. 和 SP. 都遵循的容器儲存介面。
-
一旦 SP. 基於 CSI 實現了自身的 Volume Driver,即可在所有支援 CSI 的 CO 中平滑遷移。
還有一個附帶的好處是,一旦 CO. 和 SP. 都遵循 CSI,就便於將 Volume Driver 解耦到 Kubernetes 的外部(又叫 out-of-tree)。Kubernetes 只用維護 CSI 介面,不用再維護 SP. 的具體實現,維護成本大大降低。
CSI 優化下的架構圖:
可以看到,Kubernetes 和 SP. 從此涇渭分明,但事情並沒有那麼簡單,借用一位大神說的:The performance improvement does not materialize from the air, it comes with code complexity increase.和效能一樣,擴充套件性和解耦也不是憑空出現。上圖可進一步細化成下圖:
明顯的變化有:
-
Controller Plane、Kubelet 不再直接與 Volume Driver 互動,引入 external-provisioner 和 external-attacher 完成該工作;
-
SP. Volume Driver 會由獨立的容器執行;
-
為了實現 external-provisioner、external-attacher 和 SP. Volume Driver 的互動引入 gRPC 協議(標紅箭頭)。
還有一些其他的變化:
-
在 Kubernetes 端 引入新的物件:
CSIPersistentVolumeSource:該型別 PV 由 CSI Driver 提供
VolumeAttachment:同步 Attach 和 Dettach 資訊
-
引入新的名稱:
mount/umount:NodePublishVolume/NodeUnpublishVolume
attach/dettach:ControllerPublishVolume/ControllerUnpublishVolume
Note:Kubernetes 適配 CSI 設計文件[3]。
可見,為了達到這個目標,相比原來複雜不少,但收益巨大,Kubernetes 和 SP. 的開發者可以專注於自身的業務。
即便如此,在現有的 CSI 上做擴充套件有時也在所難免。
基於 CSI 和分散式檔案系統實現在 MySQL 上的 Dynamically Expand Volume
Kubernetes 儲存子系統已經非常強大,但是還欠缺一些基礎功能,譬如支援 Expand Volume (部分 Storage Vendor 支援)和 SnapShot,尤其是 Expand Volume,這是必須的功能,因為隨著業務的變化,容量的增加在所難免,一旦容量接近閾值,若以遷庫的方式擴充套件儲存容量,成本太高。但現狀並不樂觀,Kubernetes 1.10.2 使用 CSI 0.2.0,其並不包含 Expand Volume 介面,這意味著即便底層的儲存支援擴容,Kubernetes 也無法使用該功能,所以我們需要做點 hard code 實現該功能:
-
擴充套件 CSI Spec
-
擴充套件 CSI Plugin
-
基於 CSI Spec 實現 Storage Driver
-
演示
-
其他
擴充套件 CSI Spec
前面提到,在 CSI 中引入了 gRPC,個人理解在 CSI 的場景有如下3個優點:
-
基於 protobuf 定義強型別結構,便於閱讀和理解
-
通過 stub 實現遠端呼叫,程式設計邏輯更清晰
-
支援雙工和流式,提供雙向互動和實時互動
網路上介紹 gRPC 和 protobuf 的文章很多,這裡不贅述。
通過 gRPC,實現 CSI 各個元件的互動。為支援 expand volume 介面,需要修改 csi.proto,在 CSI 0.2.0 的基礎上新增需要的 rpc,重點如下:
點選(此處)摺疊或開啟
-
service Controller {
-
rpc CreateVolume (CreateVolumeRequest)
-
returns (CreateVolumeResponse) {}
-
……
-
rpc RequiresFSResize (RequiresFSResizeRequest)
-
returns (RequiresFSResizeResponse) {}
-
rpc ControllerResizeVolume (ControllerResizeVolumeRequest)
-
returns (ControllerResizeVolumeResponse) {}
-
}
-
service Node { rpc NodeStageVolume (NodeStageVolumeRequest)
-
returns (NodeStageVolumeResponse) {}
-
……
-
rpc NodeResizeVolume (NodeResizeVolumeRequest)
-
returns (NodeResizeVolumeResponse) {}
- }
通過 CSI 提供的編譯功能,用新編譯出來的 csi.pb.go 替換 external-provisioner、external-attacher、csi-driver 和 kubernetes 中現有的 csi.pb.go。
Note:CSI 編譯時預設使用最新版本的 protobuf 第三方包,這可能會導致 csi.pb.go 跟 Kubernetes 中依賴的 protobuf 第三方包不相容,編譯時需要切換到統一版本。
擴充套件 CSI Plugin
在現有 CSI Plugin 基礎上,實現介面 ExpandableVolumePlugin:
點選(此處)摺疊或開啟
-
type ExpandableVolumePlugin interface {
-
VolumePlugin
-
ExpandVolumeDevice(spec *Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error)
-
RequiresFSResize() bool
- }
基於 CSI Spec 實現 Storage Driver
-
CSI Driver 實現如下所有介面:
-
CreateVolume
-
DeleteVolume
-
ControllerPublishVolume
-
ControllerUnpublishVolume
-
ValidateVolumeCapabilities
-
ListVolumes
-
GetCapacity
-
ControllerGetCapabilities
-
RequiresFSResize
-
ControllerResizeVolume
這裡涉及到比較複雜的除錯和適配工作,還有一些其他的工作:
-
定義 CSI 對應的 StorageClass,並設定 allowVolumeExpansion 為 true
-
啟用 Feature Gates:ExpandPersistentVolumes
-
新增 Admission Control:PersistentVolumeClaimResize
-
……
通過擴充套件 Container Storage Interface 0.2.0,我們在Kubernetes 1.10.2 上實現了線上擴容檔案系統擴容。對 MySQL 例項製造兩種型別工作負載:
-
通過鍵值更新和查詢
-
批量資料載入資料
-
讀數一:MySQL QPS 在正常波動範圍內;
-
讀數二:持續批量載入資料,MySQL 檔案系統容量不斷變大;
-
讀數三:在20分鐘內,線上動態擴容 Volume 和 Filesystem 2 次, 過程高效平滑。
其他
工作到這裡基本結束,要改動的地方不少,客觀上並不簡單。如果沒有 Kubernetes 和 CSI,難度會更大。
通過此方法可以完成對其他 Storage Vendor 的擴充套件,譬如 FCSan、iSCSI。
對 CSI 的展望
目前 CSI 已發展到 0.2.0,0.3.0 也釋出在即。
0.3.0 中呼聲最高的特性是 Snapshot。藉助該功能,可以實現備份和異地容災。但是為了實現該功能,在 Kubernetes 現有的 Control-Plane 上還要新增新的 Controller,客觀上,複雜度會進一步提高。同時,部分 in-tree Volume Driver 已通過 CSI 遷移到外部,考慮到 Kubernetes 整體的釋出節奏和 API 的穩定性,個人覺得節奏不會太快。
除此之外,CSI 可能還有更多工作要做。以一個高可用的場景為例,當一個 Node 發生故障時,CO 觸發 Unmount->Dettach->Attach->Mount 的流程,配合 Pod 的漂移,藉助 CSI 定義的介面,Unmount、Dettach、Attach、Mount 由SP. 自身現實,但是 Unmount->Dettach->Attach->Mount 的流程還是有 CO 控制,這個流程並不標準,但是對 workload 又至關重要。
又想起<人月神話>中的那句 “No Silver Bullet”。
相關連結:
-
https://github.com/kubernetes/kubernetes/blob/afa68cc28749c09f8655941b111e46d85689daf8/pkg/volume/plugins.go#L95
-
https://github.com/container-storage-interface/spec/blob/master/spec.md
-
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md
-
https://github.com/container-storage-interface/spec/blob/master/csi.proto
-
https://docs.google.com/document/d/1kVrNwA2f4ite8_9QvCy-JQA_00hxGGMdER3I84dUDqQ/edit?usp=sharing
| 作者簡介
熊中哲,沃趣科技產品及研發負責人
曾就職於阿里巴巴和百度,超過10年關係型資料庫工作經驗,目前致力於將雲原生技術引入到關係型資料庫服務中。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2156250/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 容器化 RDS:藉助火焰圖定位Kubernetes效能問題
- 容器儲存介面--CSI
- 3 種擴充套件 Kubernetes 能力的方式套件
- kubernetes/k8s CSI分析-容器儲存介面分析K8S
- 容器化RDS—— 計算儲存分離 or 本地儲存
- Web儲存(Web Storage)擴充套件EStorageWeb套件
- 藉助 TCP 負載均衡和 Galera 叢集擴充套件 MySQLTCP負載套件MySql
- 如何擴充套件Kubernetes API?套件API
- Kubernetes 使用 ceph-csi 消費 RBD 作為持久化儲存持久化
- 一文讀懂容器儲存介面 CSI
- 紅帽通過一致且持久的儲存擴充套件Kubernetes平臺套件
- Spring容器擴充套件機制Spring套件
- Spring IoC 容器的擴充套件Spring套件
- 利用Kubernetes實現容器的持久化儲存持久化
- Spring之藉助Redis設計訪問計數器之擴充套件篇SpringRedis套件
- SAP:檢索幫助擴充套件套件
- 自建Kubernetes叢集如何使用阿里雲CSI儲存元件阿里元件
- 雲資料庫RDS儲存能力進化解析!資料庫
- 沃趣微講堂 | 深入淺出Kubernetes儲存(四):儲存新方向-CSI
- SpringCloudGateway資料庫儲存路由資訊的擴充套件方案SpringGCCloudGateway資料庫路由套件
- 如何自動擴充套件K8S儲存池容量?套件K8S
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- oracle 新增儲存自動擴充套件資料檔案流程(auto)Oracle套件
- 使用aggregation API擴充套件你的kubernetes APIAPI套件
- 深入理解Spring IOC容器及擴充套件Spring套件
- Spring Cloud Gateway 資料庫儲存路由資訊的擴充套件方案SpringCloudGateway資料庫路由套件
- 如何搭建一個高可用、高擴充套件的圖片儲存功能套件
- Kubernetes可擴充套件Admission進入Beta階段套件
- Kubernetes Extended Resource 擴充套件資源使用簡介套件
- 如何藉助分散式儲存 JuiceFS 加速 AI 模型訓練分散式UIAI模型
- windows右鍵選單擴充套件容器[開源]Windows套件
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- 細述Kubernetes和Docker容器的儲存方式Docker
- Apache Cassandra——可擴充套件微服務應用程式的持久資料儲存Apache套件微服務
- 使用Harbor作為Rainbond預設容器映象倉庫,擴充套件Rainbond映象管理能力AI套件
- (三)Kubernetes---持久化儲存持久化
- 使用KEDA和Kafka在 Kubernetes 上自動擴充套件 - PiotrKafka套件
- 使用 Kubernetes 擴充套件專用遊戲伺服器套件遊戲伺服器