How do I set up a simple dockerized RabbitMQ cluster? - docker

I've been doing a bit of reading up about setting up a dockerized RabbitMQ cluster and google turns up all sorts of results for doing so on the same machine.
I am trying to set up a RabbitMQ cluster across multiple machines.
I have three machines with the names dockerswarmmodemaster1, dockerswarmmodemaster2 and dockerswarmmodemaster3
On the first machine (dockerswarmmodemaster1), I issue the following command:
docker run -d -p 4369:4369 -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 \
-p 25672:25672 --hostname dockerswarmmodemaster1 --name roger_rabbit \
-e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3-management
Now this starts up a rabbitMQ just fine, and I can go to the admin page on 15672 and see that it is working as expected.
I then SSH to my second machine (dockerswarmmodemaster2) and this is the bit I am stuck on. I have been trying variations on the following command:
docker run -d -p 4369:4369 -p 5671:5671 -p 5672:5672 -p 15671:15671 \
-p 15672:15672 -p 25672:25672 --name jessica_rabbit -e CLUSTERED=true \
-e CLUSTER_WITH=rabbit#dockerswarmmodemaster1 \
-e RABBITMQ_ERLANG_COOKIE='secret cookie here' \
rabbitmq:3-management
No matter what I try, the web page on both RabbitMQ machines says that there is no cluster under the 'cluster links' section. I haven't tried involving the third machine yet.
So - some more info:
The machine names are resolvable by DNS.
I have tried using the --net=host switch in the docker run command on both machines; no change.
I am not using docker swarm or swarm mode.
I do not have docker compose installed. I'd prefer not to use it if possible.
Is there any way of doing this from the docker run command or will I have to download the rabbit admin cli and manually join to the cluster?

You can use this plugin https://github.com/aweber/rabbitmq-autocluster to create a RabbitMQ docker cluster.
The plugin uses etcd2 or consul as service discovery, in this way you don't need to use the rabbitmqctl command line.
I used it with docker swarm, but it is not necessary.
Here is the result

The official container seems to not support environment variables CLUSTERED and CLUSTER_WITH. It supports only a list variables that are specified in RabbitMQ Configuration.
According to official Clustering Guide, one of possible solutions is via configuration file. Thus, you can just provide your own configuration to the container.
Modified default configuration in your case will look like:
[
{ rabbit, [
{ loopback_users, [ ] },
{ cluster_nodes, {['rabbit#dockerswarmmodemaster1'], disc }}
]}
].
Save this snippet to, for example, /home/user/rmq/rabbitmq.config.
Hint: If you want to see node in management console, you need to add another file /home/user/rmq/enabled_plugins with only string
[rabbitmq_management].
after that, your command will look like
docker run -d -p 4369:4369 -p 5671:5671 -p 5672:5672 -p 15671:15671 \
-p 15672:15672 -p 25672:25672 --name jessica_rabbit \
-v /home/user/rmq:/etc/rabbmitmq \
-e RABBITMQ_ERLANG_COOKIE='secret cookie here' \
rabbitmq:3-management
PS You may also need to consider setting environment variable RABBITMQ_USE_LONGNAME.

In order to create a cluster, all rabbitmq nodes that are to form up a cluster must be accessible (each one by others) by node name (hostname).
You need to specify a hostname for each docker container with --hostname option and to add /etc/host entries for all the other containers, this you can do with --add-host option or by manually editing /etc/hosts file.
So, here is the example for a 3 rabbitmq nodes cluster with docker containers (rabbitmq:3-management image).
First, create a network so that you can assign IPs: docker network create --subnet=172.18.0.0/16 mynet1. We are going to have the following:
3 docker containers named rab1con, rab2con and rab3con
IPs respectively will be 172.18.0.11 , -12 and -13
each of them will have the host name respectively rab1, rab2 and rab3
all of them must share the same erlang cookie
Spin up the first one
docker run -d --net mynet1 --ip 172.18.0.11 --hostname rab1 --add-host rab2:172.18.0.12 --add-host rab3:172.18.0.13 --name rab1con -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3-management
second one
docker run -d --net mynet1 --ip 172.18.0.12 --hostname rab2 --add-host rab1:172.18.0.11 --add-host rab3:172.18.0.13 --name rab2con -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3-management
last one
docker run -d --net mynet1 --ip 172.18.0.13 --hostname rab3 --add-host rab2:172.18.0.12 --add-host rab1:172.18.0.11 --name rab3con -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3-management
Then, in container rab2con, do
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit#rab1
rabbitmqctl start_app
and the same in rab3con and that's it.

Related

How to pass erlang.cookie in "docker run" after RABBITMQ_ERLANG_COOKIE got depricated

I want to start three RabbitMQ containers that will be joined together in a cluster. I want to keep it simple and not define complex Dockerfiles with specific volumes.
This is what I am doing right now:
docker network create rabbits
docker run -d --rm --net rabbits --hostname rabbit-1 --name rabbit-1 -p 8081:15672 -e RABBITMQ_ERLANG_COOKIE=ASDF rabbitmq:3.8-management
docker run -d --rm --net rabbits --hostname rabbit-2 --name rabbit-2 -p 8082:15672 -e RABBITMQ_ERLANG_COOKIE=ASDF rabbitmq:3.8-management
docker run -d --rm --net rabbits --hostname rabbit-3 --name rabbit-3 -p 8083:15672 -e RABBITMQ_ERLANG_COOKIE=ASDF rabbitmq:3.8-management
When I then try to tell the nodes to join each other with the following commands, I get an error message:
docker exec -it rabbit-2 rabbitmqctl stop_app
docker exec -it rabbit-2 rabbitmqctl reset
docker exec -it rabbit-2 rabbitmqctl join_cluster rabbit#rabbit-1
docker exec -it rabbit-2 rabbitmqctl start_app
docker exec -it rabbit-2 rabbitmqctl cluster_status
This results in:
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
However I do not know how to pass this switch. When I add this to the docker run command it does not work. So i thought maybe add this after the join_cluster command, but then the cookie is already set.
How do I need to change the docker run command?
In response to your and other questions about RABBITMQ_ERLANG_COOKIE, I opened this issue:
https://github.com/rabbitmq/rabbitmq-server/issues/7262
Currently you should use the environment variable and disregard the warning.
The best practice is to use docker compose and your own image based off of the official RabbitMQ images:
https://github.com/lukebakken/docker-rabbitmq-cluster/blob/main/docker-compose.yml
https://github.com/lukebakken/docker-rabbitmq-cluster/blob/main/rmq/Dockerfile
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
The RABBITMQ_ERLANG_COOKIE environment variable is no longer used in RabbitMQ starting from version 3.7.0. Instead, you can set the Erlang cookie value by using the -e option in the docker run command and setting the RABBITMQ_ERLANG_COOKIE environment variable to your desired value. Here's an example:
docker run -d --name rabbitmq -e RABBITMQ_ERLANG_COOKIE='your_cookie_value' rabbitmq:3
Alternatively, you can store the Erlang cookie in a file and mount it as a volume in your container. For example:
Create a file named erlang.cookie with your desired cookie value
echo 'your_cookie_value' > erlang.cookie
Start the RabbitMQ container, mounting the erlang.cookie file
docker run -d --name rabbitmq -v $(pwd)/erlang.cookie:/var/lib/rabbitmq/.erlang.cookie rabbitmq:3

Remote access to cassandra 4.0.1 using docker via cqlsh

My Environment:
Windows 10 Home
WSL2
Cassandra 4.0.1: Official Docker Image
Docker command:
docker run --name cassandra-node-0 -p 7000:7000 -p 7001:7001 -p 7199:7199 -p 9042:9042 -p 9160:9160 -e CASSANDRA_CLUSTER_NAME=MyCluster -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_DC=datacenter1 -e CASSANDRA_BROADCAST_ADDRESS=192.168.1.101 -d cassandra
CQLSH Command:
docker run -it -e CQLSH_HOST=$(docker inspect --format='{{ .NetworkSettings.IPAddress}}' cassandra-node-0) --name cassandra-client --entrypoint=cqlsh cassandra
I try to connect cassandra node using cqlsh where ubuntu in WSL2 in same pc.
I did not change all *.yaml file and only use Docker Env.
When I insert node's docker network ip to CQLSH_HOST, cqlsh is successfully connected node.
But, When I insert my private ip, public ip or 127.0.0.1, cqlsh is refused connection to node.
This shows the same issue when nodes from different networks connect.
I think I'm missing a setting of something Docker Env.
What settings am I missing?
[Update] I add some port fowarding rules in firewall but same issue.
[Update 2] docker ps -a result:
0.0.0.0:7000-7001->7000-7001/tcp, :::7000-7001->7000-7001/tcp, 0.0.0.0:7199->7199/tcp, :::7199->7199/tcp, 0.0.0.0:9042->9042/tcp, :::9042->9042/tcp, 0.0.0.0:9160->9160/tcp, :::9160->9160/tcp
Try adding --hostname and --network when you run Cassandra. For example:
$ docker run --rm -d
--name cassandra-node-0
--hostname cassandra-node-0
--network cassandra-node-0
You'll find that it's easier to connect via cqlsh by adding:
--network cassandra-node-0
-e CQLSH_HOST=cassandra-node-0
to your docker run command. Cheers!

How to create multiple Debezium connectores for mysql database

I am tring to connect multiple Debezium connectores for a mysql database and my configurations are as follows.
sudo docker run -it --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 debezium/zookeeper:1.5 &
sudo docker run -it --name kafka -p 9092:9092 --link zookeeper:zookeeper debezium/kafka:1.5 &
sudo docker run -it --name connect -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets -e STATUS_STORAGE_TOPIC=my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka debezium/connect:1.5 &
sudo docker run -it --name connect1 -p 8084:8084 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets -e STATUS_STORAGE_TOPIC=my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka debezium/connect:1.5 &
but when i tring to run second connector...following error occurred.
ERRO[0000] error waiting for container: context canceled
Can anyone help me with this please.
You're not running any connectors, only containers for workers.
One Kafka Connect worker can be used to submit more than one connector task via the HTTP server on port 8083
Regarding the commands shown, you do not need multiple containers unless you are trying to create a Connect worker cluster
In order to do so, they need the same topics and the same group id.
You'd also want -p 8084:8083 since you've not changed the server port. Also, rather than using &, you can do docker run -d, but using Docker Compose would make more sense here

Docker 1.12 swarm service add volumes

I've got a container running on one of my systems (outside of my Docker swarm) that links host directories as volumes:
docker run -d --name=plex --restart=always -v /plex/config:/config -v /movies:/movies --net=host -p 32400:32400 -e X_PLEX_TOKEN=$PLEXTOKEN wernight/plex-media-server:autoupdate
I'd like to get some high availability with my swarm so in case my Plex container goes down on one host it come up on another host. I'm using NFS for my mounts (movies and plex) and I've got them mounted on each host.
I've started with this:
docker service create --name plex --restart=any --mount /plex/config:/config --mount /movies:/movies -p 32400:32400 -e X_PLEX_TOKEN=$PLEXTOKEN wernight/plex-media-server:autoupdate
But this fails because mount is expecting a key=value pair. The documentation is sparse for not sure where to go from here. Without the mounts the service starts up fine.
What is the associated command to create a service that will bring up my "Plex" instance on other nodes in my swarm in case of a failure?
I tend to agree that the docs here are pretty thin. Here's the syntax I've seen so far:
docker service create --name plex --restart=any \
--mount type=bind,source=/plex/config,target=/config \
--mount type=bind,source=/movies,target=/movies \
-p 32400:32400 -e X_PLEX_TOKEN=$PLEXTOKEN \
wernight/plex-media-server:autoupdate
There's also some discussion on changing this format over on github.

Docker: what is the equivalent of the legacy --link parameter

I need to connect my db container with my server container. Now I just red about the legacy parameter --link, which works perfect
$> docker run -d -P --name rethinkdb1 rethinkdb
$> docker run -d --link rethinkdb:db my-server
But, if this parameter will be dropped eventually, how would I do something like the above ?
The docs says to use the docker network command instead (which is available since Docker 1.9.0 - 2015-11-03)
Instead of
$> docker run -d -P --name rethinkdb rethinkdb
$> docker run -d --link rethinkdb:rethinkdb my-server
you will now use
$> docker network create --name my-network
$> docker run -d -P --name rethinkdb1 --net=my-network rethinkdb
$> docker run -d --net=my-network my-server
Note that in the new form, container names are used, while before you were able to define an alias.
When two containers are part of the same network, their /etc/hosts file is updated so that you can use the container names instead of their IP addresses.

Resources