0

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

1 Answer 1

0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .