Traefik load balancer on two servers

Hello folks,
we are having a hard time getting the load balancer feature to work with two servers. We kind of want to use a traefik instance on a server as a load balancer / failover and as a service reverse proxy using docker.

We have a service that listens to a specific route on the server: http://--server--/service.

http:
  routers:
    serviceA:
      rule: Path(`/service`)
      service: serviceA

  services:
    serviceA:
      loadBalancer:
        port: 8000

This setup is setup on two independent machines. If the service is unavailable on the first server, we want traefik to load balance on the second server.

http:
  routers:
    serviceA:
      rule: Path(`/service`)
      service: serviceA

  services:
    serviceA:
      loadBalancer:
        servers:
            - url: http://srv-01/
            - url: http://srv-02/

So at same time we need to define the port for the service to be reversed to, because we do not want to expose the ports since we are using docker service discovery but also we want to have a failover to another server. Is it possible to have both with the same traefik instance or do we need to run traefik once as reverse-proxy and once as load balancer on another machine?

By default Traefik works as a reverse proxy. When it finds multiple target services via Configuration Discovery, it will automatically do round-robin load-balancing between the targets.

Even if Traefik runs on multiple servers, you need to make sure that accessing those instances (usually by domain, which is resolved by DNS to an IP) has some kind of failover, too.

You can set a port when using .loadbalancer.servers.url=http://srv-01:8080/

Can you re-phrase what you are trying to achieve?

Hello @bluepuma77 thanks for your answer.

When we are using docker with the service discovery for a specific service (Service A), we do not expose the port on the host with docker (8080 in your example). If we would do that, the port is opened to the outer world and can be used with the machine IP. So targeting the server with the port does not seem like a valid solution.

We want the following:

http://srv-01/service
http://srv-02/service

We have the exact same setup with traefik and Service A on two machines. If Service A is broken or not responding on srv-01, we want the load balancer of traefik to route to srv-02 if the service is healthy.

The service is reachable on both hosts via the path /service after the domain name. Traefik then uses the PathPrefix to reverse proxy Service A from the docker container listening on port 8080.

If you don't want to expose the port to the outside world, you can

  1. Expose the port and set a firewall rule to only allow known IPs
  2. Expose the port on an internal IP, that is only reachable by the other server, not externally
  3. Use a Docker network. With multiple servers you need Docker Swarm

Hey @bluepuma77 thanks for the reply.

I think I am getting the idea. So if we have a DNS record for http://srv/service that points to the machines srv-01 and srv-02. The reverse proxy no longer works with a docker network for each machine but either only via ports or via docker swarm to have a single docker network managed for two machines. Do I get the idea right?

So the easiest solution would be exposing the ports inside our cluster and to not make it accessible by the outside world. In comes user traffic for http://srv/service and hits traefik on port 80 or 443. Additionally
we have a router for Service A that uses the AddPrefix middleware to listen for the /service route. The service for the router would use the load balancer servers that point to http://srv-01:8080 and http://srv-02:8080/. Does that also mean that I have to define Port 8080 as a new entry point for traefik so that in the end we would have :80, :443 and :8080?

How can we handle the path prefix for the services? As I have read, it is not possible to target loadbalancer servers with a route (E.g. /service). Normally we use a StripPrefix middleware to not let the container receive this path, since the application thinks it runs at "/". Is there a combination of AddPrefix and StripPrefix possible? So that traefik listens to /service but the container receives "/"?

Thanks in advance

How does your DNS record point to two machines?

Is your service a plain API or a web-app? Web-apps are usually not path-aware and they don’t work with additional paths, as redirects and links are usually not adapted and lead to not working paths. Use sub-domain instead.