前言

了解rocketmq原理参考:https://www.yuque.com/qinxi-cvygi/rsrp4k/baw52h

使用 Kubernetes 提供的 Deployment 和 StatefulSet 等原生资源可以很好地解决无状态应用的管理问题,但对于数据库和 RocketMQ 这类有状态应用,则存在很多局限性。
例如对 RocketMQ 来说扩容不仅仅是拉起新的实例 Pod 就完成了,还需要同步复制 Broker 的状态信息包括 Topic 信息和订阅关系这些元数据,同时要正确配置新 Broker 的 config 参数,包括 brokerName 和 NameServer IP List 等,才能使得新扩容的 Broker 可用,而这些仅仅靠用户编写 StatefulSet,修改 size 或 replicas 然后 apply 是无法做到的。

实际上 Kubernetes 开发人员也发现了这些问题,因此引入了自定义资源和控制器的概念,让开发人员可以直接用 Go 语言调用 Kubernetes API,编写自定义资源和对应的控制器逻辑来解决复杂有状态应用的管理问题,提供特定应用相关的自定义资源的这类代码组件称之为 Operator。由具备 RocketMQ 领域知识的专家编写 Operator,屏蔽了应用领域的专业知识,让用户只需要关心和定义希望达到的集群终态,这也是 Kubernetes 声明式 API 的设计哲学。

Kubernetes Operator

Operator 是在 Kubernetes 基础上通过扩展 Kubernetes API,用来创建、配置和管理复杂的有状态应用,如分布式数据库等。Operator 基于 Kubernetes 1.7 版本以来引入的自定义控制器的概念,在自定义资源和控制器之上构建,同时又包含了应用程序特定的领域知识。实现一个 Operator 的关键是 CRD(自定义资源)和 Controller(控制器)的设计。

image.png
Operator 站在 Kubernetes 内部视角,为应用的云原生化打开了新世界的大门。自定义资源可以让开发人员扩展添加新功能,更新现有的功能,并且可以自动执行一些管理任务,这些自定义的控制器就像 Kubernetes 原生的组件一样,Operator 可以直接使用 Kubernetes API 进行开发,也就是说他们可以根据这些控制器编写的自定义规则来创建和更改 Pods / Services、对正在运行的应用进行扩缩容。

安装 RocketMQ Operator

  • 下载脚本

    1. git clone https://operatorhub.io/operator/rocketmq-operator
  • 运行脚本安装 RocketMQ Operator

    1. $ ./install-operator.sh
  • 检查下 RocketMQ Operator 是否安装成功

    1. kubectl get pod -n infra|grep oper
    2. rocketmq-operator-7698d588b8-n4nfp 1/1 Running 1 23h

创建 RocketMQ 集群

应用 rocketmq-operator/example 中的 rocketmq_v1alpha1_rocketmq_cluster.yaml 文件,快速部署一个 RocketMQ 集群。

  • 数据持久化

修改storageMode

  1. ......
  2. # allowRestart defines whether allow pod restart
  3. allowRestart: true
  4. # storageMode can be EmptyDir, HostPath, StorageClass
  5. storageMode: StorageClass #修改为StorageClass
  6. # hostPath is the local path to store data
  7. hostPath: /data/rocketmq/broker
  8. ......

修改storageClassName和storage磁盘容量
由于我在阿里云上部署,因此storageClassName 为阿里云支持的类型

  1. ......
  2. # volumeClaimTemplates defines the storageClass
  3. volumeClaimTemplates:
  4. - metadata:
  5. name: broker-storage
  6. spec:
  7. accessModes:
  8. - ReadWriteOnce
  9. storageClassName: "alicloud-disk-essd" #modify
  10. resources:
  11. requests:
  12. storage: 200Gi #视情况而定大小

修改命名空间【可选】

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: broker-config
  5. namespace: infra
  6. ......

涉及到example/rocketmq_v1alpha1_cluster_service.yaml,example/rocketmq_v1alpha1_rocketmq_cluster.yaml和install-operator.sh文中的8个文件。

修改公有镜像为私有镜像【可选】
下载公有镜像并推送到私有仓库镜像,然后更改yaml文件中所有的私有镜像,目的是防止官方镜像更新,影响服务稳定。

  • 部署应用

    1. $ kubectl apply -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml
    2. broker.rocketmq.apache.org/broker created
    3. nameservice.rocketmq.apache.org/name-service created
  • 查看应用状态

    1. kubectl get pod -n infra
    2. NAME READY STATUS RESTARTS AGE
    3. broker-0-master-0 1/1 Running 0 23h
    4. broker-0-replica-1-0 1/1 Running 0 23h
    5. console-5fc88d77df-drsvl 1/1 Running 0 23h
    6. name-service-0 1/1 Running 0 23h
    7. rocketmq-operator-7698d588b8-n4nfp 1/1 Running 1 23h

    由此基础的rocketmq集群部署完毕,但是服务是要提供访问的,因此要提供访问控制台。

访问console控制台

默认使用nodePort方式暴露服务给集群外服务访问,但是这种方式对于服务经常被调度,服务访问node变化来说很不方便,因此需要使用ingress访问来访问控制台,因此需要在文件example/rocketmq_v1alpha1_cluster_service.yaml 中添加ingress配置

  1. ---
  2. #ingress
  3. apiVersion: networking.k8s.io/v1
  4. kind: Ingress
  5. metadata:
  6. name: rocketmq-console-ingress
  7. namespace: infra
  8. spec:
  9. rules:
  10. - host: rocketmq.123.top
  11. http:
  12. paths:
  13. - path: /
  14. pathType: Prefix
  15. backend:
  16. service:
  17. name: console-service
  18. port:
  19. number: 8080

添加完毕后,应用yaml文件

  1. $ kubectl apply -f example/rocketmq_v1alpha1_cluster_service.yaml

image.png

删除集群,清理环境

清除 RocketMQ 服务集群实例:

  1. $ kubectl delete -f example/rocketmq_v1alpha1_rocketmq_cluster.yaml

清除 RocketMQ Operator:

  1. $ ./purge-operator.sh

参考:
https://www.kubernetes.org.cn/8341.html
https://github.com/apache/rocketmq-operator
https://operatorhub.io/