Skip to content

Instantly share code, notes, and snippets.

@davideicardi
Last active January 21, 2019 12:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davideicardi/bcb92259842e951572b195dd906018db to your computer and use it in GitHub Desktop.
Save davideicardi/bcb92259842e951572b195dd906018db to your computer and use it in GitHub Desktop.
VerneMq Kubernetes StatefulSet + LoadBalancer

Deploy VerneMq inside Kubernetes

Allow the default service account to read pods data, by adding a role binding:

TODO: Now the yaml works only for the dev1 namespace, how can I make it more generic?

kubectl apply -f ./add-read-pods-binding.yaml

Deploy the VerneMQ StatefulSet:

kubectl apply -f ./vernemq.yaml

TODO: Mount volumes...

Check cluster running this command inside one of the pod:

vmq-admin cluster show

More info: https://hub.docker.com/r/erlio/docker-vernemq/

Testing

Sample node.js testing app:

npm install mqtt

import * as mqtt from "mqtt"
const client = mqtt.connect('mqtt://YOUR-LOADBALANCER-IP')

client.on('connect', function () {
  console.log("Connected...")
  client.subscribe('presence', (err) => {
    if (err) {
      console.error("Failed to subscribe");
      return;
    }

    client.publish('presence', 'Hello mqtt');
  });

});

client.on("error", function(err) {
  console.error(err);
});

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(topic, message.toString())
  client.end()
});
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# ClusterRoles not bound to namespace?
# namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
...
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: pod-reader-pod
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-reader
subjects:
- kind: ServiceAccount
name: default
namespace: dev1 # TODO: Here I should use the current namespace or all namespace, change this if your namespace is different
kind: Service
apiVersion: v1
metadata:
name: vernemq-public
spec:
selector:
app: vernemq
ports:
- name: mqtt
protocol: TCP
port: 1883
targetPort: 1883
- name: websocket
protocol: TCP
port: 8080
targetPort: 8080
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: vernemq
spec:
ports:
- port: 1883
name: mqtt
- port: 8883
name: mqttssl
clusterIP: None
selector:
app: vernemq
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vernemq-set
labels:
app: vernemq
spec:
serviceName: vernemq
replicas: 2
selector:
matchLabels:
app: vernemq
template:
metadata:
labels:
app: vernemq
spec:
containers:
- name: docker-vernemq
image: erlio/docker-vernemq:1.4.1
ports:
- containerPort: 1883
name: mqtt
- containerPort: 8080
name: websocket
env:
- name: DOCKER_VERNEMQ_ALLOW_ANONYMOUS
value: "on"
- name: DOCKER_VERNEMQ_DISCOVERY_KUBERNETES
value: "1"
- name: DOCKER_VERNEMQ_KUBERNETES_APP_LABEL
value: "vernemq"
- name: DOCKER_VERNEMQ_KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment