RabbitMQ with Kubernetes

Running RabbitMQ on Kubernetes gives you automated deployment, self-healing, scaling, and rolling updates. The recommended approach is the official RabbitMQ Cluster Operator — a Kubernetes operator that manages RabbitMQ clusters as native Kubernetes resources, handling all the complex cluster formation, configuration, and lifecycle management automatically.

Why Use the RabbitMQ Cluster Operator

Managing a RabbitMQ cluster on Kubernetes manually is complex. You need StatefulSets, headless services, config maps, persistent volumes, and init containers — all coordinated correctly. The RabbitMQ Cluster Operator packages this complexity into a simple custom resource (RabbitmqCluster) that you declare like any other Kubernetes object.

Installing the RabbitMQ Cluster Operator

kubectl apply -f https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml

This installs the operator into the rabbitmq-system namespace. Verify it is running:

kubectl get pods -n rabbitmq-system
NAME                                         READY   STATUS    RESTARTS
rabbitmq-cluster-operator-7cbf865f97-xhg4k   1/1     Running   0

Creating a RabbitMQ Cluster

Define a RabbitmqCluster resource:

# rabbitmq-cluster.yaml
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
  name: my-rabbitmq
  namespace: default
spec:
  replicas: 3
  image: rabbitmq:3.12-management
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2
      memory: 2Gi
  persistence:
    storageClassName: standard
    storage: 10Gi
  rabbitmq:
    additionalPlugins:
      - rabbitmq_prometheus
      - rabbitmq_shovel
    additionalConfig: |
      cluster_partition_handling = pause_minority
      vm_memory_high_watermark.relative = 0.6
kubectl apply -f rabbitmq-cluster.yaml

The operator creates a StatefulSet with 3 replicas, a headless service for inter-node communication, persistent volume claims, and a configuration ConfigMap. Cluster formation happens automatically.

Monitoring the Cluster

# Check cluster status
kubectl get rabbitmqcluster my-rabbitmq

# Watch pods come up
kubectl get pods -l app.kubernetes.io/name=my-rabbitmq -w

# Check StatefulSet
kubectl get statefulsets
NAME           READY   AGE
my-rabbitmq    3/3     2m

Accessing the Management UI

The operator creates a service for the Management UI. Port-forward it to your local machine:

kubectl port-forward service/my-rabbitmq 15672:15672

Open http://localhost:15672. Get the default credentials from the secret the operator creates:

kubectl get secret my-rabbitmq-default-user -o jsonpath='{.data.username}' | base64 --decode
kubectl get secret my-rabbitmq-default-user -o jsonpath='{.data.password}' | base64 --decode

Connecting Applications to RabbitMQ

The operator creates a service named <cluster-name> that load-balances across all nodes. Applications in the same namespace connect using:

amqp://username:password@my-rabbitmq.default.svc.cluster.local:5672/

Inject the connection string into application pods using the operator's service binding or by reading the secret directly:

# deployment.yaml (excerpt)
env:
  - name: RABBITMQ_USERNAME
    valueFrom:
      secretKeyRef:
        name: my-rabbitmq-default-user
        key: username
  - name: RABBITMQ_PASSWORD
    valueFrom:
      secretKeyRef:
        name: my-rabbitmq-default-user
        key: password
  - name: RABBITMQ_HOST
    value: my-rabbitmq.default.svc.cluster.local

Scaling the Cluster

Change the replica count in the RabbitmqCluster spec and apply:

kubectl patch rabbitmqcluster my-rabbitmq --type='merge' \
  -p '{"spec":{"replicas":5}}'

The operator adds new nodes and forms them into the existing cluster automatically. Use an odd number of replicas (3, 5, 7) for quorum.

Upgrading RabbitMQ

Update the image tag in the spec and apply:

kubectl patch rabbitmqcluster my-rabbitmq --type='merge' \
  -p '{"spec":{"image":"rabbitmq:3.13-management"}}'

The operator performs a rolling restart — one node at a time — so the cluster stays available during the upgrade.

Persistent Storage

The operator creates a PersistentVolumeClaim (PVC) for each pod. Data survives pod restarts and rescheduling because Kubernetes reattaches the same PVC to the pod when it restarts, even if it lands on a different node (subject to storage class support).

Prometheus Monitoring

With rabbitmq_prometheus plugin enabled, scrape metrics using a ServiceMonitor (Prometheus Operator):

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: rabbitmq
  namespace: default
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: my-rabbitmq
  endpoints:
    - port: prometheus
      interval: 15s

High Availability with Quorum Queues on Kubernetes

Always use Quorum Queues when running on Kubernetes. Pod restarts and rescheduling are part of normal Kubernetes operations. Quorum Queues tolerate node failures automatically, making them the correct choice for the dynamic environment that Kubernetes creates.

# Application code: declare quorum queues
channel.queue_declare(
    queue='orders',
    durable=True,
    arguments={'x-queue-type': 'quorum'}
)

Topology Operator for Declarative Configuration

The RabbitMQ Topology Operator lets you manage queues, exchanges, bindings, users, and policies as Kubernetes custom resources:

kubectl apply -f https://github.com/rabbitmq/messaging-topology-operator/releases/latest/download/messaging-topology-operator-with-certmanager.yml
# queue.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:
  name: orders-queue
spec:
  name: orders
  durable: true
  rabbitmqClusterReference:
    name: my-rabbitmq
  arguments:
    x-queue-type: quorum

Summary

The RabbitMQ Cluster Operator is the recommended way to run RabbitMQ on Kubernetes. Install it with one kubectl apply command, then declare a RabbitmqCluster resource to create and manage clusters. The operator handles cluster formation, persistent storage, rolling upgrades, and scaling automatically. Connect applications using the service DNS name and credentials from the auto-generated secret. Always use Quorum Queues in Kubernetes for resilience against pod restarts and node rescheduling. Use the Topology Operator for declarative management of queues, exchanges, and bindings as Kubernetes resources.

Leave a Comment

Your email address will not be published. Required fields are marked *