我们面临以下问题:如何在具有持久数据的 Docker-Swarm 中运行 RabbitMQ。
目前我们已实施以下设置:
- Docker-Swarm 3 节点
- GlusterFS 作为所有节点之间的复制文件系统
- RabbitMQ 与 Consul 图像:gavinmroy/alpine-rabbitmq-autocluster
大多数情况下这都可以正常工作..但现在我们必须使用持久队列来保存数据。
我们尝试使用 --hostnames 或设置 RABBITMQ_NODENAME,然后我们会为每个启动节点获得一个子目录,如“rabbit@CONTAINERID”,问题是:当重新启动容器时,会使用一个新文件夹来保存数据(新的 ContainerID)..有什么建议如何使用 Docker Swarm 功能来获得一个有效的设置?
答案1
尽管这已经沉寂了一段时间:但这就是我们所使用的。
docker-compose.yaml:
version: "3.6"
services:
rabbitmq-01:
image: rabbitmq:3.8-management
hostname: rabbitmq-01
environment:
- RABBITMQ_ERLANG_COOKIE=<erlang-cookie-value>
secrets:
- source: main-config
target: /etc/rabbitmq/rabbitmq.conf
configs:
- source: definitions
target: /etc/rabbitmq/definitions.json
networks:
- main
- consul_main
volumes:
- rabbitmq-01-data:/var/lib/rabbitmq
deploy:
mode: global
placement:
constraints: [node.labels.rabbitmq1 == true]
rabbitmq-02:
image: rabbitmq:3.8-management
hostname: rabbitmq-02
environment:
- RABBITMQ_ERLANG_COOKIE=<erlang-cookie-value>
secrets:
- source: main-config
target: /etc/rabbitmq/rabbitmq.conf
configs:
- source: definitions
target: /etc/rabbitmq/definitions.json
networks:
- main
- consul_main
volumes:
- rabbitmq-02-data:/var/lib/rabbitmq
deploy:
mode: global
placement:
constraints: [node.labels.rabbitmq2 == true]
rabbitmq-03:
image: rabbitmq:3.8-management
hostname: rabbitmq-03
environment:
- RABBITMQ_ERLANG_COOKIE=<erlang-cookie-value>
secrets:
- source: main-config
target: /etc/rabbitmq/rabbitmq.conf
configs:
- source: definitions
target: /etc/rabbitmq/definitions.json
networks:
- main
- consul_main
volumes:
- rabbitmq-03-data:/var/lib/rabbitmq
deploy:
mode: global
placement:
constraints: [node.labels.rabbitmq3 == true]
secrets:
main-config:
file: secret.rabbitmq.conf
configs:
definitions:
file: definitions.json
networks:
main:
consul_main:
external: true
volumes:
rabbitmq-01-data:
rabbitmq-02-data:
rabbitmq-03-data:
rabbitmq.conf:
# The standard config that each cluster member gets
default_user = rmqadmin
# TODO Might wanna encrypt or use Docker secret into an env var
default_pass = <password>
default_vhost = /
loopback_users.admin = false
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_consul
cluster_formation.consul.host = consul.server
cluster_formation.node_cleanup.only_log_warning = true
cluster_formation.consul.svc_addr_auto = true
cluster_formation.consul.svc = rabbitmq-config-file
cluster_partition_handling = autoheal
# Flow Control is triggered if memory usage above %80.
vm_memory_high_watermark.relative = 0.8
# Flow Control is triggered if free disk size below 5GB.
disk_free_limit.absolute = 5GB
management.load_definitions = /etc/rabbitmq/definitions.json
定义.json从 https://your-rabbitmq-admin-ui/api/definitions 导出
请注意,rabbitmqs 以“全局”模式部署,然后限制为节点标签。
我们的集群中有三个节点带有“rabbitmqX”标签,如下所示:
$ dt node inspect node01 | grep -i -C 20 label
[
{
...
"Spec": {
"Labels": {
"rabbitmq1": "true"
},
},
...
}
一个为“rabbitmq1”:“true”,另一个为“rabbitmq2”:“true”,最后一个为“rabbitmq3”:“true”。
因此,这三个节点上各部署了一个 RMQ 实例,所以我们最终得到一个 3 节点 RMQ 集群,三个 Docker Swarm 成员上各有一个节点。
Consul 已到位,可通过“consul.server”访问,以供 RMQ 节点用作集群后端。
这将解决 RMQ 使用其容器主机名创建其数据目录的问题,因为主机名在 docker-compose 文件中固定为“rabbitmq-0X”。
希望这对任何来的人都有帮助!
答案2
是的,你可以设置RabbitMQ 集群作为单个 Docker Swarm 服务。无需使用 GlusterFS 在所有节点之间复制数据。每个 RabbitMQ 副本将单独存储其数据。
(免责声明)我写了这篇文章。