Install on Kubernetes
Install the KubeMQ operator and a three-server cluster with kmq or Helm, add your license, check it, send a test message and connect your apps.
This page shows how to install the KubeMQ operator and a cluster of three servers on Kubernetes, with kmq or with Helm. When you finish, kmq license reports the license on every server, a test message round-trips, and you know the address your applications use. Time: about 30 minutes.
Hardening for production traffic is on the Production checklist.
These commands are for bash on macOS and Linux. On Windows, run them in WSL (Windows Subsystem for Linux), or use the kmq tab of Try KubeMQ, which runs natively on Windows.
The cluster messaging, as the operator runs it:
Before you start
Create a private folder, readable only by you, and work inside it:
mkdir -p -m 700 kubemq-privatecd kubemq-private- kubectl and Helm, with a context for the target cluster. The kmq tab runs them for you.
- kmq, installed as in Try KubeMQ. Both tabs use it.
- Permission to create custom resource definitions and cluster roles.
- A storage class that creates volumes on demand. Note its name:
kubectl --context YOUR_KUBE_CONTEXT get storageclassReplace: YOUR_KUBE_CONTEXT — your cluster's kubectl context, from kubectl config get-contexts.
You should see:
HARNESS_OUTPUT_PENDINGNode and network needs: Requirements and supported setups.
Add your license
--accept-terms records that you accept the trial terms and the privacy notice; an AI agent must ask you first.
kmq trial request --email YOUR_EMAIL --name "YOUR_NAME" --company "YOUR_COMPANY" --platform kubernetes --accept-termsReplace: YOUR_EMAIL, YOUR_NAME, YOUR_COMPANY — your work email, full name and company.
You should see:
HARNESS_OUTPUT_PENDINGType the emailed code yourself, never in chat.
kmq trial verify --request YOUR_REQUEST_IDReplace: YOUR_REQUEST_ID — the request_id printed above.
You should see:
HARNESS_OUTPUT_PENDINGkmq trial claim --request YOUR_REQUEST_IDYou should see:
HARNESS_OUTPUT_PENDINGThe key covers one cluster of 3 servers and binds to the first cluster it starts on; to move it, contact KubeMQ through Plans compared.
Use the key from your KubeMQ order email. It must cover at least 3 servers.
Save the license key as license.key in this folder. The file holds only the key, on one line, with no quotes and no KUBEMQ_LICENSE_KEY= prefix. Then make it readable by you alone:
chmod 600 license.keyThis file is a secret. Do not commit it, paste it into chat, or attach it to a support ticket.
kmq license import --file license.keyYou should see:
HARNESS_OUTPUT_PENDINGkmq printed a license reference, credential or reference. The kmq tab uses it and creates its own license Secret; Helm step 2 stores license.key as the Secret messaging-license, exporting a trial key first.
Steps
Write the install file
In kubemq-private:
{
"schema_version": 1,
"goal": "production",
"target": "kubernetes",
"name": "messaging",
"credential": "YOUR_LICENSE_REF",
"kubernetes": {
"context": "YOUR_KUBE_CONTEXT",
"namespace": "kubemq",
"operator_release": "kubemq-operator",
"cluster_release": "messaging",
"server_count": 3,
"storage_class": "YOUR_STORAGE_CLASS",
"volume_size": "20Gi"
}
}Replace: YOUR_LICENSE_REF — your license reference; YOUR_KUBE_CONTEXT — your cluster's kubectl context; YOUR_STORAGE_CLASS — the storage class you noted.
Check the cluster and save a plan
kmq deploy prepare --input kubernetes.json --out prepared.json --deadline 10mYou should see:
HARNESS_OUTPUT_PENDINGIt creates the namespace, a license Secret and a management certificate Secret that kmq trusts.
kmq deploy plan --input prepared.json --out plan.jsonYou should see:
HARNESS_OUTPUT_PENDINGInstall the operator and the cluster
kmq deploy apply --plan plan.json --deadline 15mYou should see:
HARNESS_OUTPUT_PENDINGAfter an interruption, run it again; it resumes.
Create the namespace
kubectl --context YOUR_KUBE_CONTEXT create namespace kubemq --dry-run=client -o yaml | kubectl --context YOUR_KUBE_CONTEXT apply -f -You should see:
HARNESS_OUTPUT_PENDINGStore the license as a Secret
With a trial key, export it first (delete an old license.key; kmq never overwrites):
kmq license export --credential YOUR_LICENSE_REF --out license.keyReplace: YOUR_LICENSE_REF — your license reference.
You should see:
HARNESS_OUTPUT_PENDINGCreate the Secret; the same command replaces it:
kubectl --context YOUR_KUBE_CONTEXT -n kubemq create secret generic messaging-license --from-file=licenseKey=license.key --dry-run=client -o yaml | kubectl --context YOUR_KUBE_CONTEXT apply -f -You should see:
HARNESS_OUTPUT_PENDINGSecurity: keep the key out of Helm values
Never use --set licenseKey=, --from-literal or a key in cluster-values.yaml: Helm stores values in the cluster.
Install the operator
helm repo add kubemq-next https://kubemq-io.github.io/charts-nexthelm repo update kubemq-nexthelm upgrade --install kubemq-operator kubemq-next/kubemq-next \
--kube-context YOUR_KUBE_CONTEXT \
-n kubemq \
--set operator.enabled=true \
--set cluster.enabled=false \
--waitYou should see:
HARNESS_OUTPUT_PENDINGInstall the cluster
In kubemq-private:
operator:
enabled: false
cluster:
enabled: true
fullnameOverride: messaging
replicas: 3
licenseKeySecretRef:
name: messaging-license
key: licenseKey
volume:
size: 20Gi
storageClass: YOUR_STORAGE_CLASS
api:
expose: ClusterIP
auth:
enable: true
adminUsername: admin
env:
STORE_NEXT_ACK_POLICY: "strict"Replace: YOUR_STORAGE_CLASS — the storage class you noted.
License fields, resources and node spread: Deployment & High Availability.
helm upgrade --install messaging kubemq-next/kubemq-next \
--kube-context YOUR_KUBE_CONTEXT \
-n kubemq \
-f cluster-values.yamlYou should see:
HARNESS_OUTPUT_PENDINGThen wait until every server is ready:
kubectl --context YOUR_KUBE_CONTEXT -n kubemq wait --for=condition=Ready kubemqclusters.next.kubemq.io/messaging --timeout=10mYou should see:
HARNESS_OUTPUT_PENDINGCheck the license:
kmq license --kube-context YOUR_KUBE_CONTEXTYou should see:
HARNESS_OUTPUT_PENDINGCheck for one row per server, messaging-0 to messaging-2, each active with the same PLAN and EXPIRES. Any other state needs attention: How licensing works.
Send a test message
Open the management port
kubectl --context YOUR_KUBE_CONTEXT -n kubemq port-forward pod/messaging-0 18080:8080Replace: YOUR_KUBE_CONTEXT — your cluster's kubectl context.
You should see:
HARNESS_OUTPUT_PENDINGLeave it running.
Sign in
kmq auth login --bootstrap --installation messaging --username admin --api-address https://127.0.0.1:18080kmq reads the first password from the cluster and asks for a new one. You should see:
HARNESS_OUTPUT_PENDINGSave the first password in kubemq-private:
kubectl --context YOUR_KUBE_CONTEXT -n kubemq get secret messaging-api-admin -o jsonpath='{.data.admin-password}' | base64 -d > admin-passwordkmq auth login --username admin --api-address http://127.0.0.1:18080 --context-name messagingPaste the contents of admin-password when kmq asks, then set a new password. You should see:
HARNESS_OUTPUT_PENDINGSecurity: use the admin password only
The Secret's operator-token key belongs to the operator. Never use it.
If kmq reports Management connection failed, check that Terminal 2 is still running, then run the command again.
Send and receive
kmq queue send onboarding-check '{"id":1}'You should see:
HARNESS_OUTPUT_PENDINGkmq queue receive onboarding-checkYou should see:
HARNESS_OUTPUT_PENDINGConnect your applications
Applications inside the cluster use these Services, all ClusterIP:
| Interface | In-cluster address | Port |
|---|---|---|
| gRPC | messaging-grpc.kubemq.svc.cluster.local | 50000 |
| REST | messaging-rest.kubemq.svc.cluster.local | 9090 |
| Kafka-compatible | messaging-kafka.kubemq.svc.cluster.local | 9092 |
| RabbitMQ-compatible (AMQP 0-9-1) | messaging-amqp.kubemq.svc.cluster.local | 5672 |
From outside Kubernetes: Interfaces (gRPC · REST · API · HTTP). Client code: Client SDKs.
Replace the license later
Get the new license as in Add your license.
kmq deploy update --installation messaging --credential YOUR_LICENSE_REF --deadline 15mReplace: YOUR_LICENSE_REF — the new reference.
You should see:
HARNESS_OUTPUT_PENDINGPut the new key in license.key and run the Secret command from Helm step 2 again.
The operator restarts the servers one at a time, keeping their data; an online key needs internet access meanwhile. Then run the wait and kmq license commands again. If a server does not become ready, put the previous license back and see Troubleshooting.
Remove the cluster
kmq deploy remove --installation messaging --deadline 15mYou should see:
HARNESS_OUTPUT_PENDINGHelm keeps the cluster resource, so delete it first:
kubectl --context YOUR_KUBE_CONTEXT -n kubemq delete kubemqclusters.next.kubemq.io messaging --waithelm uninstall messaging --kube-context YOUR_KUBE_CONTEXT -n kubemqBoth keep the volumes and the operator. Remove the operator once no cluster uses it:
helm uninstall kubemq-operator --kube-context YOUR_KUBE_CONTEXT -n kubemqReplace: YOUR_KUBE_CONTEXT — your cluster's kubectl context.
Data loss: volumes and namespace
Deleting the volume claims or the namespace deletes every message and the cluster's identity. Keep your administrator password; a cluster on these volumes needs it.
Use your own management certificate
For production, a management certificate your organization issues. On a first kmq install, create the namespace first (Helm step 1). With cert-manager:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: messaging-api
namespace: kubemq
spec:
secretName: messaging-api-tls
dnsNames:
- messaging-api.kubemq.svc
- messaging-api.kubemq.svc.cluster.local
ipAddresses:
- 127.0.0.1
issuerRef:
name: YOUR_ISSUERkubectl --context YOUR_KUBE_CONTEXT -n kubemq apply -f management-certificate.yamlReplace: YOUR_ISSUER — a cert-manager issuer in kubemq (for a cluster issuer, add kind: ClusterIssuer); YOUR_KUBE_CONTEXT — your cluster's kubectl context.
Without cert-manager, use files covering the same names and address:
kubectl --context YOUR_KUBE_CONTEXT -n kubemq create secret tls messaging-api-tls --cert=YOUR_TLS_CERT_FILE --key=YOUR_TLS_KEY_FILEReplace: YOUR_TLS_CERT_FILE — the certificate; YOUR_TLS_KEY_FILE — its key.
At first install only, before kmq step 2, add two fields to kubernetes.json:
{
"schema_version": 1,
"goal": "production",
"target": "kubernetes",
"name": "messaging",
"credential": "YOUR_LICENSE_REF",
"kubernetes": {
"context": "YOUR_KUBE_CONTEXT",
"namespace": "kubemq",
"operator_release": "kubemq-operator",
"cluster_release": "messaging",
"server_count": 3,
"storage_class": "YOUR_STORAGE_CLASS",
"volume_size": "20Gi",
"tls_secret": "messaging-api-tls",
"ca_file": "YOUR_CA_FILE"
}
}Replace: YOUR_CA_FILE — your issuing authority's certificate; YOUR_LICENSE_REF, YOUR_KUBE_CONTEXT, YOUR_STORAGE_CLASS — as in kmq step 1.
On a cluster kmq already installed, contact support.
Add tlsSecret: messaging-api-tls under api in cluster-values.yaml and apply it as the settings-change section of Kubernetes (Helm) shows. The servers restart: run the wait command again, restart the Terminal 2 port-forward, then sign in over HTTPS with your new password:
kmq auth login --username admin --api-address https://127.0.0.1:18080 --ca-file YOUR_CA_FILE --context-name messaging --service-name messaging-kmq-tlsReplace: YOUR_CA_FILE — your issuing authority's certificate.
You should see:
HARNESS_OUTPUT_PENDINGIf something goes wrong
Replace: YOUR_KUBE_CONTEXT — your cluster's kubectl context.
- Pods stay
Pending.kubectl --context YOUR_KUBE_CONTEXT -n kubemq describe pod messaging-0says why: usually storage or too few nodes; see Requirements and supported setups. ImagePullBackOff. The nodes cannot reach the registry; see Requirements and supported setups or Install air-gapped.credential_storage_unavailable. On Linux with no keyring, add--credential-backend fileto everykmq trial,kmq license,kmq deployandkmq authcommand.- A server stops with a licensing message.
kubectl --context YOUR_KUBE_CONTEXT -n kubemq logs messaging-0prints a Troubleshooting link, such as#cluster-over-cap.
Next steps
Was this page helpful?
Install with Docker
Keep the KubeMQ server you started with Docker: add a license key with docker run, Compose or Podman, check the license and remove it safely.
Install air-gapped
Install a KubeMQ cluster on Kubernetes with no internet access: download a verified bundle, mirror the images, apply an offline license file.