要用 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 等。同時,我們還需要考慮節點的資源限制和調優等問題。