docker 部署rabbitmq,k8s部署rabbitmq集群

版权声明:本文为博主原创文章,转载请注明来源。开发合作联系[email protected] https://blog.csdn.net/luanpeng825485697/article/details/82078416

rabbit原理和架构可以参考https://blog.csdn.net/luanpeng825485697/article/details/82082751

docker部署rabbit

在docker环境部署RabbitMQ

RabbitMQ是用 Erlang 编写的,直接部署的话需要先部署 Erlang 环境,比较麻烦。在 docker 环境下部署就比较简单了,直接使用rabbitmq官方提供的镜像即可。

登录 docker 节点,运行

docker pull rabbitmq:management

这里使用的是带 web 管理插件的镜像。

启动容器:

docker run -d --name rabbitmq --publish 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management

容器启动之后就可以访问web 管理端了 http://宿主机IP:15672,默认创建了一个 guest 用户,密码也是 guest。

好了,RabbitMQ已经启动成功了,然后我们来实践一下。

先添加两个Exchange(camera_exchange、screen_exchange)和两个queue(carema_queue、screen_queue)都选择topic模式

这里写图片描述
这里写图片描述

为camera_exchange绑定camera_queue,并绑定两个路由(过滤条件)ca1.#和ca2.#

这里写图片描述

为screen_exchange绑定screen_queue,并绑定两个路由(过滤条件)sc1.#和sc2.#

这里写图片描述

exchange和queue可以多对多绑定。

这样就可以在exchange中发送消息了。消息包含key(Routing key)和message(Payload)。exchange接收消息后通过key值选择将消息发送到哪个queue。

这里写图片描述

在queue中接收消息

这里写图片描述

k8s部署rabbit集群

消息中间件rabbitmq,一般以集群方式部署,主要提供消息的接受和发送,实现各微服务之间的消息异步。本篇将以rabbitmq+HA方式进行部署。

一、原理介绍

rabbitmq是依据erlang的分布式特性(RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证)来实现的,所以部署rabbitmq分布式集群时要先安装erlang,并把其中一个服务的cookie复制到另外的节点。

rabbitmq集群中,各个rabbitmq为对等节点,即每个节点均提供给客户端连接,进行消息的接收和发送。节点分为内存节点和磁盘节点,一般的,均应建立为磁盘节点,为了防止机器重启后的消息消失;

RabbitMQ的Cluster集群模式一般分为两种,普通模式和镜像模式。消息队列通过rabbitmq HA镜像队列进行消息队列实体复制。

普通模式下,以两个节点(rabbit01、rabbit02)为例来进行说明。对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。

镜像模式下,将需要消费的队列变为镜像队列,存在于多个节点,这样就可以实现RabbitMQ的HA高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在consumer消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。

二、集群部署方案

本方案中是在多台机器之间部署rabbitmq的cluster,要求如下:这几个节点需要在同一个局域网内;这几个节点需要有相同的erlang cookie,否则不能正常通信,为了实现cookie内容一致,采用scp的方式进行。

这里仍然使用上面的镜像rabbitmq:management,因为上面的镜像中已经安装了erlang和rabbit

rabbit在目录/usr/lib/rabbitmq中

erlang在目录/usr/lib/erlang中

设置erlang

找到erlang cookie文件的位置,官方在介绍集群的文档中提到过.erlang.cookie一般会存在这两个地址:第一个是 h o m e / . e r l a n g . c o o k i e / v a r / l i b / r a b b i t m q / . e r l a n g . c o o k i e 使 r a b b i t m q {home}目录下,也就是$home/.erlang.cookie。如果我们使用rpm等安装包方式进行安装的,那么这个文件会在/var/lib/rabbitmq目录下。

在rabbitmq:management镜像查看文件

cat ~/.erlang.cookie

这里将 node1 的该文件复制到 node2、node3,注意这个文件的权限是 400(默认即是400),因此采用scp的方式只拷贝内容即可;

可以通过cat $~/.erlang.cookie来查看三台机器的cookie是否一致,设置erlang的目的是要保证集群内的cookie内容一致。

k8s部署

首先说明一下,rabbitmq是使用autocluster插件去调用kubernetes apiserver获取rabbitmq服务的endpoints获取node节点信息,并加入集群的。下面开始操作:

# 集群中的每个rabbitmq都要是相同的cookie
echo $(openssl rand -base64 32) > erlang.cookie
kubectl create secret generic erlang.cookie --from-file=erlang.cookie   -n cloudai-2 

kubectl create -f rabbitmq-serviceAccount.yaml
kubectl create -f rabbitmq-service.yaml
kubectl create -f rabbitmq-deployment.yaml

其中rabbitmq-serviceAccount.yaml为

---
apiVersion: v1
kind: ServiceAccount    # 也就是pod在k8s中的角色。kubectl是admin角色。Service Account 是 Kubernetes 用于集群内运行的程序,进行服务发现时调用 API 的帐号,帐号的 token 会直接挂载到 Pod 中,可以供程序直接使用。
metadata:
  name: rabbitmq
  namespace: cloudai-2
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: rabbitmq
  namespace: cloudai-2
rules:
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: rabbitmq
  namespace: cloudai-2
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: rabbitmq
subjects:
- kind: ServiceAccount
  name: rabbitmq
  namespace: cloudai-2

rabbitmq-service.yaml文件为

apiVersion: v1
kind: Service
metadata:
  labels:
    app: rabbitmq
  name: rabbitmq
  namespace: cloudai-2
spec:
  ports:
  - port: 5672
    name: port-5672
    protocol: TCP
    targetPort: 5672    
  - port: 4369
    name: port-4369
    protocol: TCP
    targetPort: 4369    
  - port: 5671
    name: port-5671
    protocol: TCP
    targetPort: 5671    
  - port: 15672
    name: port-15672
    protocol: TCP
    targetPort: 15672    
  - port: 25672
    name: port-25672
    protocol: TCP
    targetPort: 25672    
  selector:
    app: rabbitmq    # 选择pod
  externalIPs:
    - 192.168.2.177    # 这里要更改一下,只在指定的外部ip上监听,而非像nodeport所有节点监听.  只用externalIPs:port  访问

rabbitmq-deployment.yaml文件为

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: rabbitmq
  namespace: cloudai-2
  labels:
    app: rabbitmq  
spec:
  selector:    
    matchLabels:
      app: rabbitmq
  replicas: 3
  template:
    metadata:
      labels:
        app: rabbitmq
    spec:
      serviceAccountName: rabbitmq
      containers:
      - name: rabbitmq
        image: rabbitmq:management
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 5672
            name: port-5672
          - containerPort: 4369
            name: port-4369
          - containerPort: 5671
            name: port-5671
          - containerPort: 15672
            name: port-15672
          - containerPort: 25672
            name: port-25672
        env:
          - name: AUTOCLUSTER_TYPE
            value: "k8s"
          - name: AUTOCLUSTER_DELAY
            value: "10"
          - name: AUTOCLUSTER_CLEANUP
            value: "true"
          - name: RABBITMQ_DEFAULT_USER
            value: 1111                        # 连接rabbit的账号
          - name: RABBITMQ_DEFAULT_PASS
            value: 2222                       #连接rabbit的密码
          - name: HOSTNAME
            valueFrom:
             fieldRef:
              fieldPath: status.podIP
          - name: MY_POD_IP
            valueFrom:
             fieldRef:
              fieldPath: status.podIP
          - name: CLEANUP_INTERVAL
            value: "60"
          - name: CLEANUP_WARN_ONLY
            value: "false"
          - name: K8S_SERVICE_NAME
            value: "rabbitmq"
          - name: K8S_ADDRESS_TYPE
            value: "hostname"
          - name: K8S_HOSTNAME_SUFFIX
            value: ".$(K8S_SERVICE_NAME)"
          - name: RABBITMQ_USE_LONGNAME
            value: "true"
          - name: K8S_HOST
            value: "192.168.2.177"
          - name: K8S_PORT
            value: "6443"
          - name: RABBITMQ_ERLANG_COOKIE
            valueFrom:
             secretKeyRef:
              name: erlang.cookie
              key: erlang.cookie

猜你喜欢

转载自blog.csdn.net/luanpeng825485697/article/details/82078416