一、背景
RocketMQ无论采用Master/Slave的主从模式,还是采用Dledger的多副本模式,均能保证RocketMQ集群的高可用性,但在一些极端场景下,例如机房断电、机房火灾、地震等不可抗拒因素使得该IDC可用区的RocketMQ集群无法正常对外提供消息服务能力。因此,为了增强抗风险能力,消息队列RocketMQ集群多活异地容灾极为重要。
二、物理部署异地容灾方案
图2-1 物理部署异地容灾方案图
移动云部署的RocketMQ采用的Master/Slave的主从模式,其中物理部署异地容灾的方案包括以下几部分:
(1) NameServer组件作为轻量级注册中心,无状态,负责更新和发现 Broker服务Namesrv之间相互没有通信,单台Namesrv宕机不影响其他Namesrv节点与集群的功能,两台Namesrv部署在不同的可用区,当一个可用区故障,另外一个可用区的Namesrv依然能对外提供服务。
(2) Broker组件作为消息中转角色,负责存储消息,转发消息,采用Master/Slave部署模式,在两个可用区上交叉部署(如broker-a的Master部署在可用区1上,Slave节点部署在可用区2上,broker-b的Master部署在可用区2上,Slave节点部署在可用区1上),消息发送到Master节点后会实时同步到Slave节点,保证每个可用区保存了全量的消息。当单个可用区故障也会对外提供消息的读写能力。
三、云化版本异地容灾单集群方案
针对物理机部署RocketMQ运维、迁移、扩缩容费时费力,操作复杂;业务增加以后,资源无法弹性,手动扩缩容实时性差;底层资源利用率不高,用户资源隔离和流量的管控需要额外投入等问题。可以借助K8S Operator,Operator 的工作原理,实际上是利用了 Kubernetes 的自定义 API 资源(如使用CRD,CustomResourceDefinition),来描述想要部署的应用;然后在自定义控制器里,根据自定义 API 对象的变化,来完成具体的部署和运维工作,实现Operator主要关键是 CRD(自定义资源)和 Controller(控制器)的设计。
图3-1 Operator原理图
自研了RocketMQ Operator实现集群的秒级部署,扩缩容,规格变更等一些列常见的运维操作,进而解决在物理部署所带来的难题。下图是RocketMQ Operator设计实现:
图3-2 RocketMQ Operator架构图
该方案使用三个异地可用区部署一个K8S集群,每个可用区部署一个master节点,图中的Broker是两主两从高可用方案,采用交叉部署,namesrv每个可用区部署一个实例。
图3-3 云化异地容灾单集群方案
这个方案存在几个问题:大规模单K8S集群出现故障时可能会对整个集群产生影响,且组件升级难、风险大;随着业务增加,核心组件压力增大,性能下降;单一集群的建设可能受限于特定的地理位置和前期规划,缺乏灵活性。
四、云化版本异地容灾集群联邦方案
针对上述方案的缺点,消息队列RocketMQ云化版本多可用区的现阶段优化为如下方案:
图4-1 云化异地容灾多联邦集群方案
K8S集群采用云原生Kosmos进行多个集群联邦,不在单纯依赖单个K8S集群,RocketMQ服务资源通过Kosmos CluterTree同步联邦集群间的svc,pod等资源 ,联邦集群间的网络由Kosmos ClusterLink打通。
五、Kosmos简介
Kosmos是移动云的分布式云原生联邦集群技术集合,于2023年8月开源,项目地址:https://github.com/kosmos-io/kosmos。Kosmos包含多集群网络工具ClusterLink、跨集群编排工具ClusterTree等:
图5-1 Kosmos模块和组件
ClusterLink的作用是打通多个Kubernetes集群之间的网络,在CNI上层实现,用户无需卸载或重启已经安装的CNI插件,且不会对正在运行的pod产生影响。ClusterLink的主要功能如下:
✓ 提供跨集群PodIP、ServiceIP互访能力
✓ 提供P2P、Gateway多种网络模式
✓ 支持全局IP分配
✓ 支持IPv4、IPv6双栈
ClusterTree的作用是实现Kubernetes的树形扩展和应用的跨集群编排。ClusterTree本质是一组控制器,用户可以像使用单集群那样直接与控制面kube-apiserver进行交互,不需要额外的代码改造。目前,ClusterTree包含的主要功能如下:
✓提供创建跨集群应用能力
✓兼容k8s api,用户零改造
✓支持有状态应用
✓支持k8s-native(需要访问kube-apiserver的)应用
除此之外,Kosmos还提供一些辅助工具,其中,kosmos-operator简化了Kosmos部署。Kosmosctl是一款命令行工具,为用户提供网络连通性测试、集群纳管、Kosmos部署安装等功能。
六、Kosmos多集群网络ClusterLink
(一)ClusterLink工作流程和原理
ClusterLink基于linux隧道技术打通跨集群网络,隧道类型是可配置的,例如:VxLAN或IPSec。ClusterLink包含Network-Manager、Agent等多个组件,如下图所示浅蓝色部分。各个组件相互协作完成隧道、路由表、fdb等网络配置。
图 6-1 ClusterLink架构
其工作流程如下:
- 首先,位于各个子集群的Controller-Manager组件负责收集集群信息,如:podCIDR、serviceCIDR、node信息等,这些信息在不同的CNI插件下会保存在不同位置,因此Controller-Manager包含一些插件来适配CNI。收集的集群信息会保存在两个自定义资源:Cluster、ClusterNode中。
- 然后,Network-Manager组件监听到这两个CR的变化,实时计算各个节点所需的网络配置,如:网卡信息、路由表、iptables、arp等等。对应节点的网络配置信息保存在NodeConfig自定义资源对象中。
- 接下来,作为网络配置的具体实施者,agent,一个daemonset,负责读取对应节点的网络配置,进行底层网络配置。待网络配置完成后,pod即可通过podIP、serviceIP进行跨集群访问。
(二)ClusterLink网络模式介绍
图 6-2 ClusterLink网络模式
目前,ClusterLink包含两种网络模式:Gateway和P2P。在Gateway模式中,数据包由左侧pod发出后,先经由集群内隧道vx-local到达该集群gateway节点。然后再走跨集群隧道到达对端集群。数据包到达对端集群后,交由CNI处理,走单集群网络到达目标pod。该模式有利有弊,其优势在于每个集群只需要1个节点(考虑HA时需要2个)提供对外访问即可,适用于跨云混合云场景。缺点是因为网络路径较长,有一定的性能损耗。针对此问题,ClusterLink提供P2P模式,对网络性能要求较高的场景可以使用此模式。在该模式下,数据包的控制粒度更细,会直接发往对端pod所在节点。此外,P2P和Gateway两种模式支持混合使用。
七、Kosmos跨集群编排ClusterTree
(一)ClusterTree 组件和原理介绍
ClusterTree实现了Kubernetes的树形扩展和应用的跨集群编排,用户可以像使用单集群那样访问root kube-apiserver。Leaf集群作为节点添加在root集群中,用户可以使用k8s原生的方式控制pod分布,例如:labelSelector、亲和/反亲和、污点和容忍、拓扑分布约束等。
图 7-1 ClusterTree 架构
ClusterTree其本质是一组控制器,各个控制器的作用如下:
- node-controller:节点资源计算;节点状态维护;节点lease更新
- pod-controller:监听root集群pod创建,调用leaf集群kube-apiserver进行pod创建;维护pod状态;环境变量转换;权限注入
- storagecopy-controller:pv/pvc资源同步和状态管理
- mcs-controller:service资源同步和状态管理
(二)ClusterTree 高可用介绍
当出现AZ级故障,或者AZ之间网络中断,确保用户正常访问RocketMQ集群实例是非常重要的。如上图所示,为了应对A处网络断开或者控制面故障,ClusterTree实现了service和endpoint资源的同步,让用户访问流量直接从子集群走,解耦了管理和业务,也缩短了网络路径。RocketMQ的nameserver pod是跨集群分布,当B处网络断开或者某个AZ故障,会导致用户有50%概率访问失败的nsv pod。针对此问题,ClusterTree的eps-probe插件会周期对跨集群ep进行探测,并移除失效endpoint。
图 7-2 RocketMQ跨AZ高可用
八、Kosmos 集群负载和网络性能测试
ClusterTree能管理多少节点和pod?ClusterLink较单集群网络的性能如何?这些都是用户非常关注的问题,对此我们也做了相应的测试。
(一)集群负载测试
- ClusterLoader2ClusterLoader2 能够针对Kubernetes 定义的SLIs/SLOs 指标进行测试,检验集群是否符合各项服务质量标准。ClusterLoader2 最终会输出一份Kubernetes集群性能报告,展示一系列性能指标测试结果。https://github.com/kubernetes/perf-tests/tree/master/clusterloader2
- Kwok道客开源项目,用于快速模拟大规模集群。https://github.com/kubernetes-sigs/kwok
图 8-1 集群负载测试-测试方法
如图所示,我们首先通过kwok创建了20个大规模集群,每个集群包含5000个节点,我们将这些集群使用Kosmos进行纳管。接下来,使用clusterloader2 连接控制面kube-apiserver进行集群负载测试,其关键测试参数如图所示。
图 8-2 集群负载测试-测试结果
使用kosmos管理k8s集群联邦,在 100,000 节点和 200,000 pod场景下,达到官方SLOs标准,并且该规模并未达到kosmos上限。
(二)网络性能测试
图 8-3 网络性能测试-测试方法
图片