使用 Kubernetes 部署高可用 RocketMQ 集群

一、介绍

RocketMQ是一款阿里巴巴开源的消息中间件,在2017年9月份成为Apache的顶级项目,是国内首个互联网中间件在 Apache 上的顶级项目。

RocketMQ的起源受到另一款消息中间件Kafka的启发。最初,淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容。

RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等。

1.1 RocketMQ 特点

  • 支持发布/订阅(Pub/Sub)和点对点(P2P)消息模型

  • 在一个队列中可靠的先进先出(FIFO)和严格的顺序传递 (RocketMQ可以保证严格的消息顺序,而ActiveMQ无法保证)

  • 支持拉(pull)和推(push)两种消息模式

  • pull其实就是消费者主动从MQ中去拉消息,而push则像rabbit MQ一样,是MQ给消费者推送消息。但是RocketMQ的push其实是基于pull来实现的。
    它会先由一个业务代码从MQ中pull消息,然后再由业务代码push给特定的应用/消费者。其实底层就是一个pull模式

  • 单一队列百万消息的堆积能力 (RocketMQ提供亿级消息的堆积能力,这不是重点,重点是堆积了亿级的消息后,依然保持写入低延迟)

  • 支持多种消息协议,如 JMS、MQTT 等

  • 分布式高可用的部署架构,满足至少一次消息传递语义(RocketMQ原生就是支持分布式的,而ActiveMQ原生存在单点性)

  • 提供 docker 镜像用于隔离测试和云集群部署

  • 提供配置、指标和监控等功能丰富的 Dashboard

1.2 RocketMQ 优势

目前主流的 MQ 主要是 RocketMQ、kafka、RabbitMQ,其主要优势有:

  • 支持事务型消息(消息发送和 DB 操作保持两方的最终一致性,RabbitMQ 和 Kafka 不支持)
  • 支持结合 RocketMQ 的多个系统之间数据最终一致性(多方事务,二方事务是前提)
  • 支持 18 个级别的延迟消息(Kafka 不支持)
  • 支持指定次数和时间间隔的失败消息重发(Kafka 不支持,RabbitMQ 需要手动确认)
  • 支持 Consumer 端 Tag 过滤,减少不必要的网络传输(即过滤由MQ完成,而不是由消费者完成。RabbitMQ 和 Kafka 不支持)
  • 支持重复消费(RabbitMQ 不支持,Kafka 支持)

1.3 RocketMQ 基本概念

RocketMQ主要有四大核心组成部分:NameServer、Broker、Producer以及Consumer四部分。

1.3.1 Name Server

Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。

NameServer 是整个 RocketMQ 的“大脑” ,它是 RocketMQ 的服务注册中心,所以 RocketMQ 需要先启动 NameServer 再启动 Rocket 中的 Broker。

1.3.2 Broker

消息服务器(Broker)是消息存储中心,主要作用是接收来自 Producer 的消息并存储,Consumer 从这里取得消息。它还存储与消息相关的元数据,包括用户组、消费进度偏移量、队列信息等。从部署结构图中可以看出 Broker 有 Master 和 Slave 两种类型,Master 既可以写又可以读,Slave不可以写只可以读。

1.4 部署方式

Spring Cloud Alibaba 全家桶之 RocketMQ 是一款典型的分布式架构下的消息中间件产品,使用异步通信方式和发布订阅的消息传输模型。

很多基于 Spring Cloud 开发的项目都喜欢采用 RocketMQ 作为消息中间件。

RocketMQ 常用的部署模式如下:

  • 单 Master 模式
  • 多 Master 无 Slave 模式
  • 多 Master 多 Slave 模式-异步复制
  • 多 Master 多 Slave 模式-同步双写

1.4.1 单 Master 模式

这种部署方式风险较大,仅部署一个 NameServer 和一个 Broker,一旦 Broker 重启或者宕机时,会导致整个服务不可用,不建议线上生产环境使用,仅可以用于开发和测试环境。

部署方案参考官方rocketmq-docker项目中使用的容器化部署方案涉及的镜像、启动方式、定制化配置。

1.4.2 多 Master 多 Slave-异步复制模式

每个 Master 配置一个 Slave,有多对 Master-Slave,HA 采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:

  • 优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时 Master 宕机后,消费者仍然可以从 Slave 消费,而且此过程对应用透明,不需要人工干预,性能同多 Master 模式几乎一样;
  • 缺点:Master 宕机,磁盘损坏情况下会丢失少量消息。

更多的部署方案详细信息可以参考官方文档

多 Master 多 Slave-异步复制模式适用于生产环境,部署方案采用官方提供的 RocketMQ Operator

这边主要介绍 多 Master 多 Slave-异步复制模式在 K8s 集群上的部署方案。

二、离线镜像制作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1、登入远程仓库
docker login --username=xxx 远程仓库地址 回车输入密码

# 2、下载镜像
# docker pull apacherocketmq/rocketmq-operator:0.3.0-snapshot
docker pull apache/rocketmq-operator:0.3.0
docker pull apacherocketmq/rocketmq-console:2.0.0
docker pull apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker pull apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

# 3、重新打 tag
docker tag apache/rocketmq-operator:0.3.0 自己的仓库地址/apacherocketmq/rocketmq-operator:0.3.0
docker tag apacherocketmq/rocketmq-console:2.0.0 自己的仓库地址/apacherocketmq/rocketmq-console:2.0.0
docker tag apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0 自己的仓库地址/apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker tag apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0 自己的仓库地址/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

# 4、推送到私有镜像仓库
docker push 自己的仓库地址/apacherocketmq/rocketmq-operator:0.3.0
docker push 自己的仓库地址/apacherocketmq/rocketmq-console:2.0.0
docker push 自己的仓库地址/apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker push 自己的仓库地址/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

# 5、清理临时镜像
docker rmi apache/rocketmq-operator:0.3.0
docker rmi apacherocketmq/rocketmq-console:2.0.0
docker rmi apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker rmi apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

docker rmi 自己的仓库地址/apacherocketmq/rocketmq-operator:0.3.0
docker rmi 自己的仓库地址/apacherocketmq/rocketmq-console:2.0.0
docker rmi 自己的仓库地址/apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0
docker rmi 自己的仓库地址/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0

三、思路梳理

多 Master 多 Slave-异步复制模式的 RocketMQ 部署,使用官方提供的 RocketMQ Operator,部署起来比较快速便捷,扩容也比较方便。

默认配置会部署 1 个 Master 和 1 个对应的 Slave,部署完成后可以根据需求扩容 Master 和 Slave。

四、准备资源配置清单

获取 RocketMQ Operator

1
2
3
# git 获取代码时指定版本
cd /srv
git clone -b 0.3.0 https://github.com/apache/rocketmq-operator.git

本文演示的资源配置清单都是直接修改 rocketmq-operator 默认的配置,生产环境应根据默认配置修改一套适合自己环境的标准配置文件,并存放于 git 仓库中。

4.1、为 deploy 资源配置清单文件增加或修改命名空间:

1
2
3
4
5
6
7
8
9
10
cd /srv/rocketmq-operator
sed -i 'N;8 a \ namespace: devops' deploy/crds/rocketmq.apache.org_brokers.yaml
sed -i 'N;8 a \ namespace: devops' deploy/crds/rocketmq.apache.org_consoles.yaml
sed -i 'N;8 a \ namespace: devops' deploy/crds/rocketmq.apache.org_nameservices.yaml
sed -i 'N;8 a \ namespace: devops' deploy/crds/rocketmq.apache.org_topictransfers.yaml
sed -i 'N;18 a \ namespace: devops' deploy/operator.yaml
sed -i 'N;18 a \ namespace: devops' deploy/role_binding.yaml
sed -i 's/namespace: default/namespace: devops/g' deploy/role_binding.yaml
sed -i 'N;18 a \ namespace: devops' deploy/service_account.yaml
sed -i 'N;20 a \ namespace: devops' deploy/role.yaml

切记此步骤只能执行一次,如果失败了则需要删掉后重新执行。
执行完成后一定要查看一下结果是否符合预期 grep -r devops deploy/*。

4.2、修改 example 资源配置清单文件中的命名空间

1
2
sed -i 's/namespace: default/namespace: devops/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml
sed -i 'N;18 a \ namespace: devops' example/rocketmq_v1alpha1_cluster_service.yaml

4.3、修改镜像地址为内网地址:

1
2
3
4
5
6
7
8
sed -i 's#apache/rocketmq-operator:0.3.0#自己的仓库地址/apacherocketmq/rocketmq-operator:0.3.0#g' deploy/operator.yaml
sed -i 's#apacherocketmq#自己的仓库地址/apacherocketmq#g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

这边有好几个镜像地址要改,看下配置文件,修改下。

# 如果仓库有密码记得添加key
imagePullSecrets:
- name: testregistrysecret

4.4、修改 RocketMQ 版本 (可选):

1
sed -i 's/4.5.0/4.9.4/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml 

Notice: 默认的资源配置清单示例中部署 RocketMQ 集群的版本为 4.5.0, 实际使用时请根据需求调整。要去docker hub查下。

4.5、修改 NameService 网络模式 (可选):

1
2
3
sed -i 's/hostNetwork: true/hostNetwork: false/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml 
sed -i 's/dnsPolicy: ClusterFirstWithHostNet/dnsPolicy: ClusterFirst/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

在k8s中,有4种DNS策略,分别是 ClusterFirstWithHostNet 、ClusterFirst 、Default 、和 None,这些策略可以通过 dnsPolicy 这个字段来定义

如果在初始化 Pod、Deployment 或者 RC 等资源时没有定义,则会默认使用 ClusterFirst 策略

  • ClusterFirstWithHostNet

    当一个 Pod 以 HOST 模式(和宿主机共享网络,hostNetwork: true)启动时,这个 POD 中的所有容器都会使用宿主机的 /etc/resolv.conf 配置进行 DNS 查询,但是如果在 Pod 中仍然还想继续使用 k8s 集群 的 DNS 服务时,就需要将 dnsPolicy 设置为 ClusterFirstWithHostNet。

  • ClusterFirst

    使用这种方式表示 Pod 内的 DNS 优先会使用 k8s 集群内的 DNS 服务,也就是会使用 kubedns 或者 coredns 进行域名解析。如果解析不成功,才会使用宿主机的 DNS 配置进行解析。

  • Default

    这种方式,会让 kubelet 来决定 Pod 内的 DNS 使用哪种 DNS 策略。kubelet 的默认方式,其实就是使用宿主机的 /etc/resolv.conf 来进行解析。你可以通过设置 kubelet 的启动参数, –resolv-conf=/etc/resolv.conf 来决定该 DNS 服务使用的解析文件的地址
    当我们部署集群 DNS 服务的时候,一般就需要将 dnsPolicy 设置成 Default,而并非使用默认值 ClusterFirst,否则该 DNS 服务的上游解析地址会变成它自身的 Service 的 ClusterIP(我解析我自己),导致域名无法解析

  • None

    这种方式顾名思义,不会使用集群和宿主机的 DNS 策略。而是和 dnsConfig 配合一起使用,来自定义 DNS 配置,否则在提交修改时报错。

4.6、修改 storageClassName 为 glusterfs或者nfs:

1
2
3
4
# 有2处
sed -i 's/storageClassName: rocketmq-storage/storageClassName: 业务存储名字/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

sed -i 's/storageMode: EmptyDir/storageMode: StorageClass/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

4.7、修改 nameServers 为域名的形式:

1
2
# 有两处
sed -i 's/nameServers: ""/nameServers: "name-server-service.devops:9876"/g' example/rocketmq_v1alpha1_rocketmq_cluster.yaml

Notice: name-server-service.devops 是 NameServer service 名称 + 项目名称的组合
默认配置采用 pod [ip:port] 的形式 , 一旦 Pod IP 发生变化 ,Console 就没法管理集群了 , 且 Console 不会自动变更配置,如果设置为空的话可能还会出现随便配置的情况,因此一定要提前修改。

4.8、修改 RocketMQ NameServer 和 Console 的 service 配置:

1
2
3
4
sed -i '32,46s/^#//g' example/rocketmq_v1alpha1_cluster_service.yaml
sed -i 's/nodePort: 30000/nodePort: 31080/g' example/rocketmq_v1alpha1_cluster_service.yaml
sed -i 's/nodePort: 30001/nodePort: 31081/g' example/rocketmq_v1alpha1_cluster_service.yaml
sed -i 's/namespace: default/namespace: devops/g' example/rocketmq_v1alpha1_cluster_service.yaml

NameServer 默认使用了 NodePort 的形式,单纯在 K8S 集群内部使用的话,可以修改为集群模式。

其他参数也可以根据自己的业务需求需要,比如存储大小,默认是8G

五、部署 RocketMQ Operator (手动)

部署 RocketMQ Operator:

1
2
3
4
5
6
7
8
kubectl create -f deploy/crds/rocketmq.apache.org_brokers.yaml
kubectl create -f deploy/crds/rocketmq.apache.org_nameservices.yaml
kubectl create -f deploy/crds/rocketmq.apache.org_consoles.yaml
kubectl create -f deploy/crds/rocketmq.apache.org_topictransfers.yaml
kubectl create -f deploy/service_account.yaml
kubectl create -f deploy/role.yaml
kubectl create -f deploy/role_binding.yaml
kubectl create -f deploy/operator.yaml

验证 CRDS:

1
2
3
4
5
6
$ kubectl get crd | grep rocketmq.apache.org

brokers.rocketmq.apache.org 2022-11-09T02:54:52Z
consoles.rocketmq.apache.org 2022-11-09T02:54:54Z
nameservices.rocketmq.apache.org 2022-11-09T02:54:53Z
topictransfers.rocketmq.apache.org 2022-11-09T02:54:54Z

验证 RocketMQ Operator:

1
2
3
4
5
6
7
8
9
$ kubectl get deploy -n devops -o wide

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
rocketmq-operator 1/1 1 1 6m46s manager registry.devops.com.cn/apacherocketmq/rocketmq-operator:0.3.0 name=rocketmq-operator

$ kubectl get pods -n devops -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rocketmq-operator-7cc6b48796-htpk8 1/1 Running 0 2m28s 10.233.116.70 ks-k8s-master-2 <none> <none>

部署 RocketMQ 集群

创建服务:

1
2
3
4
$ kubectl apply -f example/rocketmq_v1alpha1_cluster_service.yaml

service/console-service created
service/name-server-service created

创建集群:

1
2
3
4
5
6
$ kubectl apply -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml

configmap/broker-config created
broker.rocketmq.apache.org/broker created
nameservice.rocketmq.apache.org/name-service created
console.rocketmq.apache.org/console created

验证

StatefulSet:

1
2
3
4
5
6
$ kubectl get sts -o wide -n devops

NAME READY AGE CONTAINERS IMAGES
broker-0-master 1/1 27s broker registry.devops.com.cn/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0
broker-0-replica-1 1/1 27s broker registry.devops.com.cn/apacherocketmq/rocketmq-broker:4.5.0-alpine-operator-0.3.0
name-service 1/1 27s name-service registry.devops.com.cn/apacherocketmq/rocketmq-nameserver:4.5.0-alpine-operator-0.3.0

Deployment:

1
2
3
4
5
$ kubectl get deploy -o wide -n devops

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
console 1/1 1 1 52s console registry.devops.com.cn/apacherocketmq/rocketmq-console:2.0.0 app=rocketmq-console
rocketmq-operator 1/1 1 1 4h43m manager registry.devops.com.cn/apacherocketmq/rocketmq-operator:0.3.0 name=rocketmq-operator

Pod:

1
2
3
4
5
6
7
8
$ kubectl get pods -o wide -n devops

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
broker-0-master-0 1/1 Running 0 47s 10.233.87.24 ks-k8s-master-1 <none> <none>
broker-0-replica-1-0 1/1 Running 0 17s 10.233.117.28 ks-k8s-master-0 <none> <none>
console-8d685798f-5pwct 1/1 Running 0 116s 10.233.116.84 ks-k8s-master-2 <none> <none>
name-service-0 1/1 Running 0 96s 10.233.116.85 ks-k8s-master-2 <none> <none>
rocketmq-operator-7cc6b48796-htpk8 1/1 Running 2 (98s ago) 4h39m 10.233.116.70 ks-k8s-master-2 <none> <none>

Services:

1
2
3
4
5
$ kubectl get svc -o wide -n devops

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
console-service NodePort 10.233.38.15 <none> 8080:31080/TCP 21m app=rocketmq-console
name-server-service NodePort 10.233.56.238 <none> 9876:31081/TCP 21m name_service_cr=name-service

通过浏览器打开 K8S 集群中任意节点的 IP:31080,可以看到 RocketMQ 控制台的管理界面。

六、扩容 NameServer (一般够用,正常不去扩容)

如果当前的 name service 集群规模不能满足您的需求,您可以简单地使用 RocketMQ-Operator 来扩大或缩小 name service 集群的规模。(或者一开始部署的时候就部署2个)

扩容 name service 需要编写并执行独立的资源配置清单,参考官方示例Name Server Cluster Scale,并结合自己实际环境的 rocketmq-operator 配置修改。

Notice: 不要在已部署的资源中直接修改副本数,直接修改不会生效,会被 Operator 干掉。

编辑扩容 NameServer 资源配置清单 , rocketmq_v1alpha1_nameservice_cr.yaml:

1
修改参数,这边没去验证,就先跳过。

执行扩容操作:

1
kubectl apply -f rocketmq/cluster/rocketmq_v1alpha1_nameservice_cr.yaml

验证 StatefulSet:

1
2
3
4
$ kubectl get sts name-service -o wide -n zdevops

NAME READY AGE CONTAINERS IMAGES
name-service 2/2 16m name-service registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0

验证 Pods:

1
2
3
4
5
6
7
8
9
$ kubectl get pods -o wide -n zdevops

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
broker-0-master-0 1/1 Running 0 18m 10.233.87.117 ks-k8s-master-1 <none> <none>
broker-0-replica-1-0 1/1 Running 0 43s 10.233.117.99 ks-k8s-master-0 <none> <none>
console-8d685798f-hnmvg 1/1 Running 0 18m 10.233.116.113 ks-k8s-master-2 <none> <none>
name-service-0 1/1 Running 0 18m 10.233.116.114 ks-k8s-master-2 <none> <none>
name-service-1 1/1 Running 0 110s 10.233.87.120 ks-k8s-master-1 <none> <none>
rocketmq-operator-6db8ccc685-5hkk8 1/1 Running 0 18m 10.233.116.112 ks-k8s-master-2 <none> <none>

特别说明

NameServer 扩容一定要慎重,在实际验证测试中发现 NameServer 扩容会导致重建已有的除了 Broker-0 的 Master 之外的其他 Broker 的 Master 和 所有的 Slave。按官方文档上的说明,应该是 Operator 通知所有的 Broker 更新 name service list parameters,以便它们可以注册到新的 NameServer Service。

同时,在 allowRestart: true 策略下,Broker 将逐渐更新,因此更新过程也不会被生产者和消费者客户端感知,也就是说理论上不会影响业务(未实际测试)。

但是,所有 Broker 的 Master 和 Slave 重建后,查看集群状态时,集群节点的信息不稳定,有的时候能看到 3 个节点,有的时候则能看到 4 个节点。

因此,生产环境最好在初次部署的时候就配置 NameServer 的副本数为 2 或是 3,尽量不要在后期扩容,除非你能搞定扩容造成的一切后果。

七、扩容 Broker

通常情况下,随着业务的发展,现有的 Broker 集群规模可能不再满足您的业务需求。你可以简单地使用 RocketMQ-Operator 来升级、扩容 Broker 集群。

扩容 Broker 需要编写并执行独立的资源配置清单,参考官方示例Broker Cluster Scale,并结合自己实际环境的 rocketmq-operator 配置修改。

编辑扩容 Broker 资源配置清单 , rocketmq_v1alpha1_broker_cr.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 备份起来下次使用
cpsave example/rocketmq_v1alpha1_broker_cr.yaml
# 添加namespsec
sed -i 'N;18 a \ namespace: devops' example/rocketmq_v1alpha1_broker_cr.yaml
sed -i 'N;34 a \ namespace: devops' example/rocketmq_v1alpha1_broker_cr.yaml
# 修改nameserver
sed -i 's/nameServers: ""/nameServers: "name-server-service.devops:9876"/g' example/rocketmq_v1alpha1_broker_cr.yaml

#修改镜像地址为内网地址:
sed -i 's#apache/rocketmq-operator:0.3.0#自己的仓库地址/apacherocketmq/rocketmq-operator:0.3.0#g' deploy/operator.yaml
sed -i 's#apacherocketmq#自己的仓库地址/apacherocketmq#g' example/rocketmq_v1alpha1_broker_cr.yaml
# 如果仓库有密码记得添加key
imagePullSecrets:
- name: testregistrysecret

#修改 storageClassName 为 glusterfs或者nfs:

sed -i 's/storageClassName: rocketmq-storage/storageClassName: 业务存储名字/g' example/rocketmq_v1alpha1_broker_cr.yaml

sed -i 's/storageMode: EmptyDir/storageMode: StorageClass/g' example/rocketmq_v1alpha1_broker_cr.yaml

Notice: 注意重点字段 scalePodName: broker-0-master-0。

选择源 Broker pod,将从其中将主题和订阅信息数据等旧元数据传输到新创建的 Broker。

Notice: 注意重点字段 size: 2 如果1 是没变化。

执行扩容 Broker:

1
kubectl apply -f rocketmq/cluster/rocketmq_v1alpha1_broker_cr.yaml

Notice: 执行成功后将部署一个新的 Broker Pod 组,同时 Operator 将在启动新 Broker 之前将源 Broker Pod 中的元数据复制到新创建的 Broker Pod 中,因此新 Broker 将重新加载已有的主题和订阅信息。

验证 StatefulSet:

1
2
3
4
5
6
7
$ kubectl get sts  -o wide -n zdevops
NAME READY AGE CONTAINERS IMAGES
broker-0-master 1/1 43m broker registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-0-replica-1 1/1 43m broker registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-1-master 1/1 27s broker registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
broker-1-replica-1 1/1 27s broker registry.zdevops.com.cn/apacherocketmq/rocketmq-broker:4.9.4-alpine-operator-0.3.0
name-service 2/2 43m name-service registry.zdevops.com.cn/apacherocketmq/rocketmq-nameserver:4.9.4-alpine-operator-0.3.0

验证 Pods:

1
2
3
4
5
6
7
8
9
10
11
$ kubectl get pods -o wide -n zdevops

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
broker-0-master-0 1/1 Running 0 44m 10.233.87.117 ks-k8s-master-1 <none> <none>
broker-0-replica-1-0 1/1 Running 0 26m 10.233.117.99 ks-k8s-master-0 <none> <none>
broker-1-master-0 1/1 Running 0 72s 10.233.116.117 ks-k8s-master-2 <none> <none>
broker-1-replica-1-0 1/1 Running 0 72s 10.233.117.100 ks-k8s-master-0 <none> <none>
console-8d685798f-hnmvg 1/1 Running 0 44m 10.233.116.113 ks-k8s-master-2 <none> <none>
name-service-0 1/1 Running 0 44m 10.233.116.114 ks-k8s-master-2 <none> <none>
name-service-1 1/1 Running 0 27m 10.233.87.120 ks-k8s-master-1 <none> <none>
rocketmq-operator-6db8ccc685-5hkk8 1/1 Running 0 44m 10.233.116.112 ks-k8s-master-2 <none> <none>

在 KubeSphere 控制台验证:

在 RocketMQ 控制台验证:

八、清理资源

清理 RocketMQ Cluster
部署集群失败或是需要重新部署时,采用下面的顺序清理删除。

1
2
kubectl delete -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
kubectl delete -f example/rocketmq_v1alpha1_cluster_service.yaml

清理 RocketMQ Operator

1
2
3
4
5
6
7
8
kubectl delete -f deploy/crds/rocketmq.apache.org_brokers.yaml
kubectl delete -f deploy/crds/rocketmq.apache.org_nameservices.yaml
kubectl delete -f deploy/crds/rocketmq.apache.org_consoles.yaml
kubectl delete -f deploy/crds/rocketmq.apache.org_topictransfers.yaml
kubectl delete -f deploy/service_account.yaml
kubectl delete -f deploy/role.yaml
kubectl delete -f deploy/role_binding.yaml
kubectl delete -f deploy/operator.yaml

清理存储卷
需要手工查找 Broker 和 NameServer 相关的存储卷并删除。

1
2
3
4
5
6
7
8
9
10
11
12
# 查找存储卷
$ kubectl get pvc -n devops

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
broker-storage-broker-0-master-0 Bound pvc-6a78b573-d72a-47ca-9012-5bc888dfcb0f 8Gi RWO glusterfs 3m54s
broker-storage-broker-0-replica-1-0 Bound pvc-4f096942-505d-4e34-ac7f-b871b9f33df3 8Gi RWO glusterfs 3m54s
namesrv-storage-name-service-0 Bound pvc-2c45a77e-3ca1-4eab-bb57-8374aa9068d3 1Gi RWO glusterfs 3m54s

# 删除存储卷
kubectl delete pvc namesrv-storage-name-service-0 -n devops
kubectl delete pvc broker-storage-broker-0-master-0 -n devops
kubectl delete pvc broker-storage-broker-0-replica-1-0 -n devops

参考文档