移動云RocketMQ云原生消息隊列2.0的彈性存儲層的設計與實踐
作者|王維,中國移動云能力中心IaaS產(chǎn)品部rpc產(chǎn)品組研發(fā)工程師,主要負責消息隊列云原生方向的設計與研發(fā)工作
胡宗棠,中國移動云能力中心laaS產(chǎn)品部消息隊列&rpc團隊的負責人,主要負責消息隊列、rpc、配置管理等云原生中間件的架構設計與技術研發(fā)工作
1.背景介紹
移動云RocketMQ消息隊列產(chǎn)品線,基于kubernetes組件和自定義Operator,在完成全面云原生化后,增加諸多云原生特性,比如一鍵化部署集群、極致彈性擴縮容和業(yè)務無感知熱升級/熱遷移等。同時,云原生化升級也導致RocketMQ面臨多項挑戰(zhàn):
- RocketMQ的Broker Pod節(jié)點是有狀態(tài)的服務,在Broker Pod漂移后如何保證寫入本地磁盤的消息數(shù)據(jù)同步遷移;
- 基于(1)的問題,在移動云RocketMQ云原生消息隊列 1.0的架構中,我們采用了Ceph/GlusterFS存儲方案來解決該問題。但該方案帶來的問題是:外部存儲系統(tǒng)的引入,不僅增加了部署/運維的人力成本,而且使得消息隊列服務架構復雜化;
- RocketMQ消息隊列集群的吞吐量受限于磁盤IO讀寫速率,相較于直接采用宿主機磁盤存儲,引入Ceph/GlusterFS或者其他第三方存儲系統(tǒng)會直接影響RocketMQ的性能;
基于上述問題,RocketMQ研發(fā)團隊在移動云RocketMQ云原生消息隊列2.0的架構設計中,基于“CSI + LVM”云原生容器存儲技術,結合自研的Operator組件,在RocketMQ消息隊列具備極致彈性擴縮等云原生特性的同時,能夠承載萬億級數(shù)據(jù)洪峰,為移動云上客戶的業(yè)務系統(tǒng)提供低延遲、高并發(fā)、高可靠的分布式消息隊列云服務。
2.概念概述
1.CSI
CSI[1](Container Storage Interface )即容器存儲接口,是Kubernetes 目前主推的存儲擴展方式。該方式為容器編排系統(tǒng)定義了標準的接口,使得開發(fā)者可以更靈活方便的將第三方存儲系統(tǒng)與容器工作負載集成。
開發(fā)者通過實現(xiàn)CSI 規(guī)定的RPC接口(CSI Identity、CSI Controller、CSI Node),即下圖中Custom Components部分,協(xié)同社區(qū)提供的輔助Sidecar容器(External Components),與Kubernetes 核心組件進行交互,從而實現(xiàn)對自定義容器存儲的管理。
(圖片出處 [2])
External Components 是一系列由社區(qū)Storage sig小組維護的輔助容器,主要包括如下:
?External-provisioner
用于實現(xiàn)持久卷(PersistentVolume)的創(chuàng)建、刪除等功能
External-attacher
用于實現(xiàn)持久卷的附著、分離功能
External-snapshotter
用于實現(xiàn)持久卷快照、備份恢復功能
External-resizer
用于實現(xiàn)持久卷的擴容縮容功能
Node-driver-registrar
使用kubelet插件機制向所在節(jié)點的kubelet注冊用戶開發(fā)的CSI 驅動信息
Livenessprobe
用于輔助用戶CSI插件實現(xiàn)健康檢查功能?
這些不同功能的Sidecar容器,由開發(fā)者根據(jù)自己實際需要選擇使用。更詳細的使用可以查看官方文檔[3]
Custom Components 需要開發(fā)者自己實現(xiàn),由三組RPC接口集合組成,來實現(xiàn)對存儲卷整個生命周期的管理。
Identity Service負責對外暴露插件信息,開發(fā)者實現(xiàn)的存儲插件必須實現(xiàn)該操作集,其中GetPluginCapabilities 根據(jù)用戶實際實現(xiàn)的RPC操作返回對應的集合。
Controller Service包含一些卷的創(chuàng)建,刪除、快照等操作。同樣的,用戶可以根據(jù)實際需要的功能選擇性實現(xiàn)接口。實現(xiàn)Controller Service的插件可以根據(jù)自身實際需要選擇不同的部署方式,通常會使用Deployment 部署單個或少量節(jié)點。
Node Service包含一些節(jié)點管理的接口。其負責需要和宿主機打交道的操作,例如掛載卸載存儲卷等操作,通常會以DaemonSet的方式部署。
2.LVM
LVM (Logical Volume Manager)即邏輯卷管理器,通過將多個物理分區(qū)/硬盤從邏輯上組合成一個更大的虛擬硬盤,從而實現(xiàn)對硬盤容量的彈性管理。
(圖片出處 [4])
以下是LVM中的幾個概念
PV 物理卷(Physical Volume)
通常對應一個普通分區(qū)或硬盤;
VG 卷組(Volume Group)
由若干個物理卷組成,卷組可以動態(tài)添加或者移除物理卷;
PE 物理擴展塊(Physical Extend)
PE是LVM的最小存儲單位,類似文件系統(tǒng)block;
LV 邏輯卷(Logical Volume)
從卷組中分割出部分空間,形成邏輯卷。用戶格式化后掛載文件系統(tǒng)使用;
如下以一個實際使用例子列舉部分命令
序號 | LVM存儲操作命令 | 說明 |
1 | pvcreate /dev/sdb /dev/sdc | 創(chuàng)建物理卷 |
2 | vgcreate vg1 /dev/sdb /dev/sdc | 創(chuàng)建卷組 |
3 | lvcreate -L 2G -n lv1 vg1 | 創(chuàng)建邏輯卷 |
4 | mkfs -t xfs /dev/vg1/lv1 | 格式化邏輯卷 |
5 | mount /mount/test /dev/vg1/lv1 | 掛載使用卷 |
6 | lvextend -L +2G /dev/vg1/lv1 | 邏輯卷擴容 |
借助LVM,用戶可以根據(jù)實際業(yè)務需求申請邏輯卷,之后同樣也可以按需進行擴/縮容,從而可以實現(xiàn)用戶對磁盤空間的按需申請、擴容縮容等需求。
3.基于“CSI+LVM”的RocketMQ消息隊列容器存儲層設計
通過實現(xiàn)CSI規(guī)范,同時借助LVM的能力,即可利用宿主機本地磁盤構建出一個簡單的容器存儲驅動,實現(xiàn)動態(tài)創(chuàng)建卷、對卷的擴縮容等功能。此外,為解決Broker Pod漂移帶來的問題,我們在創(chuàng)建PV時添加親和性,使其綁定原來的Node,由于RocketMQ消息隊列集群本身就是采用分布式高可用架構。所以,在某些場景中,屏蔽一定的Pod漂移能力,并不會給RocketMQ消息隊列的高可用帶來什么影響。
上圖展示了移動云消息隊列存儲部分的架構,其中藍色部分是由我們實現(xiàn)的CSI插件部分
RocketMQ Operator
遵循Kubernetes 的資源和控制器理念,通過拓展RocketMQ相關資源(CRD),以實現(xiàn)對RocketMQ集群生命周期的管理。
LVolume
用于整個流程管理存儲的自定義資源對象(CRD)。
CSI-Controller-Plugin
主要實現(xiàn)了CreateVolume、DeleteVolume、ControllerExpandVolume接口,負責LVolume的創(chuàng)建等。
CSI-Node-Plugin
主要實現(xiàn)了NodePublishVolume、NodeUnpublishVolume、NodeExpandVolume操作,內(nèi)部通過調(diào)用LVM命令管理LV(邏輯卷)、PV(物理卷)、VG(卷組)資源,通過使用Cgroup 限制卷讀寫速率。
下面介紹下主要創(chuàng)建流程:
- 用戶發(fā)起創(chuàng)建消息隊列后會由RocketMQ Operator創(chuàng)建需要的Kubernetes 資源,其中包括指定StorageClassName的PVC、Pod資源;
- KubeScheduler調(diào)度PVC到指定節(jié)點后進入到Provision階段;
- 0Sidecar容器 External-provisioner監(jiān)聽到PVC后調(diào)用同Pod中的ControllerPugin的CreateVolume接口;
- ControllerPlugin收到CreateVolume進行一些驗證后,創(chuàng)建LVolume對象,用于記錄需要創(chuàng)建的卷信息,而后返回成功給External-provisioner;
- External-provisioner根據(jù)返回結果創(chuàng)建PV對象,添加節(jié)點親和性,并和PVC進行綁定;
- 由于我們不需要對卷Attach,故通過設置CSIDriver的AttachRequired屬性為false跳過Attach階段,而后kubeScheduler調(diào)度Pod到指定節(jié)點后進入mount階段;
- Kubelet監(jiān)聽到綁定到自身節(jié)點的Pod后調(diào)用NodePlugin的NodePublishVolume接口;
- NodePlugin收到NodePublishVolume請求后通過調(diào)用lvm命令創(chuàng)建邏輯卷,并將卷mount到Pod的指定目錄;
- 而后NodePlugin根據(jù)LVolume中的相關信息設置Cgroup限制磁盤讀寫IO速率;
- 至此主要流程結束;
4.總結
本文介紹了基于“CSI + LVM”云原生容器存儲技術及RocketMQ消息隊列在容器存儲上的設計與實踐,其中實現(xiàn)了基于“CSI +LVM”的容器存儲,支持本地卷的動態(tài)創(chuàng)建、動態(tài)擴縮容、磁盤IO速率限制、拓撲支持等基本功能,同時為移動云云原生消息中間件提供了一種采用本地卷作為容器存儲方式。
引用鏈接
1.CSI規(guī)范https://github.com/container-storage-interface/spec
2.CSI圖片出處https://kingjcy.github.io/post/cloud/paas/base/kubernetes/k8s-store-csi/
3.CS文檔https://kubernetes-csi.github.io/docs/introduction.html
4.LVM圖片出處https://www.cnblogs.com/fzhelpdesk/p/16189915.html