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