天天看點

每日分享- Docker 部署 rabbitmq 叢集

作者:理工男二号

要用 Docker 部署 RabbitMQ 叢集,需要先建立一個 Docker 鏡像,然後使用 Docker Compose 工具定義和啟動容器。以下是一個簡單的例子:

1 建立 Docker 鏡像

可以使用以下指令在本地建立一個基于 RabbitMQ 的 Docker 鏡像:

docker build -t my-rabbitmq-image .
           

Dockerfile 内容如下:

FROM rabbitmq:3.8.9-management

# Enable the RabbitMQ plugins
RUN rabbitmq-plugins enable --offline rabbitmq_management
           

2 定義 Docker Compose 配置

可以使用以下 Docker Compose 配置定義 RabbitMQ 叢集:

version: '3'

services:
  rabbitmq1:
    image: my-rabbitmq-image
    hostname: rabbitmq1
    volumes:
      - rabbitmq1-data:/var/lib/rabbitmq
    environment:
      - RABBITMQ_ERLANG_COOKIE=abcdefg
      - RABBITMQ_NODENAME=rabbitmq1@rabbitmq1
      - RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbit cluster_formation peers [{rabbitmq2,'rabbitmq2'}]"
    ports:
      - "5672:5672"
      - "15672:15672"
    networks:
      rabbitmq-cluster:
        aliases:
          - rabbitmq1

  rabbitmq2:
    image: my-rabbitmq-image
    hostname: rabbitmq2
    volumes:
      - rabbitmq2-data:/var/lib/rabbitmq
    environment:
      - RABBITMQ_ERLANG_COOKIE=abcdefg
      - RABBITMQ_NODENAME=rabbitmq2@rabbitmq2
      - RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbit cluster_formation peers [{rabbitmq1,'rabbitmq1'}]"
    ports:
      - "5673:5672"
      - "15673:15672"
    networks:
      rabbitmq-cluster:
        aliases:
          - rabbitmq2

volumes:
  rabbitmq1-data:
  rabbitmq2-data:

networks:
  rabbitmq-cluster:
           

這個配置檔案定義了兩個 RabbitMQ 容器,每個容器都有一個獨立的資料卷和一個唯一的主機名,然後配置了兩個環境變量,其中 RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS 參數指定了叢集的對等節點,使得兩個 RabbitMQ 容器可以發現彼此并加入到同一個叢集中。在容器内,服務監聽 5672 和 15672 端口,外部暴露的端口分别是 5672 和 15672,用于接受 AMQP 連接配接和管理 Web 控制台連接配接。同時,還定義了一個 Docker 網絡用于連接配接兩個 RabbitMQ 容器。

3 啟動 RabbitMQ 叢集

可以使用以下指令啟動 RabbitMQ 叢集:

docker-compose up -d
           

該指令會在背景啟動兩個 RabbitMQ 容器。可以通過以下指令檢視容器的運作狀态:

docker-compose ps
           

可以使用以下指令停止和删除 RabbitMQ 叢集:

docker-compose down
           

另外,還有一些其他的例子:

1 使用 Docker Swarm 部署 RabbitMQ 叢集

Docker Swarm 是 Docker 内置的容器編排工具,可以用于部署分布式應用和服務。要使用 Docker Swarm 部署 RabbitMQ 叢集,可以建立一個 Docker Swarm 叢集,然後使用 Docker Stack 工具定義和啟動服務棧。以下是一個簡單的例子:

首先,使用以下指令初始化 Docker Swarm 叢集:

docker swarm init
           

然後,可以使用以下 Docker Compose 檔案定義 RabbitMQ 服務棧:

version: '3.8'

services:
  rabbitmq:
    image: rabbitmq:3.8.9-management
    hostname: "{{.Task.Slot}}-{{.Service.Name}}"
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == worker
      update_config:
        parallelism: 1
        delay: 10s
    environment:
      RABBITMQ_ERLANG_COOKIE: mycookie
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest
      RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: "-rabbit cluster_formation peer_discovery_backend rabbit_peer_discovery_classic_config -rabbitmq_peer_discovery_nodes [{rabbit@rabbitmq-1},{rabbit@rabbitmq-2},{rabbit@rabbitmq-3}]"
    ports:
      - "5672:5672"
      - "15672:15672"
    networks:
      - rabbitmq

networks:
  rabbitmq:
           

該配置檔案定義了一個名為 rabbitmq 的服務,使用了 RabbitMQ 官方鏡像,并啟用了 Web 控制台和預設使用者 guest。在 environment 部分,設定了 RabbitMQ 叢集的環境變量 RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS,指定了叢集的對等節點。在 deploy 部分,使用了 Docker Swarm 的部署配置,将服務部署到了 3 個工作節點上,并指定了一個最小間隔為 10 秒的更新延遲。

最後,使用以下指令啟動 RabbitMQ 服務棧:

docker stack deploy -c docker-compose.yml rabbitmq
           

2 使用 Kubernetes 部署 RabbitMQ 叢集

Kubernetes 是一種廣泛使用的容器編排平台,可用于自動化部署、擴充和管理容器化應用。要使用 Kubernetes 部署 RabbitMQ 叢集,需要建立一個 Kubernetes 叢集,然後使用 Kubernetes 資源對象定義和部署應用程式。以下是一個簡單的例子:

-1 首先,需要建立一個 Kubernetes 叢集,可以使用公共雲提供商(如 AWS、Azure、GCP 等)或自托管的 Kubernetes 叢集。

-2 然後,建立一個 YAML 檔案,定義 RabbitMQ 叢集的 Kubernetes 服務和 StatefulSet 對象,例如:

apiVersion: v1
kind: Service
metadata:
  name: rabbitmq
spec:
  type: NodePort
  ports:
    - name: amqp
      port: 5672
      nodePort: 30001
    - name: management
      port: 15672
      nodePort: 30002
  selector:
    app: rabbitmq
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rabbitmq
spec:
  serviceName: rabbitmq
  replicas: 3
  selector:
    matchLabels:
      app: rabbitmq
  template:
    metadata:
      labels:
        app: rabbitmq
    spec:
      containers:
        - name: rabbitmq
          image: rabbitmq:3.8.9-management
          ports:
            - containerPort: 5672
            - containerPort: 15672
          env:
            - name: RABBITMQ_ERLANG_COOKIE
              value: mycookie
            - name: RABBITMQ_DEFAULT_USER
              value: guest
            - name: RABBITMQ_DEFAULT_PASS
              value: guest
            - name: RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS
              value: "-rabbit cluster_formation peer_discovery_backend rabbit_peer_discovery_classic_config -rabbitmq_peer_discovery_nodes rabbitmq-0.rabbitmq.default.svc.cluster.local,rabbitmq-1.rabbitmq.default.svc.cluster.local,rabbitmq-2.rabbitmq.default.svc.cluster.local"
          volumeMounts:
            - name: rabbitmq-data
              mountPath: /var/lib/rabbitmq
  volumeClaimTemplates:
    - metadata:
        name: rabbitmq-data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 10Gi
           

-3 使用 kubectl 指令行工具運作 YAML 檔案,部署 RabbitMQ 叢集,例如:

kubectl apply -f rabbitmq.yaml
           

在這個 YAML 檔案中,我們定義了一個名為 rabbitmq 的 Kubernetes 服務和一個 StatefulSet 對象。在 StatefulSet 中,我們定義了 RabbitMQ 官方鏡像和一些環境變量,包括節點名稱、使用者名和密碼等。我們還指定了一個名為 rabbitmq-data 的持久卷,用于存儲 RabbitMQ 節點的資料。最後,我們使用 kubectl apply 指令來建立和管理 RabbitMQ 叢集。

需要注意的是,在部署 RabbitMQ 叢集時,我們需要確定每個節點都可以通路其他節點。Kubernetes 中有許多網絡插件和解決方案可以幫助我們實作此目的,例如 Kubernetes 自帶的 flannel 網絡插件或者第三方插件,如 Calico 等。同時,我們還需要考慮節點的資源限制和調優等問題。