This How-to article is related to the official HiveMQ Kubernetes Operator documentation, which you can find here: https://www.hivemq.com/docs/operator/4.7/kubernetes-operator/operator-intro.html.
It explains how to expose the HiveMQ Control Center and Rest API using Ingress.
For this you have to have a Kubernetes Ingress Controller of your choice (e.g. NGINX, Traefik, Voyager, …) already setup and running.
Exposing the HiveMQ resources without a proper TLS implementation is not recommended in production so keep in mind to enhance the Ingress configuration with TLS as documented by the Ingress provider.
Architecture Overview
(Source: https://kubernetes.io/docs/concepts/services-networking/ingress/ )
Prepare your HiveMQ Deployment
To deploy HiveMQ in Kubernetes using Helm you have to download the default values.yaml
file from the official GitHub repository (https://github.com/hivemq/helm-charts/blob/master/charts/hivemq-operator/values.yaml) first.
After this you have to edit the file so the HiveMQ Control Center “cc” and the HiveMQ Rest API “api” will not get exposed (expose: false
). You also have to uncomment the "api" section as you can see in the following example. With this configuration, the HiveMQ Kubernetes Operator will not create Kubernetes services for those HiveMQ components:
... # The ports can be edited or expanded upon, but the MQTT port must be the first one. ports: - name: "mqtt" port: 1883 expose: true patch: - '[{"op":"add","path":"/spec/selector/hivemq.com~1node-offline","value":"false"},{"op":"add","path":"/metadata/annotations","value":{"service.spec.externalTrafficPolicy":"Local"}}]' # If you want Kubernetes to expose the MQTT port to external traffic # - '[{"op":"add","path":"/spec/type","value":"LoadBalancer"}]' - name: "cc" port: 8080 expose: false patch: - '[{"op":"add","path":"/spec/sessionAffinity","value":"ClientIP"}]' # If you want Kubernetes to expose the HiveMQ control center via load balancer. # Warning: You should consider configuring proper security and TLS beforehand. Ingress may be a better option here. # - '[{"op":"add","path":"/spec/type","value":"LoadBalancer"}]' # To enable the HiveMQ REST API and expose it as a service. Be aware of the security risks of exposing the REST API - name: "api" port: 8888 expose: false patch: - '[{"op":"add","path":"/spec/sessionAffinity","value":"ClientIP"}]' ...
Helm installation using custom values
For the installation using Helm you have to add the official HiveMQ Helm repository and install the Helm chart using the modified values.yaml
file.
helm repo add hivemq https://hivemq.github.io/helm-charts helm repo update helm upgrade --install -f values.yaml hivemq-prod hivemq/hivemq-operator # you can change "hivemq-prod" to fit your needs
The HiveMQ Kubernetes Operator will automatically create all the necessary Kubernetes resources for you.
Expose the HiveMQ Control Center and REST API inside the Kubernetes Cluster
The following file hivemq-service.yaml
will create a Service called "hivemq-cc-service" with type ClusterIP to expose the HiveMQ Control Center and REST API inside your Kubernetes cluster.
apiVersion: v1 kind: Service metadata: name: hivemq-cc-service # The service name spec: ports: - name: "cc" port: 8080 protocol: TCP - name: "api" port: 8888 protocol: TCP selector: hivemq-cluster: hivemq-prod # from the helm upgrade command above
kubectl apply -f hivemq-service.yaml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hivemq-cc-service ClusterIP <Cluster-IP> <none> 8080/TCP,8888/TCP <Age>
Deploy Ingress
At this point we already have deployed HiveMQ with the desired components, but for now it’s only available from within the Kubernetes cluster.
To expose it outside the Kubernetes cluster, you have to set up an Kubernetes Ingress Controller as Proxy with a corresponding Ingress Resource, which will configure the Ingress Controller properly.
Keep in mind that the syntax of the following Ingress definition in ingress.yaml
depends on your Kubernetes version and Ingress Controller. You can find the required informations at the documentation of your Ingress Provider.
It’s important that you configure the cookie annotation based on your Ingress provider.
Otherwise you will not be able to use the HiveMQ Control Center properly.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hivemq-ingress annotations: nginx.ingress.kubernetes.io/affinity: cookie spec: rules: - host: <hostname> # match with your DNS hostname, e.g. cc.hivemq.com for http(s)://cc.hivemq.com http: paths: - path: / # this will match http(s)://cc.hivemq.com/ pathType: Exact backend: service: name: hivemq-cc-service # Value from hivemq-service.yaml port: number: 8080 # Value from hivemq-service.yaml - path: /api # this will match http(s)://cc.hivemq.com/api (recursive) pathType: Prefix backend: service: name: hivemq-cc-service # Value from hivemq-service.yaml port: number: 8080 # Value from hivemq-service.yaml
kubectl apply -f ingress.yaml
This will — based on your Ingress Controller — create some resources and a Service from type LoadBalancer which will get an external IP assigned automatically from the On-Premise or Cloud LoadBalancer, which is accessible from outside your Kubernetes Cluster.
If you have configured DNS properly, you should now be able to access your resources e.g. using http://cc.hivemq.com.
Resources
Ingress: https://kubernetes.io/docs/concepts/services-networking/ingress/
NGINX Ingress: https://docs.nginx.com/nginx-ingress-controller/
Path types: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types
Traefik Ingress: https://doc.traefik.io/traefik/providers/kubernetes-ingress/