The module lifecycle stage: Preview
The module has requirements for installation
A RabbitMQ instance is described by a Rabbit object in your namespace. The module deploys one RabbitMQ server for each Rabbit object and creates a Service and a Secret with credentials for connecting to it.
Quick start
To deploy a RabbitMQ instance with the default class, follow these steps:
-
Create a namespace for the instance or choose an existing one, for example
rabbit. -
Save the following manifest to the
rabbit-sample.yamlfile:apiVersion: managed-services.deckhouse.io/v1alpha1 kind: Rabbit metadata: name: rabbit-sample spec: rabbitClassName: default configuration: maxMessageSize: 16Mi instance: memory: size: 512Mi cpu: cores: 1 coreFraction: "50%" persistentVolumeClaim: size: 1Gi -
Apply the manifest:
d8 k -n rabbit apply -f rabbit-sample.yaml -
Wait until the instance is ready:
d8 k -n rabbit wait rabbit/rabbit-sample --for=condition=LastValidConfigurationApplied --timeout=10m -
Connect your application to the
d8ms-rmq-rabbit-sampleService on port5672with the credentials from thed8ms-rmq-rabbit-sample-user-secretSecret. The details are in Connecting to RabbitMQ.
Choosing a class
The class sets the allowed instance sizes, the RabbitMQ settings you can change and the nodes where RabbitMQ runs.
Specify the class name in the spec.rabbitClassName parameter.
If the parameter is not set, the default class is used.
To list the available classes, run the following command:
d8 k get rabbitclassesTo see the limits of a class, run the following command:
d8 k get rabbitclass <CLASS_NAME> -o yamlThe limits are described in the sizingPolicies, validations and overridableConfiguration parameters of the class.
If the class does not exist, the module accepts the Rabbit object with a warning,
but does not deploy RabbitMQ until the class is created.
Setting CPU and memory
The resources of the RabbitMQ pod are set in the spec.instance section:
spec:
instance:
cpu:
cores: 2
coreFraction: "50%"
memory:
size: 2GiThe module sets the pod resources as follows:
| Resource | Limit | Request |
|---|---|---|
| CPU | cores |
cores multiplied by coreFraction |
| Memory | memory.size |
memory.size |
The class checks the values when you create or change the object:
coresmust fall within thecoresrange of one of the class sizing policies. The first matching policy is used for the other checks.memory.sizemust fall within thememoryrange of that policy and be a multiple of itsstep.coreFractionmust be one of thecoreFractionsvalues of that policy, written in the same form, for example"50%".- The values must satisfy every CEL rule in the
validationsparameter of the class.
The module passes memory.size to RabbitMQ as the amount of available memory
and sets the memory watermark, at which RabbitMQ blocks publishers, to 60% of this value.
Configuring storage
RabbitMQ stores messages and metadata on a persistent volume
described in the spec.instance.persistentVolumeClaim section:
spec:
instance:
persistentVolumeClaim:
size: 10Gi
storageClassName: <STORAGE_CLASS_NAME>Replace <STORAGE_CLASS_NAME> with the name of a StorageClass in the cluster.
If storageClassName is not set, the default StorageClass of the cluster is used.
Storage follows these rules:
- The storage class is fixed when the volume is created. A later change of
storageClassNameis not applied. - The volume size can only be increased. The StorageClass must allow volume expansion. A smaller value is ignored.
- Without the
persistentVolumeClaimsection, the module creates no volume, and the data is lost when the pod restarts.
The volume belongs to the Rabbit object. When you delete the Rabbit object, the volume and all RabbitMQ data are deleted too.
Changing RabbitMQ settings
The RabbitMQ settings are set in the spec.configuration section:
spec:
configuration:
maxMessageSize: 16MiThe maxMessageSize parameter sets the largest allowed message size. RabbitMQ rejects larger messages.
You can set it only if the class lists it in the overridableConfiguration parameter; the default class allows it.
Other RabbitMQ settings are set by the administrator in the class.
Enabling TLS
With TLS, RabbitMQ accepts only encrypted AMQPS connections on port 5671, and port 5672 is closed.
TLS is set in the spec.tls section; without this section, TLS is disabled.
The server certificate must contain the following DNS names,
where <NAME> is the Rabbit object name and <NAMESPACE> is its namespace:
d8ms-rmq-<NAME>;d8ms-rmq-<NAME>.<NAMESPACE>;d8ms-rmq-<NAME>.<NAMESPACE>.svc;d8ms-rmq-<NAME>.<NAMESPACE>.svc.<CLUSTER_DOMAIN>, where<CLUSTER_DOMAIN>is the cluster domain,cluster.localby default.
Clients can connect without a client certificate.
If a client presents a certificate, RabbitMQ verifies it against the CA certificate from ca.crt.
Certificate from cert-manager
In the CertManager mode,
the module requests the certificate from cert-manager and puts the DNS names listed above into it.
This mode requires the cert-manager module: enable it if it is disabled.
Specify either a ClusterIssuer or an Issuer from the namespace of the Rabbit object:
spec:
tls:
mode: CertManager
certManager:
clusterIssuerName: <CLUSTER_ISSUER_NAME>To use an Issuer, replace clusterIssuerName with issuerName.
The issuer must put the CA certificate into the ca.crt key of the certificate Secret.
The module starts RabbitMQ after cert-manager has issued the certificate.
Your own certificate
In the CustomCertificate mode, RabbitMQ uses certificates from Secrets in the namespace of the Rabbit object:
spec:
tls:
mode: CustomCertificate
customCertificate:
serverTLSSecret: <TLS_SECRET_NAME>
serverCASecret: <CA_SECRET_NAME>Replace the placeholders:
<TLS_SECRET_NAME>: Secret of thekubernetes.io/tlstype with the server certificate intls.crtand its key intls.key.<CA_SECRET_NAME>: Secret with the CA certificate in theca.crtkey.
Certificate state
The status.certificate.server section of the Rabbit object shows the state of the server certificate:
ttl: number of days until the certificate expires;failed:trueif the certificate cannot be read.
Connecting to RabbitMQ
The module creates the following objects for connecting to the instance, where <NAME> is the Rabbit object name:
- Service
d8ms-rmq-<NAME>with port5672, or port5671with TLS; - Secret
d8ms-rmq-<NAME>-user-secretwith theusernameandpasswordkeys.
The user from the Secret has full permissions on the / virtual host.
The password is generated when the Rabbit object is created and does not change.
To get the password, run the following command:
d8 k -n <NAMESPACE> get secret d8ms-rmq-<NAME>-user-secret -o jsonpath='{.data.password}' | base64 -dAn application in the cluster connects with the following URI:
amqp://<USERNAME>:<PASSWORD>@d8ms-rmq-<NAME>.<NAMESPACE>.svc:5672/With TLS, use the amqps scheme and port 5671.
The password can contain the !@#$%^&* characters: URL-encode it in the URI.
Checking the status
The state of the instance is shown in the status.conditions list of the Rabbit object.
To see the conditions, run the following command:
d8 k -n <NAMESPACE> get rabbit <NAME> -o jsonpath='{range .status.conditions[*]}{.type}{"\t"}{.status}{"\t"}{.reason}{"\t"}{.message}{"\n"}{end}'The instance is ready when all conditions are True:
| Condition | Meaning when True |
Reasons when False |
|---|---|---|
ConfigurationValid |
The current object specification passed the class checks | RulesValidationFailed, ValidationFailed |
ScaledToLastValidConfiguration |
The RabbitMQ pod is ready and runs the last valid configuration | ScaleError, NotScaled |
Available |
RabbitMQ accepts connections | NotServing |
LastValidConfigurationApplied |
The last valid configuration is applied, and RabbitMQ is available. This is the summary condition | Syncing while changes are applied, or <OBJECT>ReconciliationFailed if the module cannot create a Kubernetes object |
Each False condition has a reason and a message that describe the problem.
If a change of the object does not pass the checks, RabbitMQ keeps running with the last valid configuration.
This configuration is shown in the status.lastValidConfiguration section.
Troubleshooting
This section lists typical errors, their causes and fixes.
Object is rejected with a sizing error
The module rejects a Rabbit object whose resources do not match the class. The error message contains one of the following texts:
| Message | Cause | Fix |
|---|---|---|
cpu does not fit any of Sizing Policies of the chosen Class |
cores is outside the ranges of all sizing policies |
Choose cores within a range from sizingPolicies of the class |
memory setting does not fit selected ... Class in range |
memory.size is outside the range of the matching policy |
Choose memory.size within the range; the limits are shown in bytes |
memory setting does not fit Step |
memory.size is not a multiple of step |
Round memory.size to a multiple of step |
core fraction does not match array in selected ... Class |
coreFraction is not in coreFractions |
Use one of the coreFractions values in the same form, for example "50%" |
Object is rejected because of a setting
The message restricted to override by administrator means that the class does not allow the setting you changed in spec.configuration.
Remove the setting or choose a class that lists it in overridableConfiguration.
The message Message: <TEXT> means that the object does not satisfy a CEL rule of the class.
<TEXT> is the message of the rule.
Change the object so that it satisfies the rule.
Pod cannot be scheduled
The ScaledToLastValidConfiguration condition with the ScaleError reason
means that the RabbitMQ pod cannot be placed on any node.
The pod placement is set in the class by the administrator.
Check the pod events and contact the administrator:
d8 k -n <NAMESPACE> describe pod d8ms-rmq-<NAME>-0Object has no conditions
If a new Rabbit object has no conditions, the class it references probably does not exist.
When such an object is created,
the module shows the warning RabbitClass <CLASS_NAME> was not found yet, skipping validation.
Check the spec.rabbitClassName value, or ask the administrator to create the class.