k8s持久化存储rabbitmq数据

前言:有个需求是要持久化存储rabbitmq的消息数据,这样可以避免因为异常导致消息丢失的问题,找了好久都没有一个靠谱的答案,更恐怖的是一大堆人乱写一通,以下是本人解决问题的心路历程

0X00 问题&错误的尝试

rabbitmq数据持久化问题挺麻烦的,麻烦在rabbitmq的数据目录下的文件和文件夹的名字会依赖于本机的主机名,所以pod一旦重启或者移动到其他node,都会导致主机名变化,那么volume的挂载路径也得随之而变,哪能不停的监听pod状态去改yml文件呢?所以必须得解决主机名会发生变化的问题,首先想到的是看看rabbitmq的官方文档,看看能不能通过什么方式固定数据目录的名称,让他不随着主机名变化。

ReplicationController.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    component: rabbitmq
  name: rabbitmq-controller
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: taskQueue
        component: rabbitmq
    spec:
      volumes:  # 设置一个volumes,使用本机的/home/rabbitmq_data/目录进行数据存储
      - name: rabbitmq-data
        hostPath:
          path: /home/rabbitmq_data
      containers:
      - image: rabbitmq:latest
        name: rabbitmq
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5672
        resources:
          limits:
            cpu: 1000m
        env:  # 设置环境变量,指定本rabbitmq节点的数据存储目录
        - name: RABBITMQ_MNESIA_DIR
          value: /var/lib/rabbitmq/mnesia/rabbitmq-server
        volumeMounts:  # 将上面声明的volumes挂载到容器内部
        - mountPath: /var/lib/rabbitmq/mnesia/rabbitmq-server
          name: rabbitmq-data 

官方环境变量列表(https://www.rabbitmq.com/relocate.html):

不得不说,这个环境变量真的是坑爹的很,确实将数据存储目录改变成了固定值,但是你会发现持久化数据仍然会存在问题,因为在/var/lib/rabbitmq/mnesia/目录下还有一些鬼目录依赖hostname,目录名称会携带hostname,那么重启pod之后,hostname就改变了,所以数据无法持久化!!!!

举个例子,现在的pod hostname为rabbitmq-controller-tx75c,那么那些鬼目录可能就是rabbit@rabbitmq-controller-tx75c。pod重建后,hostname变成了rabbitmq-controller-4lc5h,那么rabbitmq在识别目录时就会存在问题,无法正常启动

0X01 解决方案

既然这个rabbitmq创建的鬼目录依赖hostname,那我们固定pod的hostname不就行了!?google了一番,很多人寄希望于这种解决方案,那么在部署的yml文件中指定hostname:

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    component: rabbitmq
  name: rabbitmq-controller
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: taskQueue
        component: rabbitmq
    spec:
      nodeName: node1  # 指定pod的调度节点
      hostname: rabbitmq-server  # 固定pod的hostname
      volumes:  # 设置一个volumes,使用本机的/home/rabbitmq_data/目录进行数据存储
      - name: rabbitmq-data
        hostPath:
          path: /home/rabbitmq_data
      containers:
      - image: rabbitmq:latest
        name: rabbitmq
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5672
        resources:
          limits:
            cpu: 1000m
        volumeMounts:  # 将上面声明的volumes挂载到容器内部
        - mountPath: /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-server
          name: rabbitmq-data

看起来没啥问题了,结果将node的本地目录挂载到pod之后又有问题,提示没有权限,我寻思本地数据目录的权限我给的是666啊,应该没问题。后来想到rabbitmq会在目录中创建子目录,所以需要执行权限,那么数据目录权限直接777,搞定!

0X02 其他的一些鬼问题

1.0X01为运行一个rabbitmq pod,那么运行多个rabbitmq pod的话,数据存储该怎么搞?

如果k8s用的是ceph存储,那么应该不用考虑这些,不同的pod挂载不同的PV&PVC就完事。但是小集群可能没有ceph,这玩意bug多又难得维护。那么可以考虑将rabbitmq分散到每个node中,每个node上部署一个rabbitmq的pod,这个好办,使用Daemonset就行了,保证每个node节点会运行一个pod,然后每个pod挂载的又都是本机的hostpath,互不干扰,完美!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值