KubeMQ
Deploy

Install KubeMQ with Helm

Deploy KubeMQ to Kubernetes for production with the Helm charts and operator, with a production readiness checklist.

Prerequisites

Before you begin, ensure you have the following installed and configured:

  • Kubernetes cluster (v1.20 or later) — any distribution (EKS, GKE, AKS, k3s, minikube)
  • kubectl — configured to access your cluster
  • Helm v3 — download from helm.sh
  • KubeMQ license key — required for the cluster to start

Running KubeMQ for local development? Consider using Docker instead for a simpler setup.

How it works

KubeMQ ships four Helm charts. The standard install path is a 3-step sequence:

  1. kubemq-crds — CRD schema only. Registers the KubemqCluster (and KubemqConnector) resource types with Kubernetes. No workloads, no operator.
  2. kubemq-controller — The operator Deployment. Watches for KubemqCluster resources and reconciles StatefulSets, Services, and configuration.
  3. kubemq-cluster — Renders one KubemqCluster custom resource. This chart is a thin passthrough: nearly every Helm value you set becomes the identically-named field on the CR's spec, and the operator installed in step 2 does the actual reconciling.

A fourth chart, the umbrella kubemq chart, bundles CRDs + operator + one KubemqCluster CR into a single release — a one-shot alternative to running the three charts above in sequence. It requires only key (your license) to render.

All components are installed into the kubemq namespace.

Add the KubeMQ Helm repository

Register the KubeMQ Helm chart repository and update your local chart index.

The published chart channel is prerelease-only today. Every published chart version carries a -next.N suffix (for example 3.0.0-next.3), and Helm ignores prerelease versions unless you pass --devel. Every helm search, helm install, and helm upgrade command on this page needs --devel or it will fail to resolve a version.

This chart-version prerelease channel (-next.N, gated by --devel) is separate from the image-tag :next you'll see later on this page (the mutable operator/server container image tag) — don't confuse the two "next" channels.

Terminal
helm repo add kubemq-charts https://kubemq-io.github.io/charts
helm repo update

Verify the repository was added successfully:

Terminal
helm search repo kubemq-charts --devel

You should see charts for kubemq-crds, kubemq-controller, kubemq-cluster, and the umbrella kubemq chart.

Install KubeMQ

KubeMQ installation on Kubernetes requires three Helm charts installed in order: CRDs, the controller (operator), and the cluster itself.

Install KubeMQ CRDs

The Custom Resource Definitions must be installed first. They define the KubemqCluster resource type that the operator manages.

Terminal
helm install --create-namespace -n kubemq kubemq-crds kubemq-charts/kubemq-crds --devel

Install KubeMQ controller

The KubeMQ controller (operator) watches for KubemqCluster resources and manages the lifecycle of KubeMQ nodes.

Terminal
helm install --wait -n kubemq kubemq-controller kubemq-charts/kubemq-controller --devel

Install KubeMQ cluster

Deploy the KubeMQ cluster. Replace YOUR_LICENSE_KEY with your actual license key.

Terminal
helm install --wait -n kubemq kubemq-cluster kubemq-charts/kubemq-cluster \
  --set key=YOUR_LICENSE_KEY \
  --devel

By default, this creates a 3-node cluster. To deploy a single standalone node for development, add --set standalone=true.

Verify installation

Confirm that all KubeMQ pods are running and ready.

Terminal
kubectl get pods -n kubemq

Expected output:

NAME                                  READY   STATUS    RESTARTS   AGE
kubemq-controller-xxxxxxxxx-xxxxx     1/1     Running   0          2m
kubemq-cluster-0                      1/1     Running   0          1m
kubemq-cluster-1                      1/1     Running   0          1m
kubemq-cluster-2                      1/1     Running   0          1m

Check the services exposed by KubeMQ:

Terminal
kubectl get svc -n kubemq

To access the KubeMQ dashboard, port-forward the API service:

Terminal
kubectl port-forward -n kubemq svc/kubemq-cluster 8080:8080

Then open http://localhost:8080 in your browser.

Charts & images

ChartPurpose
kubemq-crdsRegisters the KubemqCluster / KubemqConnector CRD schemas — no workloads
kubemq-controllerThe operator Deployment
kubemq-clusterRenders one KubemqCluster CR (thin spec.* passthrough)
kubemq (umbrella)CRDs + operator + one CR in a single release (key required)

All four charts are on the prerelease channel today — pass --devel on every helm command (see the callout above).

Images and the :next channel

The kubemq-controller chart's operator and server images default to the mutable image-tag :nextoperatorImage and kubemqImage in the Controller chart values below. kubemqImage isn't consumed by the operator's own container — it feeds the operator's RELATED_IMAGE_KUBEMQ_CLUSTER environment variable, which is what the operator uses as the container image when it renders a KubemqCluster StatefulSet.

Configurable values

The snippets below are illustrative, one per chart — not exhaustive field tables. Field-by-field defaults and valid values for the KubemqCluster spec live in the Configuration Reference (linked throughout this section).

Controller chart values

values.yaml (kubemq-controller)
operatorImage: europe-docker.pkg.dev/kubemq/images/kubemq-operator:next
kubemqImage: europe-docker.pkg.dev/kubemq/images/kubemq:next
imagePullSecrets:
  - name: my-registry-secret

# Images for the connector workloads started by the operator
connectorTargetsImage: europe-docker.pkg.dev/kubemq/images/kubemq-targets:next
connectorSourcesImage: europe-docker.pkg.dev/kubemq/images/kubemq-sources:next
connectorBridgesImage: europe-docker.pkg.dev/kubemq/images/kubemq-bridges:next

connectorTargetsImage, connectorSourcesImage, and connectorBridgesImage set the images the operator uses for the Targets, Sources, and Bridges connector workloads. Pin these to your own registry mirror in production — don't rely on the chart's built-in default.

Cluster chart values

Only key (your license) and imagePullSecrets are native to this chart. Every other value is a verbatim passthrough to the KubemqCluster CR — a Helm value maps 1:1 to the spec.* field of the same name:

values.yaml (kubemq-cluster)
key: "YOUR_LICENSE_KEY"

# Everything below passes through as spec.* on the KubemqCluster CR —
# see the Configuration Reference for the full field list.
replicas: 3
volume:
  size: 50Gi

For the complete field list, see Deployment & High Availability and Storage Engines.

Umbrella chart values

Only key is chart-native, and it's required — the release fails to render without it. The operator image is hardcoded in the chart's template, not driven by operatorImage/kubemqImage:

values.yaml (kubemq)
key: "YOUR_LICENSE_KEY"

Any value you set in a values.yaml pins that field permanently — once active, the server's built-in default no longer applies for that field, even across upgrades. Keep values.yaml minimal and only set what you intend to override long-term.

Using a values file

For complex configurations, create a values.yaml file for the kubemq-cluster chart:

values.yaml
key: "YOUR_LICENSE_KEY"
replicas: 3
standalone: false

volume:
  size: 20Gi
  storageClass: fast-ssd

grpc:
  expose: LoadBalancer
  port: 50000

api:
  expose: LoadBalancer
  port: 8080

resources:
  requestsCpu: "2"
  requestsMemory: 4Gi
  limitsCpu: "4"
  limitsMemory: 8Gi

Then install with:

Terminal
helm install --wait -n kubemq kubemq-cluster kubemq-charts/kubemq-cluster -f values.yaml --devel

Declarative install (KubemqCluster CR)

The kubemq-controller you installed above is the KubeMQ operator: it watches for KubemqCluster custom resources and reconciles the actual cluster state to match. Instead of passing cluster settings as Helm flags, you can describe the desired cluster declaratively in a KubemqCluster manifest and let the controller create and manage it.

This reuses the controller already running from the steps above — there is nothing extra to install. Apply a KubemqCluster resource and the operator does the rest.

Create a KubeMQ cluster

Define the desired cluster state in a KubemqCluster custom resource, then apply it with kubectl.

Basic cluster

kubemq-cluster.yaml
apiVersion: core.k8s.kubemq.io/v1alpha1
kind: KubemqCluster
metadata:
  name: kubemq-cluster
  namespace: kubemq
spec:
  replicas: 3
  key: "YOUR_LICENSE_KEY"

Apply the manifest:

Terminal
kubectl apply -f kubemq-cluster.yaml

Standalone node (development)

For local development or testing, deploy a single standalone node:

kubemq-standalone.yaml
apiVersion: core.k8s.kubemq.io/v1alpha1
kind: KubemqCluster
metadata:
  name: kubemq-dev
  namespace: kubemq
spec:
  replicas: 1
  standalone: true
  key: "YOUR_LICENSE_KEY"
  grpc:
    expose: NodePort
    nodePort: 32000
  api:
    expose: NodePort
    nodePort: 32080

Production cluster

A production-ready configuration with resource limits, persistent storage, and LoadBalancer services:

kubemq-production.yaml
apiVersion: core.k8s.kubemq.io/v1alpha1
kind: KubemqCluster
metadata:
  name: kubemq-production
  namespace: kubemq
spec:
  replicas: 3
  key: "YOUR_LICENSE_KEY"
  volume:
    size: 50Gi
    storageClass: fast-ssd
  grpc:
    expose: LoadBalancer
    port: 50000
    bodyLimit: 100000000
  rest:
    disabled: false
    expose: ClusterIP
    port: 9090
  api:
    expose: LoadBalancer
    port: 8080
  resources:
    requestsCpu: "2"
    requestsMemory: 4Gi
    limitsCpu: "4"
    limitsMemory: 8Gi
  health:
    initialDelaySeconds: 5
    periodSeconds: 10
    timeoutSeconds: 5

A next-engine cluster requires spec.volume.size. A volumeless next-engine cluster raises the EphemeralNextStore warning — its durable data would otherwise live on ephemeral container storage. The storage engine itself (legacy vs next) is established once, at cluster creation, and is immutable thereafter — there is no in-place migration between engines. See Storage Engines for the full engine-selection model.

To enable Kafka on Kubernetes, see the zero-config recipe in Configure → Zero-config Kafka.

Check the status of your cluster after applying a manifest:

Terminal
kubectl get kubemqclusters -n kubemq

Manage the cluster

Scale

Update the replicas field in your manifest and re-apply, or patch the resource directly:

Terminal
kubectl patch kubemqcluster kubemq-cluster -n kubemq \
  --type merge -p '{"spec":{"replicas":5}}'

For clustered mode (non-standalone), use an odd number of replicas (3, 5, 7) to maintain consensus quorum. With even numbers, the cluster cannot tolerate as many failures.

Update configuration

Edit the KubemqCluster resource to change configuration. The operator reconciles changes automatically.

Terminal
kubectl edit kubemqcluster kubemq-cluster -n kubemq

Or apply an updated manifest:

Terminal
kubectl apply -f kubemq-cluster-updated.yaml

Delete

Remove a KubeMQ cluster while keeping the controller running (so it can still manage other clusters):

Terminal
kubectl delete kubemqcluster kubemq-cluster -n kubemq

This removes all pods and services for that cluster. Persistent volume claims are retained by default.

Field reference

Field-by-field settings for the KubemqCluster spec — types, defaults, and valid values — live in the Configuration Reference, not here: Deployment & High Availability, Storage Engines, and Connectors.

Upgrade

Upgrade an existing KubeMQ installation to a new version or change configuration:

Terminal
helm upgrade --wait -n kubemq kubemq-cluster kubemq-charts/kubemq-cluster \
  --set key=YOUR_LICENSE_KEY \
  --reuse-values \
  --devel

The --reuse-values flag preserves your existing configuration and only applies the changes you specify.

Helm does not upgrade CRDs

Helm never upgrades CRDs shipped in a chart's crds/ directory — running helm upgrade against kubemq-crds will not update an already-installed KubemqCluster CRD. The primary CRD-upgrade path is applying the canonical CRD manifest directly with kubectl apply -f <path to the current KubemqCluster CRD manifest>, not helm upgrade.

Upgrade order

Upgrade in this order:

  1. CRDs and the operator, together, in one step. The window where CRDs are upgraded but the operator is still old is transient — it is not a resting state you should pause in.
  2. Server images. Because the server rides the mutable :next tag rather than a pinned semantic version, "upgrading" the server means rolling the pods so they re-pull the current :next image — there's no version number to bump to.
  3. Charts — the Helm release metadata itself (--reuse-values/--set as needed).

An old operator strips fields it doesn't know about. Don't add spec.env, spec.envFromSecrets, expose, or nodePort — or rely on the engine writing itself back onto the CR — until the operator itself has been upgraded. An old operator permanently strips unknown fields the first time it reconciles a resource, it doesn't just ignore them once.

Operator rollback is not engine-safe. If you roll the operator back, pin spec.store.engine: next explicitly first — a clustered next CR left to auto-detect will crash-loop under an old operator. The engine-establishment annotation on the CR survives rollback (it's untyped metadata an old operator doesn't touch), so re-upgrading the operator later re-derives the engine correctly.

An explicit legacy CR gets one checksum-triggered rolling restart on upgrade. On any CR where the engine was previously unset, engine write-back also arms the replicas-freeze: once the operator establishes the engine as next, spec.replicas becomes immutable on that CR.

v2.8.x → v2.9.0 (breaking)

The six wire-protocol connectors — MQTT, AMQP 0.9.1, AMQP 1.0, STOMP, AWS, and GCP — changed their CRD field from disabled: bool to enabled: *bool. This requires all three components upgraded in lockstep: kubemq-crds ≥ 2.13.0, kubemq-operator ≥ 1.19.0, and the server ≥ v3.0.0-b7. Kafka's enabled: *bool opt-in field is unaffected — it already used this shape, consistent with the post-v2.9 pattern.

Uninstall

Remove KubeMQ from your cluster. Uninstall in reverse order:

Terminal
helm uninstall -n kubemq kubemq-cluster
helm uninstall -n kubemq kubemq-controller
helm uninstall -n kubemq kubemq-crds

Uninstalling deletes all KubeMQ pods and services. Persistent volume claims (PVCs) are retained by default. Delete them manually if you want to remove all data: kubectl delete pvc -n kubemq -l app=kubemq-cluster.

To also remove the namespace:

Terminal
kubectl delete namespace kubemq

Production checklist

Before you point real traffic at a cluster, run down this list.

CheckWhat to do
Odd replica countUse 3, 5, or 7 replicas for clustered mode — an odd number keeps consensus quorum well-defined. Even counts don't buy you extra fault tolerance and can complicate quorum math.
volume.size setSet spec.volume.size (or the volume.size Helm value) explicitly. It's required for the next storage engine — a volumeless next cluster raises the EphemeralNextStore warning because its durable data would otherwise live on ephemeral container storage. See Storage Engines.
Resource requests/limitsSet resources.requestsCpu / requestsMemory / limitsCpu / limitsMemory (or the matching spec.resources.* fields). There are no built-in defaults — an unset field is simply omitted from the pod spec. See the sizing table below.
Service exposureDecide LoadBalancer vs ClusterIP (vs NodePort) per interface (grpc.expose, rest.expose, api.expose) based on whether clients connect from outside the cluster.
Health probesSet spec.health.enabled: true so the operator wires a liveness probe (/health on the API port) and API_BIND_ADDRESS=0.0.0.0 so the kubelet can reach it. Off by default.
Secure itTurn on authentication (JWT or OIDC), authorization (policy-based roles), and TLS/mTLS before exposing the cluster beyond a trusted network. All off by default. Full field-by-field reference: Security.
Image-tag policyThe server rides the mutable :next tag — that's the mandatory release channel, not a placeholder. Own the rolling model: "upgrading" means re-pulling :next and rolling the pods, there's no version number to bump to. For change control, mirror :next to your own registry and promote on your own schedule. Do not pin the image by digest or semver — that channel doesn't exist today and breaks the upgrade path.
PVC retentionDeleting a KubemqCluster (or uninstalling the chart) retains PVCs by default — data survives. Delete them explicitly (kubectl delete pvc -n kubemq -l app=kubemq-cluster) if you actually want to wipe storage.

Sizing: eval vs. production

Illustrative starting points, not hard requirements — tune to your message volume, payload size, and retention needs.

Eval / devProduction
Replicas1 (standalone: true)3, 5, or 7
CPU request / limit250m / 500m2 / 4
Memory request / limit512Mi / 1Gi4Gi / 8Gi
volume.size5Gi (or unset for legacy)50Gi+, fast-ssd storage class
Service exposureClusterIP / port-forwardLoadBalancer

Was this page helpful?

On this page