RabbitMQ-Cluster-Operator部署RabbitMQ集群
大约 4 分钟约 1139 字
RabbitMQ-Cluster-Operator部署RabbitMQ集群
0 参考资料
- https://artifacthub.io/packages/helm/bitnami/rabbitmq-cluster-operator
- https://github.com/rabbitmq/cluster-operator
- https://www.rabbitmq.com/kubernetes/operator/operator-overview.html
- https://www.rabbitmq.com/production-checklist.html
- https://github.com/rabbitmq/cluster-operator/tree/main/docs/examples/
- https://www.rabbitmq.com/kubernetes/operator/operator-monitoring.html
- https://www.rabbitmq.com/kubernetes/operator/using-operator.html#service-availability
1 部署RabbitMQ-Cluster-Operator
# 下载官方提供的部署operator的清单文件
mkdir rabbitmq-operator
cd rabbitmq-operator/
wget https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml
# 将清单文件中用到的镜像私有化到私有镜像仓库
docker pull rabbitmqoperator/cluster-operator:2.1.0
docker tag rabbitmqoperator/cluster-operator:2.1.0 harbor.leadchina.cn/rabbitmqoperator/cluster-operator:2.1.0
docker push harbor.leadchina.cn/rabbitmqoperator/cluster-operator:2.1.0
# 修改operator的资源清单文件使用私有镜像仓库
# 应用资源清单文件部署operator
kubectl create -f cluster-operator.yml
2 使用RabbitMQ-Cluster-Opertor部署RabbitMQ集群
# 多参考官方的operator文档以及example
# rabbitmq-cluster-operator测试样例
https://github.com/rabbitmq/cluster-operator/tree/main/docs/examples/
# 将组建rabbitmq集群需要的镜像私有化放到私有仓库中
docker pull rabbitmq:3.10.2-management
docker tag rabbitmq:3.10.2-management harbor.leadchina.cn/rabbitmq/rabbitmq:3.10.2-management
docker push harbor.leadchina.cn/rabbitmq/rabbitmq:3.10.2-management
# 以下是可以用到生产环境的rabbitmq集群清单示例
# RabbitmqCluster类型的资源会被rabbitmq-cluster-operator监测并进行rabbtimq集群组建,同时也会创建Statefullset、Headless-service、以及外部访问的service
[root@salt-master-50 ~/rabbitmq-operator]# cat helloworld.yaml
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: mq1
namespace: default
labels:
app: rabbitmq
spec:
image: harbor.leadchina.cn/rabbitmq/rabbitmq:3.10.2-management
replicas: 5
resources:
requests:
cpu: 2
memory: 4Gi
limits:
cpu: 2
memory: 4Gi
service:
type: NodePort
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- pod-anti-affinity
topologyKey: kubernetes.io/hostname
persistence:
storageClassName: csi-rbd-sc
storage: "5Gi"
override:
statefulSet:
spec:
template:
spec:
containers:
- name: rabbitmq
volumeMounts:
- mountPath: /var/lib/rabbitmq/quorum-segments
name: quorum-segments
- mountPath: /var/lib/rabbitmq/quorum-wal
name: quorum-wal
# topologySpreadConstraints:
# - maxSkew: 1
# topologyKey: "topology.kubernetes.io/hostname"
# whenUnsatisfiable: DoNotSchedule
# labelSelector:
# matchLabels:
# app.kubernetes.io/name: hello-world
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: persistence
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeMode: Filesystem
storageClassName: csi-rbd-sc
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: quorum-wal
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeMode: Filesystem
storageClassName: csi-rbd-sc
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: quorum-segments
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeMode: Filesystem
storageClassName: csi-rbd-sc
rabbitmq:
envConfig: |
RABBITMQ_LOGS=""
RABBITMQ_QUORUM_DIR=/var/lib/rabbitmq/quorum-segments
additionalPlugins:
- rabbitmq_top
- rabbitmq_shovel
# advancedConfig: |
# [
# {ra, [
# {wal_data_dir, '/var/lib/rabbitmq/quorum-wal'}
# ]}
# ].
additionalConfig: |
log.console = true
log.console.level = debug
log.console.formatter = json
log.console.formatter.json.field_map = verbosity:v time msg domain file line pid level:-
log.console.formatter.json.verbosity_map = debug:7 info:6 notice:5 warning:4 error:3 critical:2 alert:1 emergency:0
log.console.formatter.time_format = epoch_usecs
default_user=guest
default_pass=guest
cluster_partition_handling = pause_minority
vm_memory_high_watermark_paging_ratio = 0.99
disk_free_limit.relative = 1.5
collect_statistics_interval = 10000
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: production-ready-rabbitmq
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: testmq
[root@salt-master-50 ~/rabbitmq-operator]# kubectl create -f helloworld.yaml
4 benchmark测试
# 测试前必须要先登录控制台创建测试用户,不能使用自带的guest用户测试
# 使用下面命令获取rabbitmq用户名和密码
NAMESPACE='default'
INSTANCE='mq1'
username=`kubectl -n $NAMESPACE get secret ${INSTANCE}-default-user -o jsonpath="{.data.username}" | base64 --decode`
password=`kubectl -n $NAMESPACE get secret ${INSTANCE}-default-user -o jsonpath="{.data.password}" | base64 --decode`
echo "user: ${username}, password: ${password}"
# 使用上面打印的用户和密码,然后再查看svc的nodeport在浏览器登录(觉得麻烦就直接使用下面命令创建)
# 创建用户并授予权限(登录到集群中的任意一个pod中使用下面命令创建)
rabbitmqctl add_user test Qwerty123456
rabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test ".*" ".*" ".*"
# 使用perf-test测试工具测试rabbitmq是否正常能使用
docker pull pivotalrabbitmq/perf-test
docker tag pivotalrabbitmq/perf-test:latest harbor.leadchina.cn/rabbitmq/perf-test:latest
docker push harbor.leadchina.cn/rabbitmq/perf-test:latest
# 压测脚本
[root@salt-master-50 ~/rabbitmq-operator]# cat benchmark-test.sh
#!/bin/bash
instance=mq1
username='test'
password='Qwerty123456'
service=${instance}
kubectl get pod perf-test |grep perf-test > /dev/null 2>&1 && kubectl delete pod perf-test
kubectl run perf-test --image=harbor.leadchina.cn/rabbitmq/perf-test:latest -- --uri "amqp://${username}:${password}@${service}"
sleep 30
kubectl logs -f perf-test
# 执行压测操作
[root@salt-master-50 ~/rabbitmq-operator]# ./benchmark-test.sh
5 配置rabbitmq监控(prometheus)
# 创建rabbitmq集群专用的servicemonitor,可以根据自身需求调整
# 官方servicemonitor配置下载链接https://raw.githubusercontent.com/rabbitmq/cluster-operator/main/observability/prometheus/monitors/rabbitmq-servicemonitor.yml
[root@salt-master-50 ~/rabbitmq-operator]# cat rabbitmq-servicemonitor.yml
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: rabbitmq
labels:
prometheus: service
# If labels are defined in spec.serviceMonitorSelector.matchLabels of your deployed Prometheus object, make sure to include them here.
spec:
endpoints:
- port: prometheus
scheme: http
interval: 15s
scrapeTimeout: 14s
- port: prometheus-tls
scheme: https
interval: 15s
scrapeTimeout: 14s
tlsConfig:
insecureSkipVerify: true # set to false and uncomment lines below to enable tls verification
# ca:
# secret:
# key: ca.crt
# name: tls-secret # name of the secret containing the CA cert which signed the RabbitMQ Prometheus TLS cert
# serverName: '*.RABBITMQ-INSTANCE-NAME.NAMESPACE.svc.cluster.local'
- port: prometheus
scheme: http
path: /metrics/detailed
params:
family:
- queue_coarse_metrics
- queue_metrics
interval: 15s
scrapeTimeout: 14s
- port: prometheus-tls
scheme: https
path: /metrics/detailed
params:
family:
- queue_coarse_metrics
- queue_metrics
interval: 15s
scrapeTimeout: 14s
tlsConfig:
insecureSkipVerify: true
selector:
matchLabels:
app.kubernetes.io/component: rabbitmq
namespaceSelector:
any: true
[root@salt-master-50 ~/rabbitmq-operator]#
# 配置grafana dashboard, 可以直接到官网搜 https://grafana.com/grafana/dashboards/10991-rabbitmq-overview/
6 修改rabbitmq集群节点类型
# RabbitMQ集群节点有两种类型,ram和disc
# disc可以保证队列及交换机数据一致性,但是性能一般,而ram类型的节点性能会比较好,如果集群中有多个节点,可以考虑将部分disc类型的节点转成ram类型
# 具体转换操作如下
# 在要修改的节点上操作
rabbitmqctl stop_app
# 等待节点完全停止后
rabbitmqctl change_cluster_node_type ram
# 启动应用
rabbitmqctl start_app
# 再次查看节点类型
rabbitmqctl cluster_status