HAProxy load balancer outside the swarm, how?


I have been asked to look into using Docker Swarm at our work.

We currently have a HAProxy load balancer and 8 IIS webservers.

Is it possible to keep using our HAProxy as a load balancer if we make a Docker Swarm?
But without making our HAProxy run in a container.

I have been googling like crazy, and everywhere I look, all the examples I find have HAProxy running in a container, which is not what we want.

Our goal is to have HAProxy directly connect to service in the container, without using the Docker routing mesh.

From what I can tell from my googling, it could be done by using the Docker DNS as a resolver in HAProxy.
Basically like described in this article, but with HAProxy outside the Docker Swarm:

But how do I access the Docker DNS outside the swarm?

You could use deployment contraints to restrict deployment to specific nodes and publish ports in host mode on those, Then setup your external HAProxy to forward traffic to the published host ports on those nodes, though make sure HAProxy does a healthcheck to send traffic to nodes with active instances of your containers.

You either publish ports to a host ports or use the ingress routing mesh - you have to live with either one of the solutions! There is no “but, i want to still access the container from every node without using ingress”. There is no way to access the DNS as well.

On the other side, what is wrong with putting HAProxy into a container? I would always prefer to put the Reverseproxy on dedicated nodes using global deployments and deployment constraint with host ports, then leverage the container network to forward traffic to the target service. This is especialy usefull if your target service is not suited for replication.

One downside with having HAProxy inside the swarm with the exposed ports via mode=ingress is that HAProxy does not see the IP address of the incoming traffic. This is a major issue since it’s impossible to block malicious IP addresses, every request comes from the same internal IP address.

Please correct me if I am wrong, but I don’t see how ingress-only is able to propagate the IP address to HAProxy.

Security should always be implemented on the outer perimeter. If the docker host happens to be the outer perimeter, because the host has a public ip, then of course it must be implemented on the host.

I suggested mode=host as global deployment for haproxy (=no ingress). This indeed retains the source ip.

mode=ingres uses the Linux IPVS kernel module for the virtual ip of the service, which spreads traffic to the service tasks. In this scenario, the service tasks will of course see the virtual ip of the service.