This guide covers how to deploy Custom Resource objects that will be managed by the Messaging Topology Operator. If RabbitMQ Messaging Topology Operator is not installed, see the quickstart guide.
This guide has the following sections:
Note: Additional information about using the operator on Openshift can be found at [Using the RabbitMQ Kubernetes Operators on Openshift](./using-on-openshift.html).
Messaging Topology Operator can reconcile its objects in any namespace. However, by default, it will limit its interactions to RabbitmqCluster objects within same namespace as the topology object, for example Queue. In other words, Messaging Topology Operator will reconcile a Queue object, in namespace default, only if RabbitmqCluster object is also in namespace default.
This is the default behaviour, and it can be customised to allow a specific list of namespaces to allow reconciliation from. To create a list of allowed namespaces, the RabbitmqCluster object has to be annotated with key rabbitmq.com/topology-allowed-namespaces, and value a comma-separated list, without spaces, of namespace names; for example default,ns1,my-namespace. The value asterisk * can be used to allow all namespaces.
Any topology object can be declared to target a RabbitmqCluster in a different namespace using .spec.rabbitmqClusterReference.namespace. Topology objects within the same namespace as RabbitmqCluster are always allowed.
The following YAML declares a RabbitmqCluster object that allows topology objects from namespace my-app:
apiVersion: rabbitmq.com/v1beta1 kind: RabbitmqCluster metadata: name: example-rabbit namespace: rabbitmq-service annotations: rabbitmq.com/topology-allowed-namespaces: "my-app" spec: replicas: 1
Note that the above YAML specifies namespace rabbitmq-service. Then the following YAML will target the above RabbitMQ, from namespace my-app.
apiVersion: rabbitmq.com/v1beta1 kind: Queue metadata: name: test # name of this custom resource; does not have to the same as the actual queue name namespace: my-app spec: name: test-queue # name of the queue rabbitmqClusterReference: name: example-rabbit namespace: rabbitmq-service
If topology objects, for example Queue, target a RabbitmqCluster, and such RabbitmqCluster does not allow requests from the topology object's namespace, a status condition will be created with an error message, and the object will not be reconciled, until it is updated.
For example, RabbitmqCluster in namespace ns1 allows topologies from my-app, and topology object Queue in namespace not-allowed targets said RabbitmqCluster, Messaging Topology Operator will log an error message, update a status condition in the Queue object, and give up reconciling the Queue object. If the RabbitmqCluster object is updated to allow topology objects from namespace not-allowed, the Queue object must be manually updated to trigger a reconciliation; for example, by adding a label to the Queue object.
--- apiVersion: v1 kind: Secret metadata: name: my-rabbit-creds type: Opaque stringData: username: a-user # has to be an existing user password: a-secure-password uri: https://my.rabbit:15672 # uri for the management api; when scheme is not provided in uri, operator defaults to 'http' --- apiVersion: rabbitmq.com/v1beta1 kind: Queue metadata: name: qq-example spec: name: my-queue rabbitmqClusterReference: connectionSecret: name: my-rabbit-creds # has to an existing secret in the same namespace as this Queue object
Note that spec.rabbitmqClusterReference is an immutable field. You cannot update the connectionSecret name after creation.
Messaging Topology Operator can declare queues and policies in a RabbitMQ cluster.
The following manifest will create a queue named 'test' in the default vhost:
apiVersion: rabbitmq.com/v1beta1 kind: Queue metadata: name: test # name of this custom resource; does not have to the same as the actual queue name namespace: rabbitmq-system spec: name: test # name of the queue autoDelete: false durable: true rabbitmqClusterReference: name: example-rabbit
The following manifest will create a policy named 'lazy-queue' in default virtual host:
apiVersion: rabbitmq.com/v1beta1 kind: Policy metadata: name: policy-example # name of this custom resource namespace: rabbitmq-system spec: name: lazy-queue pattern: "^lazy-queue-" # matches any queue begins with "lazy-queue-" applyTo: "queues" definition: queue-mode: lazy rabbitmqClusterReference: name: example-rabbit
Note that it's not recommended setting optional queue arguments on queues directly. Once set, queue properties cannot be changed. Use policies instead.
The Messaging Topology repo has more examples on queues and policies.
Messaging Topology Operator can manage exchanges and bindings. The following manifest will create a fanout exchange:
apiVersion: rabbitmq.com/v1beta1 kind: Exchange metadata: name: fanout namespace: rabbitmq-system spec: name: fanout-exchange # name of the exchange type: fanout # default to 'direct' if not provided; can be set to 'direct', 'fanout', 'headers', and 'topic' autoDelete: false durable: true rabbitmqClusterReference: name: example-rabbit
The following manifest will create a binding between an exchange and a queue:
apiVersion: rabbitmq.com/v1beta1 kind: Binding metadata: name: binding namespace: rabbitmq-system spec: source: test # an existing exchange destination: test # an existing queue destinationType: queue # can be 'queue' or 'exchange' rabbitmqClusterReference: name: example-rabbit
More examples on exchanges and bindings.
You can use Messaging Topology Operator to create RabbitMQ users and assign user permissions. Learn more about user management in the Access Control guide.
Messaging Topology Operator creates users with generated credentials by default.
The following manifest will create a user with generated username and password and the generated username and password can be accessed via a Kubernetes secret object:
apiVersion: rabbitmq.com/v1beta1 kind: User metadata: name: user-example namespace: rabbitmq-system spec: tags: - policymaker rabbitmqClusterReference: name: example-rabbitmq
To get the name of the kubernetes secret object that contains the generated username and password, run the following command:
kubectl get users.rabbitmq.com user-example -o jsonpath='{.status.credentials.name}'
Note that the Operator does not monitor the generated secret object and updating the secret object won't update the credentials. As a workaround, add a label or annotation to users.rabbitmq.com object to trigger the Operator to reconcile.
The Operator also supports creating RabbitMQ users with provided credentials. When creating a user with provided username and password, create a kubernetes secret object contains keys username and password in its Data field. The Operator does not monitor the provided secret object and updating the secret object won't update the credentials. As a workaround, add a label or annotation to users.rabbitmq.com object to trigger the Operator to reconcile.
The following manifest will create a user with username and password provided from secret 'my-rabbit-user' :
apiVersion: rabbitmq.com/v1beta1 kind: User metadata: name: import-user-sample spec: tags: - policymaker - monitoring # other available tags are 'management' and 'administrator' rabbitmqClusterReference: name: rabbit-example importCredentialsSecret: name: my-rabbit-user # name of the secret
To set user permissions on an existing user, create permissions.rabbitmq.com resources. The following example will assign permissions to user rabbit-user-1:
apiVersion: rabbitmq.com/v1beta1 kind: Permission metadata: name: rabbit-user-1-permission namespace: rabbitmq-system spec: vhost: "/" user: "rabbit-user-1" # name of the RabbitMQ user permissions: write: ".*" configure: ".*" read: ".*" rabbitmqClusterReference: name: sample
More examples on users and permissions.
Messaging Topology Operator can create virtual hosts.
The following manifest will create a vhost named 'test' in a RabbitmqCluster named 'example-rabbit':
apiVersion: rabbitmq.com/v1beta1 kind: Vhost metadata: name: test-vhost # name of this custom resource namespace: rabbitmq-system spec: name: test # name of the vhost rabbitmqClusterReference: name: example-rabbit
Messaging Topology Operator can define Federation upstreams.
Because a Federation upstream URI contains credentials, it is provided through a Kubernetes Secret object. The 'uri' key is mandatory for the Secret object. Its value can be either a single URI or a comma-separated list of URIs.
The following manifest will define an upstream named 'origin' in a RabbitmqCluster named 'example-rabbit':
apiVersion: rabbitmq.com/v1beta1 kind: Federation metadata: name: federation-example namespace: rabbitmq-system spec: name: "origin" uriSecret: # secret must be created in the same namespace as this Federation object; in this case 'rabbitmq-system' name: {secret-name} ackMode: "on-confirm" rabbitmqClusterReference: name: example-rabbit
More federation examples.
Messaging Topology Operator can declare dynamic Shovels.
Shovel source and destination URIs are provided through a Kubernetes Secret object. The Secret Object must contain two keys, 'srcUri' and 'destUri', and the value of each key can be either a single URI or a comma-separated list of URIs.
The following manifest will create a Shovel named 'my-shovel' in a RabbitmqCluster named 'example-rabbit':
apiVersion: rabbitmq.com/v1beta1 kind: Shovel metadata: name: shovel-example namespace: rabbitmq-system spec: name: "my-shovel" uriSecret: # secret must be created in the same namespace as this Shovel object; in this case 'rabbitmq-system' name: {secret-name} srcQueue: "the-source-queue" destQueue: "the-destination-queue" rabbitmqClusterReference: name: example-rabbit
More shovels examples.
Some custom resource properties are immutable. Messaging Topology Operator implements validating webhooks to prevent updates on immutable fields. Forbidden updates will be rejected. For example:
kubectl apply -f test-queue.yaml Error from server (Forbidden): ... Resource: "rabbitmq.com/v1beta1, Resource=queues", GroupVersionKind: "rabbitmq.com/v1beta1, Kind=Queue" Name: "example", Namespace: "rabbitmq-system" for: "test-queue.yaml": admission webhook "vqueue.kb.io" denied the request: Queue.rabbitmq.com "example" is forbidden: spec.name: Forbidden: updates on name, vhost, and rabbitmqClusterReference are all forbidden
Properties that cannot be updated is documented in the Messaging Topology Operator API docs.
Deleting custom resources will delete the corresponding resources in the RabbitMQ cluster. Messaging Topology Operator sets kubernetes finalizers on all custom resources. If the object has already been deleted in the RabbitMQ cluster, or the RabbitMQ cluster has been deleted, Messaging Topology Operator will delete the custom resource without trying to delete the RabbitMQ object.
Messaging Topology Operator does not work for RabbitmqCluster deployed with importing definitions. The Operator reads the default user secret set in RabbitmqCluster status status.binding, if the RabbitmqCluster is deployed with imported definitions, definitions will overwrite the default user credentials and may cause Messaging Topology Operator not be able to access the RabbitmqCluster. To get around this issue, either you can create a RabbitmqCluster without importing definitions, or you can manually update the default user kubernetes secret to the actual user credentials set in the definitions.
If the RabbitmqClusters managed by the Messaging Topology Operator are configured to serve the Management over HTTPS, there are some additional steps required to configure Messaging Topology Operator. Follow this TLS dedicated guide to configure the Operator.
If the RabbitmqClusters managed by the Messaging Topology Operator are configured to store their default user credentials in Vault, there are some additional steps requires to configure Messaging Topology Operator. Follow this Vault dedicated guide to configure the operator.
Messaging Topology Operator logs reconciliation results and errors. Operator logs can be inspected by kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=messaging-topology-operator. It uses zap logger which can be configured via passing command line flags in the Operator deployment manifest.
For example, to configure the log level to 'debug':
apiVersion: apps/v1 kind: Deployment metadata: name: messaging-topology-operator namespace: rabbitmq-system spec: template: spec: containers: - args: - --zap-log-level=debug command: - /manager
Other available command line flags for the zap logger can be found documented in controller runtime.
By default, Messaging Topology Operator reconciles topology objects when there are create/update/delete events for that particular custom resource. From version 1.6.0, you can configure the Operator to perform reconciliation for all topology objects in a specific frequency by setting an environment variable in the Operator deployment:
apiVersion: apps/v1 kind: Deployment metadata: [...] name: messaging-topology-operator namespace: rabbitmq-system spec: template: spec: containers: - command: - /manager env: - name: SYNC_PERIOD value: 5m # needs to be in a format that's readable by golang time.ParseDuration(), e.g. “1000s”, “5.3h” or “20h35m” ...
Recreating a deleted queue will not recovery any messages.
Note that this frequency applies to all topology objects managed by the Operator. Depending on how many objects you've created with Topology Operator, reconciling all objects in a frequency could cause unnecessary load on both the Operator and the RabbitMQ server. Only use this feature if time based reconciliation is required for your use case.
If you have questions about the contents of this guide or any other topic related to RabbitMQ, don't hesitate to ask them on the RabbitMQ mailing list.
If you'd like to contribute an improvement to the site, its source is available on GitHub. Simply fork the repository and submit a pull request. Thank you!