Score:0

Accessing Mosquitto MQTT from outside my kubernetes cluster

us flag

I have the following Mosquitto setup on my minikube:

Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mosquitto
  namespace: mosquitto
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mosquitto
  template:
    metadata:
      labels:
        name: mosquitto
    spec:
      containers:
        - name: mosquitto
          image: eclipse-mosquitto:2.0.12
          ports:
          - containerPort: 1883
          volumeMounts:
          - name: mosquitto-config
            mountPath: /mosquitto/config/mosquitto.conf
            subPath: mosquitto.conf
      volumes:
      - name: mosquitto-config
        configMap:
          name: mosquitto-configmap  

ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mosquitto-configmap
  namespace: mosquitto
data:
  mosquitto.conf: |-
    listener 1883
    allow_anonymous true  

Service:

apiVersion: v1
kind: Service
metadata:
  name: mosquitto-service
spec:
  type: NodePort
  selector:
    name: mosquitto
  ports:
    - protocol: TCP
      port: 1883
      targetPort: 1883
      nodePort: 30007  

Now I'd like to access my deployment from my LAN. Testing with MQTT-Explorer from my host Windows machine. Using mqtt://localhost:30007 doesn't work. The setup is known to be working with port-forwarding, tho.

$ k port-forward mosquitto-66d69df7c9-zrvgt 1111:1883
Forwarding from 127.0.0.1:1111 -> 1883
Forwarding from [::1]:1111 -> 1883
Handling connection for 1111

I think I'm misunderstanding the service part. In the end the service should be reachable from within my LAN either with :

Bonus question: How can I route the service to something like mqtt.local? Kubernetes Ingress doesn't work for me either, guessing because it's used for HTTP only

Score:0
pl flag

A NodePort allocates an IP that is internal to the cluster, hence the need to port forward.

To pass that internal port to an external port you need to change the spec.type to LoadBalancer.

I found the term "LoadBalancer" to be confusing as it conflicts with the term used by services such as AWS for their own load balancers (eg ELB in Amazon). In Kubernetes a LoadBalancer service will load balance between any pods that match the criteria you specify, or in this case just the one.

The trick is, if you're in an environment with actual load balancers then the service will automatically map to an external load balancer so you can access the service with a real IP.

This can also be done with an Ingress but that can only be used for http and https services with an ingress controller eg NGINX. Because MQTT is a different protocol the service is used to pass the connection through.

In my case I'm not on a cloud service so there is no load balancer like ELB provided by default - you have to add your own (see what I mean about confusing). I installed a local MetalLB load balancer in the cluster and the port magically appeared in one of the pools of local IPs I allocated.

From there you just need to set up DNS (in your router perhaps) so that the name you want corresponds with the allocated IP. My broker now appears on mqtt.local on port 1883

Here's the yaml that worked for me:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mosquitto
  namespace: mosquitto
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mosquitto
  template:
    metadata:
      labels:
        name: mosquitto
    spec:
      containers:
        - name: mosquitto
          image: eclipse-mosquitto:2.0.12
          ports:
          - containerPort: 1883
          volumeMounts:
          - name: mosquitto-config
            mountPath: /mosquitto/config/mosquitto.conf
            subPath: mosquitto.conf
      volumes:
      - name: mosquitto-config
        configMap:
          name: mosquitto-configmap  
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mosquitto-configmap
  namespace: mosquitto
data:
  mosquitto.conf: |-
    listener 1883
    allow_anonymous true 
---
apiVersion: v1
kind: Service
metadata:
  name: mosquitto-service
  namespace: mosquitto
  annotations:           # <-- Which IP pool to use
    metallb.universe.tf/address-pool: lb-static-ips
spec:
  type: LoadBalancer # <-- Changed
  selector:
    name: mosquitto
  ports:
    - name: mosquitto
      protocol: TCP
      port: 1883
      targetPort: 1883
      # nodePort: 30007  <--- LoadBalancer will figure this out

... and this is the YAML for metalLB:

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: http # one IP address for virtual http hosts
      protocol: layer2
      addresses:
      - 10.3.3.152/32

    - name: lb-static-ips #  IP addresses for services
      protocol: layer2
      addresses:
      - 10.3.3.153-10.3.3.160
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.