This is the fastest way to get up and running with a RabbitMQ cluster deployed by the Cluster Operator. More detailed resources are available for installation, usage and API reference.
kubectl
configured to access the clusterThis guide goes through the following steps:
kubectl rabbitmq
PluginMany steps in the quickstart - installing the operator, accessing the Management UI, fetching credentials for the RabbitMQ Cluster, are made easier by the kubectl rabbitmq
plugin. While there are instructions to follow along without using the plugin, getting the plugin will make these commands simpler. To install the plugin, look at its installation instructions.
For extensive documentation on the plugin see the kubectl
Plugin guide.
Let's start by installing the latest version of the Cluster Operator. This can be done directly using kubectl apply
:
kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" # namespace/rabbitmq-system created # customresourcedefinition.apiextensions.k8s.io/rabbitmqclusters.rabbitmq.com created # serviceaccount/rabbitmq-cluster-operator created # role.rbac.authorization.k8s.io/rabbitmq-cluster-leader-election-role created # clusterrole.rbac.authorization.k8s.io/rabbitmq-cluster-operator-role created # rolebinding.rbac.authorization.k8s.io/rabbitmq-cluster-leader-election-rolebinding created # clusterrolebinding.rbac.authorization.k8s.io/rabbitmq-cluster-operator-rolebinding created # deployment.apps/rabbitmq-cluster-operator created
The Cluster Operator can also be installed using the kubectl rabbitmq
plugin:
kubectl rabbitmq install-cluster-operator
Installing the Cluster Operator creates a bunch of Kubernetes resources. Breaking these down, we have:
rabbitmq-system
. The Cluster Operator deployment is created in this namespace.kubectl get all -n rabbitmq-system NAME READY STATUS RESTARTS AGE pod/rabbitmq-cluster-operator-54f948d8b6-k79kd 1/1 Running 0 2m10s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/rabbitmq-cluster-operator 1/1 1 1 2m10s NAME DESIRED CURRENT READY AGE replicaset.apps/rabbitmq-cluster-operator-54f948d8b6 1 1 1 2m10s
rabbitmqclusters.rabbitmq.com
. The custom resource allows us to define an API for the creation of RabbitMQ Clusters.kubectl get customresourcedefinitions.apiextensions.k8s.io NAME CREATED AT ... rabbitmqclusters.rabbitmq.com 2021-01-14T11:12:26Z ...
Now that we have the Operator deployed, let's create the simplest RabbitMQ Cluster.
This example can be found in the Cluster Operator GitHub repo. As mentioned on the page:
This is the simplest
RabbitmqCluster
definition. The only explicitly specified property is the name of the cluster. Everything else will be configured according to the Cluster Operator's defaults.
The examples folder has many other references such as creating a RabbitMQ Cluster with TLS, mTLS, setting up a Cluster with production defaults, adding community plugins, etc.
Continuing with our example, we will submit the following yaml to Kubernetes:
apiVersion: rabbitmq.com/v1beta1 kind: RabbitmqCluster metadata: name: hello-world
Submit this using the following command:
kubectl apply -f https://raw.githubusercontent.com/rabbitmq/cluster-operator/main/docs/examples/hello-world/rabbitmq.yaml
This will create a RabbitMQ cluster called hello-world
in the current namespace. You can see the RabbitMQ Cluster as it is being created:
watch kubectl get all NAME READY STATUS RESTARTS AGE pod/hello-world-server-0 1/1 Running 0 2m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/hello-world ClusterIP 10.75.242.149 <none> 5672/TCP,15672/TCP 2m service/hello-world-nodes ClusterIP None <none> 4369/TCP,25672/TCP 2m service/kubernetes ClusterIP 10.75.240.1 <none> 443/TCP 4h1m NAME READY AGE statefulset.apps/hello-world-server 1/1 2m
If the pod is not running (its state is Pending
) and you are deploying to a resource-constrained cluster (eg. local environments like kind
or minikube
), you may need to adjust CPU and/or memory limits of the cluster. By default, the Operator configures RabbitmqCluster
pods to request 1CPU and 2GB of memory. Check the resource-limits example to see how to adjust these values.
You will also be able to see an instance of the rabbitmqclusters.rabbitmq.com
custom resource created.
kubectl get rabbitmqclusters.rabbitmq.com NAME AGE STATUS hello-world 4m1s
You may also use the kubectl rabbitmq plugin to list the RabbitMQ Clusters deployed:
kubectl rabbitmq list NAME AGE STATUS hello-world 4m10s
If your Pod is stuck in the Pending
state, most probably your cluster does not have a Physical Volume Provisioner. This can be verified as the following:
kubectl get pvc,pod NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistence-hello-world-server-0 Pending 30s
In this case, and if this is not a production environment, you might want to install the Local Path Provisioner
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml kubectl annotate storageclass local-path storageclass.kubernetes.io/is-default-class=true
After that, you need to remove and re-create the previously created RabbitMQ Cluster object:
kubectl delete rabbitmqclusters.rabbitmq.com hello-world
In order to make sure RabbitMQ has started correctly, let's view the RabbitMQ log file. This can be done by viewing the RabbitMQ pod logs. In this case, it would be:
kubectl logs hello-world-server-0 ... Starting RabbitMQ 3.8.9 on Erlang 23.2.1 Copyright (c) 2007-2022 VMware, Inc. or its affiliates. Licensed under the MPL 2.0. Website: https://rabbitmq.com ## ## RabbitMQ 3.8.9 ## ## ########## Copyright (c) 2007-2022 VMware, Inc. or its affiliates. ###### ## ########## Licensed under the MPL 2.0. Website: https://rabbitmq.com Doc guides: https://rabbitmq.com/documentation.html Support: https://rabbitmq.com/contact.html Tutorials: https://rabbitmq.com/getstarted.html Monitoring: https://rabbitmq.com/monitoring.html ...
If you care only about viewing the logs, the detail of the component is hidden away in the kubectl rabbitmq plugin. Here, you may just run:
kubectl rabbitmq tail hello-world
Next, let's access the Management UI.
username="$(kubectl get secret hello-world-default-user -o jsonpath='{.data.username}' | base64 --decode)" echo "username: $username" password="$(kubectl get secret hello-world-default-user -o jsonpath='{.data.password}' | base64 --decode)" echo "password: $password" kubectl port-forward "service/hello-world" 15672
Now we can open localhost:15672 in the browser and see the Management UI. The credentials are as printed in the commands above. Alternatively, you can run a curl
command to verify access:
curl -u$username:$password localhost:15672/api/overview {"management_version":"3.8.9","rates_mode":"basic", ...}
Using the kubectl rabbitmq
plugin, the Management UI can be accessed using:
kubectl rabbitmq manage hello-world
The next step would be to connect an application to the RabbitMQ Cluster in order to use its messaging capabilities. The perf-test application is frequently used within the RabbitMQ community for load testing RabbitMQ Clusters.
Here, we will be using the hello-world
service to find the connection address, and the hello-world-default-user
to find connection credentials.
username="$(kubectl get secret hello-world-default-user -o jsonpath='{.data.username}' | base64 --decode)" password="$(kubectl get secret hello-world-default-user -o jsonpath='{.data.password}' | base64 --decode)" service="$(kubectl get service hello-world -o jsonpath='{.spec.clusterIP}')" kubectl run perf-test --image=pivotalrabbitmq/perf-test -- --uri amqp://$username:$password@$service # pod/perf-test created
These steps are automated in the kubectl rabbitmq plugin which may simply be run as:
kubectl rabbitmq perf-test hello-world
We can now view the perf-test logs by running:
kubectl logs --follow perf-test ... id: test-141948-895, time: 16.001s, sent: 25651 msg/s, received: 25733 msg/s, min/median/75th/95th/99th consumer latency: 1346110/1457130/1495463/1529703/1542172 µs id: test-141948-895, time: 17.001s, sent: 26933 msg/s, received: 26310 msg/s, min/median/75th/95th/99th consumer latency: 1333807/1411182/1442417/1467869/1483273 µs id: test-141948-895, time: 18.001s, sent: 26292 msg/s, received: 25505 msg/s, min/median/75th/95th/99th consumer latency: 1329488/1428657/1455482/1502191/1518218 µs id: test-141948-895, time: 19.001s, sent: 23727 msg/s, received: 26055 msg/s, min/median/75th/95th/99th consumer latency: 1355788/1450757/1480030/1514469/1531624 µs id: test-141948-895, time: 20.001s, sent: 25009 msg/s, received: 25202 msg/s, min/median/75th/95th/99th consumer latency: 1327462/1447157/1474394/1509857/1521303 µs id: test-141948-895, time: 21.001s, sent: 28487 msg/s, received: 25942 msg/s, min/median/75th/95th/99th consumer latency: 1350527/1454599/1490094/1519461/1531042 µs ...
As can be seen, perf-test is able to produce and consume about 25,000 messages per second.
Now that you are up and running with the basics, you can explore what the Cluster Operator can do for you!
You can do so by: