Howto loadbalance two tcp services

Hello,

For RabbitMQ i have a Docker Stack with two services: rabbitmq-01 and rabbitmq-02, they are clustered.

For service rabbitmq-01 i've added traefik labels for the management web gui (port 15672). And for both services I've added the labels for tcp routers & services. However now each service has its own router, is there a way that there is only one router linked to both services and loadbalance between them?

Any advice/improvements are very much appreciated!

Greets,
Ray

################################################################################
# Rabbit MQ Stack
################################################################################
#$ docker stack deploy rabbitmq --compose-file docker-compose-rabbitmq_v2.yml
################################################################################
version: "3.7"

services:
  rabbitmq-01:
    image: rabbitmq:management-alpine
    user: "1024:100"
    hostname: rabbitmq-01
    environment:
      - RABBITMQ_ERLANG_COOKIE=IYCmrT+iyYdLeNSEO/H14A==
      - RABBITMQ_CONFIG_FILE=/etc/rabbitmq/rabbitmq.conf
    networks:
      proxy_traefik-net:
    volumes:
      - /etc/passwd:/etc/passwd:ro
      - /mnt/docker-cluster/rabbitmq/rabbit-01/enabled_plugins:/etc/rabbitmq/enabled_plugins
      - /mnt/docker-cluster/rabbitmq/rabbit-01/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
      - /mnt/docker-cluster/rabbitmq/rabbit-01/data:/var/lib/rabbitmq
      - /mnt/docker-cluster/rabbitmq/rabbit-01/logs:/var/log/rabbitmq

    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        - traefik.enable=true
        - traefik.docker.network=proxy_traefik-net
        - traefik.http.routers.rabbitmq-01.rule=Host(`rabbitmq.indonesia`)
        - traefik.http.services.rabbitmq-01.loadbalancer.server.port=15672
        
        - traefik.tcp.routers.rabbitmq-01.rule=HostSNI(`*`)
        - traefik.tcp.routers.rabbitmq-01.entrypoints=rabbit-mq
        - traefik.tcp.services.rabbitmq-01.loadbalancer.server.port=1883

  rabbitmq-02:
    image: rabbitmq:alpine
    user: "1024:100"
    hostname: rabbitmq-02
    environment:
      - RABBITMQ_ERLANG_COOKIE=IYCmrT+iyYdLeNSEO/H14A==
      - RABBITMQ_CONFIG_FILE=/etc/rabbitmq/rabbitmq.conf
    networks:
      proxy_traefik-net:
    volumes:
      - /etc/passwd:/etc/passwd:ro
      - /mnt/docker-cluster/rabbitmq/rabbit-02/enabled_plugins:/etc/rabbitmq/enabled_plugins
      - /mnt/docker-cluster/rabbitmq/rabbit-02/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
      - /mnt/docker-cluster/rabbitmq/rabbit-02/data:/var/lib/rabbitmq
      - /mnt/docker-cluster/rabbitmq/rabbit-02/logs:/var/log/rabbitmq
    deploy:
      placement:
        constraints:
          - node.role == worker

      labels:
        - traefik.enable=true
        - traefik.docker.network=proxy_traefik-net
        - traefik.tcp.routers.rabbitmq-02.rule=HostSNI(`*`)
        - traefik.tcp.routers.rabbitmq-02.entrypoints=rabbit-mq
        - traefik.tcp.services.rabbitmq-02.loadbalancer.server.port=1883

networks:
  proxy_traefik-net:
    external: true

traefik.yml

global:
  sendAnonymousUsage: true
  checknewversion: true

entryPoints:
  web:
    address: ":80"
  web-secure:
    address: ":443"
  rabbit-mq:
    address: ":1883"

api:
  dashboard: true
  debug: true
  #insecure: true

################################################################
# Ping configuration
################################################################

# Enable ping
ping: {}

  # Name of the related entry point
  #
  # Optional
  # Default: "traefik"
  #
  # entryPoint = "traefik"  


################################################################
# Docker configuration backend
################################################################

# Enable Docker configuration backend
providers:
  docker:
    #endpoint: "unix:///var/run/docker.sock"
    endpoint: "tcp://cluster.indonesia:2375"
    watch: true
    exposedByDefault: false
    # useBindPortIP: true
    swarmMode: true

Someone any idea how to accomplish this? :slight_smile:

I believe your second rabbit service needs to use the same service name as the first. ie, the service name should be "rabbitmq" in both instances.

 services:
  rabbitmq-01:
<snip>
      labels:
        - traefik.enable=true
        - traefik.docker.network=proxy_traefik-net
        - traefik.http.routers.rabbitmq-01.rule=Host(`rabbitmq.indonesia`)
        - traefik.http.services.rabbitmq-01.loadbalancer.server.port=15672
        
        - traefik.tcp.routers.rabbitmq.rule=HostSNI(`*`)
        - traefik.tcp.routers.rabbitmq.entrypoints=rabbit-mq
        - traefik.tcp.services.rabbitmq.loadbalancer.server.port=1883

  rabbitmq-02:
<snip>
      labels:
        - traefik.enable=true
        - traefik.docker.network=proxy_traefik-net
        - traefik.tcp.services.rabbitmq.loadbalancer.server.port=1883
1 Like

Thanks for your reply! Your solution helped me pointing to the right direction :+1:

I've added the two router lines also to the second service to make it work. If one of the service / containers are shutdown, clients get connected to the remaining service/container.

Thank you very much!

services:
  rabbitmq-01:
<snip>
      labels:
        - traefik.enable=true
        - traefik.docker.network=proxy_traefik-net
        - traefik.http.routers.rabbitmq-01.rule=Host(`rabbitmq.indonesia`)
        - traefik.http.services.rabbitmq-01.loadbalancer.server.port=15672
        
        - traefik.tcp.routers.rabbitmq.rule=HostSNI(`*`)
        - traefik.tcp.routers.rabbitmq.entrypoints=rabbit-mq
        - traefik.tcp.services.rabbitmq.loadbalancer.server.port=1883

  rabbitmq-02:
<snip>
      labels:
        - traefik.enable=true
        - traefik.docker.network=proxy_traefik-net
        - traefik.tcp.routers.rabbitmq.rule=HostSNI(`*`)
        - traefik.tcp.routers.rabbitmq.entrypoints=rabbit-mq
        - traefik.tcp.services.rabbitmq.loadbalancer.server.port=1883

this is a bad idea, If rabbitmq is two independent services, you need to distinguish access

Both services are clustered so they are not independent .