Here, we will learn about HAProxy Layer 7 load balancing with Docker containers in action. What we're going to do here is to spin up a HAProxy container with some custom configuration, which listens to the request at port 80 and forwards the traffic to a set of back-end servers containing Kestrel, Apache, and Node Docker containers, each running on a different port and which will look something like what is shown in the below image. We will use Docker-Compose to make things a bit quicker.
I have 3 super simple Docker images i.e. Node, ASP.NET Core and PHP with Apache images and an official HAProxy Docker image on my machine. We will mount a custom HAProxy configuration file `haproxy.cfg` as the volume for HAProxy container which listens for the traffic at port 80 and load-balance them among 3 containers. The HAProxy configuration file looks something like this,
- global
- debug
-
- defaults
- log global
- mode http
- timeout connect 5000
- timeout client 5000
- timeout server 5000
-
- frontend main
- bind *:80
- default_backend app
-
- backend app
- balance roundrobin
- mode http
- server srv1 app1
- server srv2 app2
- server srv3 app3
There are 2 important sections here, frontend and backend, the first of which listens for the incoming HTTP requests and the second if which processes those request. The front-end and back-end can be named anything (here I named main for front-end, and app for back-end). The front-end rule will listen at port 80 and forward the request to the app's back end to process those requests. The back-end specifies the Round-Robin load-balancing algorithm, a mode and three servers to process requests. Here we specified the name of the container, not an actual URI of the server because we want to use embedded Docker Engine DNS to resolve services against all the containers as the containers will be running in the same user-defined network.
Next, we need to specify the Docker Compose file which we will use which is,
- version: '2'
-
- services:
- app1: # Service 1
- image: haproxy/app1 # ASP.NET Core
- ports:
- - 81:80
- container_name: 'app1' # Name of the container
-
- app2: # Service 2
- image: haproxy/app2 # PHP and Apache
- ports:
- - 82:80
- container_name: 'app2' # Name of the container
-
- app3: # Service 3
- image: haproxy/app3 # Node and Express
- ports:
- - 83:80
- container_name: 'app3' # Name of the container
-
- haproxy: # Haproxy service
- image: haproxy # Official HAProxy image
- ports:
- - 80:80
- container_name: 'haproxy' # Name of the container
- volumes: # HAProxy configuration volume mount
- - '~/Documents/practice/haproxy:/usr/local/etc/haproxy/haproxy.cfg:ro'
Next, go to the Docker Compose directory, open up a terminal and type,
This will spin up 4 containers with HAProxy container and will serve at localhost port 80.
Now, refresh the same webpage a couple of times, you will see that requests are being being forwarded to different containers defined in the back-end section of HAProxy.
Conclusion
Containers like HAProxy and Nginx can be used to load-balance HTTP and TCP (L7 and L4) traffic. In Swarm, it can also use load-balance TCP traffic among containers that do not work with HTTP such as database containers etc.