在腾讯云TKE/K8S上构建高可用RabbitMQ集群

确认环境需求

在构建之前先关注生产环境中RabbitMQ对环境的需求,可以从官方文档Production-checklist中获取很多关键信息https://www.rabbitmq.com/production-checklist.html

VirtualHost

因为我们需要是搭建面向不同业务线和不同环境的多租户的RabbitMQ集群,所以需要根据不同的租户设置不同的VirtualHost

User

针对不同租户设置不同用户,不同用户的权限细粒度可以单独控制

监控

使用Prometheus exporter plugin来暴露RMQ服务内部的运行监控数据,除此之外还要关注容器宿主机的网络、磁盘、文件环境变化情况

内存使用

因为RMQ使用了Resource-driven alarms策略来控制生产者的生产速度,默认情况下,如果内存使用超过40%(vm_memory_high_watermark设置的),RMQ就不会接收来自生产者的消息了。【一般情况下就不要调整这个值啦,因为系统也要占用内存,各种资源的消耗也要占用,超过0.7不推荐,推荐范围是0.4-0.66】

磁盘占用

按照官方文档推荐,{disk_free_limit,{mem_relative,2.0}},那么磁盘可用空间至少需要达到2倍的系统总内存大小。

文件打开句柄限制

这个在容器中默认会继承宿主机的Docker的Ulimit,它会影响到同时打开的文件数量,包括网络使用的socket数量。按照官方的的算法,95%百分位并发连接数乘以2再加上当前队列数目作为文件打开句柄限制

日志聚合

我们之前在K8S集群搭建了fluentbit + ES的日志聚合系统,可以自动聚合容器内的日志,不过需要将日志都重定向到标准输出

集群大小

对于大多数情况下,能够镜像一半以上的集群节点就足够了,所以一般创建奇数个节点
集群的分区策略
集群内节点的时间同步一般情况下是不需要的,但是当rabbitmq使用的插件可能需要使用本地时间戳来记录时,那么各节点需要保证时间同步(可以用NTP)

编写K8S YAML配置

使用helm charts stable/rabbitmq-ha作为基础,然后修改配置。
我自己的配置大概如下:

namespace: middleware

# 1638MB = 0.4 * 4GB 这就是上面说的不再接受信息的上限
rabbitmqMemoryHighWatermark: 1638MB
rabbitmqMemoryHighWatermarkType: absolute


replicaCount: 3

image:
  repository: rabbitmq
  tag: 3.7-alpine
  pullPolicy: IfNotPresent

busyboxImage:
  repository: busybox
  tag: latest
  pullPolicy: Always

terminationGracePeriodSeconds: 10

service:
  annotations: {}
  clusterIP: None
  externalIPs: []

  loadBalancerIP: ""
  loadBalancerSourceRanges: []
  type: ClusterIP

podManagementPolicy: OrderedReady

updateStrategy: OnDelete

resources:
  limits:
    cpu: 500m
    memory: 4Gi
  requests:
    cpu: 200m
    memory: 4Gi


persistentVolume:
  enabled: true
  storageClass: disk-performance # 这里是之前就在腾讯云TKE设置好的StorageClass
  name: data
  accessModes:
    - ReadWriteOnce
  size: 20Gi
  annotations: {}


podAntiAffinity: soft

existingConfigMap: false

extraLabels: {}

rbac:
  create: true

serviceAccount:
  create: true

livenessProbe:
  initialDelaySeconds: 120
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 6

readinessProbe:
  failureThreshold: 6
  initialDelaySeconds: 20
  timeoutSeconds: 3
  periodSeconds: 5

existingSecret: ""

prometheus:
  exporter:
    enabled: true
    env: {}
    image:
      repository: kbudde/rabbitmq-exporter
      tag: v0.29.0
      pullPolicy: IfNotPresent
    port: 9090
    capabilities: "bert,no_sort"
    resources:
     limits:
       cpu: 200m
       memory: 1Gi
     requests:
       cpu: 100m
       memory: 100Mi

  operator:
    enabled: true
    alerts:
      enabled: false
      selector:
        role: alert-rules
      labels: {}

    serviceMonitor:
      interval: 10s
      namespace: monitor
      selector:
        release: prometheus-helm

clusterDomain: cluster.local

验证测试

使用kube-forward暴露内部Web管理端端口

export POD_NAME=$(kubectl get pods --namespace middleware -l "app=rabbitmq-ha" -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME --namespace middleware 5672:5672 15672:15672

可以看到3节点高可用RabbitMq集群已经搭建起来了