Search code examples
tcpload-balancingmqtttraefik

Is it possible to load balance MQTT traffic with Traefik 2.0 TCP feature?


I am currently using Haproxy to load balance MQTT traffic to N dockerized mqtt brokers

Traefik 2.0 is out and can proxy TCP traffic, I am wondering if it is possible to load balance MQTT traffic to N dockerized mqtt brokers using Traefik as load balancer like you would do with Haproxy.

I tried some basic configuration using the official traefik doc, but i can't get the traffic upstream.

Has anyone tried this already?


Solution

  • Yes I did it yesterday. I used the VerneMQ for MQTT broker and Traefik as a load balancer. The following configurations file are for Docker Swarm.

    Here is the docker-compose configuration I use:

    version: "3"
    
    services:
        traefik:
            image: traefik:v2.1
            ports:
                - "80:80"
                - "1883:1883"
            volumes:
                - /var/run/docker.sock:/var/run/docker.sock
                - /dev/random:/dev/random
                - ./traefik.toml:/traefik.toml
            deploy:
                placement:
                    constraints: [node.role == manager]
                labels:
                    - traefik.enable=true
                    - traefik.docker.network=net
    
                    - traefik.http.routers.dashboard.rule=Host(`traefik.home.gtheofilis.com`)
                    - traefik.http.routers.dashboard.entrypoints=http
                    - traefik.http.routers.dashboard.service=api@internal
                    - traefik.http.services.dashboard.loadbalancer.server.port=9999
    
        vmq0:
            image: vernemq/vernemq
            environment:
                DOCKER_VERNEMQ_SWARM: 1
                DOCKER_VERNEMQ_ACCEPT_EULA: "yes"
                DOCKER_VERNEMQ_ALLOW_ANONYMOUS: "on"
            deploy:
                placement:
                    constraints: [node.role == manager]
                labels:
                    - traefik.enable=false
    
        vmq:
            image: vernemq/vernemq
            depends_on:
                - vmq0
            environment:
                DOCKER_VERNEMQ_SWARM: 1
                DOCKER_VERNEMQ_DISCOVERY_NODE: vmq0
                DOCKER_VERNEMQ_ACCEPT_EULA: "yes"
                DOCKER_VERNEMQ_ALLOW_ANONYMOUS: "on"
            deploy:
                replicas: 3
                labels:
                    - traefik.enable=true
                    - traefik.docker.network=net
                    - traefik.tcp.routers.mqtt.rule=HostSNI(`*`)
                    - traefik.tcp.routers.mqtt.entrypoints=mqtt
                    - traefik.tcp.services.mqtt.loadbalancer.server.port=1883
    
                    - traefik.http.routers.mqtt_dashboard.rule=Host(`vernemq.home.gtheofilis.com`)
                    - traefik.http.routers.mqtt_dashboard.service=mqtt_dashboard
                    - traefik.http.routers.mqtt_dashboard.middlewares=auth
                    - traefik.http.routers.mqtt_dashboard.entrypoints=http
                    - traefik.http.services.mqtt_dashboard.loadbalancer.server.port=8888
    
    networks:
        default:
            external:
                name: net
    

    And this is my traefik.toml configuration file:

    [api]
        dashboard = true
    
    [entryPoints]
      [entryPoints.http]
        address = ":80"
      [entryPoints.mqtt]
        address = ":1883"
    
    [providers]
        [providers.docker]
            endpoint = "unix:///var/run/docker.sock"
            swarmMode = true