kubernetes容器化常用中间件之rabbitmq

1 篇文章 0 订阅
1 篇文章 0 订阅

rabbitmq

RabbitMQ是实现了高级消息队列协议的开源消息代理软件。RabbitMQ服务器是用Erlang语言编写的,而聚类和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。同时rabbitmq的使用非常的广泛,所以使用容器化的方式快速部署rabbitmq集群非常的有必要。

关于rabbitmq服务组成

rabbitmq服务实质邮4大部分组成

  1. epmd服务,rabbitmq起来后会自动的启动epmd服务,empd服务是erlang的一个小程序,专门用来做端口管理的。通常端口是4369
  2. rabbitmq amqp server,这个服务就是我们通常使用rabbitmq服务的时候,链接的5672端口的服务,使用来支持amqp服务的。通常端口是5672
  3. rabbitmq cluster server,主要是用来做cluster节点之间的心跳发现的,通常端口是25672
  4. 如果开启来rabbitmq manager plugin,会有一个manager api服务,通常端口是15672

除以上的服务之外,还有一个是erlang自带的数据库,专门用来做分部署服务发现的: mnesia数据库。可以从官网查看详细的文档rabbitmq官网

容器化步骤

容器化的第一步是制作rabbitmq镜像,rabbitmq是基于erlang语言开发的,所以需要在erlang环境中运行,制作rabbitmq镜像,也非常的简单,需要参照官网对应rabbitmq版本和对应的erlang的版本进行镜像制作,由于rabbitmq自身有官方的镜像,所以在这片文章中我直接只用rabbitmq官方镜像。rabbitmq官方镜像有带manager-plugin的和不带plugin的。我们使用带manager-plugin的。除此之外,我们依靠官方的一个auto-cluster插件去完成rabbitmq的集群自动初始化。所以还需要在官方镜像的基础上安装auto-cluster插件。


FROM 3.7.26-management-alpine

ADD https://github.com/rabbitmq/rabbitmq-autocluster/releases/download/0.10.0/autocluster-0.10.0.ez /opt/rabbitmq/plugins/
ADD https://github.com/rabbitmq/rabbitmq-autocluster/releases/download/0.10.0/rabbitmq_aws-0.10.0.ez /opt/rabbitmq/plugins/

RUN rabbitmq-plugins enable --offline rabbitmq_management && rabbitmq-plugins enable --offline autocluster

编译制作镜像完成后,开始写k8s相关的yaml文件,并部署rabbitmq集群

部署rabbitmq集群

auto-cluster插件也是erlang开发的,同时它需要去k8s中查询endpoint,所以需要有对应的查询k8s的endpoint的权限,第一步是创建RBAC。

创建RBAC

apiVersion: v1
kind: ServiceAccount
metadata:
  name: rabbitmq-autocluster
  namespace: default

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: rabbitmq-autocluster
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: rabbitmq-autocluster
  namespace: default

创建headless service

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: rabbitmq
    app.kubernetes.io/instance: rabbitmq-demo
    app.kubernetes.io/version: 3.7.26
  name: rabbitmq-demo
  namespace: default
spec:
  clusterIP: None
  ports:
  - name: amqp
    port: 5672
    protocol: TCP
    targetPort: 5672
  selector:
    app.kubernetes.io/instance: rabbitmq-demo
    app.kubernetes.io/version: 3.7.26
  sessionAffinity: None
  type: ClusterIP

创建secret保存adminuser,pass和erlang cookie

apiVersion: v1
kind: Secret
metadata:
  labels:
    app.kubernetes.io/name: rabbitmq
    app.kubernetes.io/instance: rabbitmq-demo
    app.kubernetes.io/version: 1.1.1
  name: rabbitmq-config
  namespace: default
data:
  rabbitmqDefaultPass: base64 password
  rabbitmqDefaultUser: base64 user
  rabbitmqErlangCookie: base64 cookie

自行更改对应的user,pass,cookie

创建statefulset

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: rabbitmq
    app.kubernetes.io/instance: rabbitmq-demo
    app.kubernetes.io/version: 3.7.26
  name: rabbitmq-demo
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/instance: rabbitmq-demo
      app.kubernetes.io/version: 3.7.26
  serviceName: rabbitmq-demo
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: rabbitmq-demo
        app.kubernetes.io/version: 3.7.26
    spec:
      containers:
      - env:
        - name: RABBITMQ_DEFAULT_USER
          valueFrom:
            secretKeyRef:
              key: rabbitmqDefaultUser
              name: rabbitmq-config
        - name: RABBITMQ_DEFAULT_PASS
          valueFrom:
            secretKeyRef:
              key: rabbitmqDefaultPass
              name: rabbitmq-config
        - name: RABBITMQ_ERLANG_COOKIE
          valueFrom:
            secretKeyRef:
              key: rabbitmqErlangCookie
              name: rabbitmq-config
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: K8S_SERVICE_NAME
          value: rabbitmq-oam-mq-mq-1
        - name: RABBITMQ_USE_LONGNAME
          value: "true"
        - name: RABBITMQ_NODENAME
          value: rabbit@$(MY_POD_NAME).$(K8S_SERVICE_NAME)
        - name: RABBITMQ_NODE_TYPE
          value: disc
        - name: AUTOCLUSTER_TYPE
          value: k8s
        - name: AUTOCLUSTER_DELAY
          value: "10"
        - name: AUTOCLUSTER_CLEANUP
          value: "true"
        - name: CLEANUP_WARN_ONLY
          value: "false"
        - name: K8S_ADDRESS_TYPE
          value: hostname
        - name: K8S_HOSTNAME_SUFFIX
          value: .$(K8S_SERVICE_NAME)
        image: 制作的rabbitmq镜像
        imagePullPolicy: IfNotPresent
        name: rabbitmq
        resources:
          limits:
            cpu: 512m
            memory: 1G
          requests:
            cpu: 521m
            memory: 1G
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /var/lib/rabbitmq
          name: data
      serviceAccount: rabbitmq-autocluster
      volumes:
      - emptyDir: {}
        name: data  

关于auto-cluster插件依赖的环境变量的配置请参考rabbitmq-autocluster,有详细的介绍和说明,可以根据自己的实际情况进行设置。

需要注意的点

  • AUTOCLUSTER_CLEANUP 这个环境变量是用来设置自动清除不健康的节点,需要配合CLEANUP_WARN_ONLY=false,同时也依赖CLEANUP_INTERVAL这个参数,默认是60s,每隔一分钟进行一次检测,当检测到不健康节点的时候,就会吧节点从集群中删除,对应的节点上的数据也相应丢失,如果对应的queue没设置成mirror queue是非常危险的。所以一般会AUTOCLUSTER_CLEANUP =false。如果AUTOCLUSTER_CLEANUP设置成true,当不健康节点节点从集群中剔除,后面故障节点又重新起来后,由于故障节点中存储的的信息中,包含该节点属于之前的集群,所以节点在起来后会尝试加入之前的集群,但是之前的集群已经吧它剔除, 所以导致故障节点一直起不来,并且报错: 大致意思是,节点yyy尝试加入集群xxx,但是集群xxx不认为节点yyy是xxx的节点。 这个时候,需要吧对应的故障节点的数据目录下的mnesia数据目录(mnesia数据目录是erlang自带的mnesia数据库的数据存储目录)。然后重启节点,让节点重新加入集群。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值