KubeMQ
DeployInstall

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-private
cd 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 storageclass

Replace: YOUR_KUBE_CONTEXT — your cluster's kubectl context, from kubectl config get-contexts.

You should see:

Output
HARNESS_OUTPUT_PENDING

Node 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-terms

Replace: YOUR_EMAIL, YOUR_NAME, YOUR_COMPANY — your work email, full name and company.

You should see:

Output
HARNESS_OUTPUT_PENDING

Type the emailed code yourself, never in chat.

kmq trial verify --request YOUR_REQUEST_ID

Replace: YOUR_REQUEST_ID — the request_id printed above.

You should see:

Output
HARNESS_OUTPUT_PENDING
kmq trial claim --request YOUR_REQUEST_ID

You should see:

Output
HARNESS_OUTPUT_PENDING

The 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.key

This file is a secret. Do not commit it, paste it into chat, or attach it to a support ticket.

kmq license import --file license.key

You should see:

Output
HARNESS_OUTPUT_PENDING

kmq 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:

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"
  }
}

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 10m

You should see:

Output
HARNESS_OUTPUT_PENDING

It creates the namespace, a license Secret and a management certificate Secret that kmq trusts.

kmq deploy plan --input prepared.json --out plan.json

You should see:

Output
HARNESS_OUTPUT_PENDING

Install the operator and the cluster

kmq deploy apply --plan plan.json --deadline 15m

You should see:

Output
HARNESS_OUTPUT_PENDING

After 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:

Output
HARNESS_OUTPUT_PENDING

Store 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.key

Replace: YOUR_LICENSE_REF — your license reference.

You should see:

Output
HARNESS_OUTPUT_PENDING

Create 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:

Output
HARNESS_OUTPUT_PENDING

Security: 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-next
helm repo update kubemq-next
helm upgrade --install kubemq-operator kubemq-next/kubemq-next \
  --kube-context YOUR_KUBE_CONTEXT \
  -n kubemq \
  --set operator.enabled=true \
  --set cluster.enabled=false \
  --wait

You should see:

Output
HARNESS_OUTPUT_PENDING

Install the cluster

In kubemq-private:

cluster-values.yaml
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.yaml

You should see:

Output
HARNESS_OUTPUT_PENDING

Then wait until every server is ready:

kubectl --context YOUR_KUBE_CONTEXT -n kubemq wait --for=condition=Ready kubemqclusters.next.kubemq.io/messaging --timeout=10m

You should see:

Output
HARNESS_OUTPUT_PENDING

Check the license:

kmq license --kube-context YOUR_KUBE_CONTEXT

You should see:

Output
HARNESS_OUTPUT_PENDING

Check 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

Terminal 2
kubectl --context YOUR_KUBE_CONTEXT -n kubemq port-forward pod/messaging-0 18080:8080

Replace: YOUR_KUBE_CONTEXT — your cluster's kubectl context.

You should see:

Output
HARNESS_OUTPUT_PENDING

Leave it running.

Sign in

kmq auth login --bootstrap --installation messaging --username admin --api-address https://127.0.0.1:18080

kmq reads the first password from the cluster and asks for a new one. You should see:

Output
HARNESS_OUTPUT_PENDING

Save 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-password
kmq auth login --username admin --api-address http://127.0.0.1:18080 --context-name messaging

Paste the contents of admin-password when kmq asks, then set a new password. You should see:

Output
HARNESS_OUTPUT_PENDING

Security: 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.

Point kmq at the cluster

kmq context use messaging

You should see:

Output
HARNESS_OUTPUT_PENDING

Send and receive

kmq queue send onboarding-check '{"id":1}'

You should see:

Output
HARNESS_OUTPUT_PENDING
kmq queue receive onboarding-check

You should see:

Output
HARNESS_OUTPUT_PENDING

Connect your applications

Applications inside the cluster use these Services, all ClusterIP:

InterfaceIn-cluster addressPort
gRPCmessaging-grpc.kubemq.svc.cluster.local50000
RESTmessaging-rest.kubemq.svc.cluster.local9090
Kafka-compatiblemessaging-kafka.kubemq.svc.cluster.local9092
RabbitMQ-compatible (AMQP 0-9-1)messaging-amqp.kubemq.svc.cluster.local5672

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 15m

Replace: YOUR_LICENSE_REF — the new reference.

You should see:

Output
HARNESS_OUTPUT_PENDING

Put 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 15m

You should see:

Output
HARNESS_OUTPUT_PENDING

Helm keeps the cluster resource, so delete it first:

kubectl --context YOUR_KUBE_CONTEXT -n kubemq delete kubemqclusters.next.kubemq.io messaging --wait
helm uninstall messaging --kube-context YOUR_KUBE_CONTEXT -n kubemq

Both keep the volumes and the operator. Remove the operator once no cluster uses it:

helm uninstall kubemq-operator --kube-context YOUR_KUBE_CONTEXT -n kubemq

Replace: 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:

management-certificate.yaml
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_ISSUER
kubectl --context YOUR_KUBE_CONTEXT -n kubemq apply -f management-certificate.yaml

Replace: 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_FILE

Replace: 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:

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-tls

Replace: YOUR_CA_FILE — your issuing authority's certificate.

You should see:

Output
HARNESS_OUTPUT_PENDING

If 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-0 says 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 file to every kmq trial, kmq license, kmq deploy and kmq auth command.
  • A server stops with a licensing message. kubectl --context YOUR_KUBE_CONTEXT -n kubemq logs messaging-0 prints a Troubleshooting link, such as #cluster-over-cap.

Next steps

Was this page helpful?

On this page