Loadbalancing With HAProxy

Tunde Alex-Oni
4 min readDec 13, 2016

--

Load balancing is the direction to go if you get a lot of traffic and are looking for high availability.

HAProxy is typically used to implement load balancing. Basically, you could scale out to ’n’ number of resources (such as application instances or database hosts) setup to cater for requests using HAProxy to distribute traffic to said resources, following whichever of the load balancing algorithms you specify.

Let’s paint a picture of traffic flow when using a load balancer for a monolithic eCommerce web application; say you are looking to scale out to 2 application running resources:

- “Resource A” (serving your application) with IP address 192.168.33.2

- “Resource B” (serving same application in Resource A) with IP address 192.168.33.3

You need to distribute the traffic to these 2 instances via a single entry point. At this point we would need to toss a new resource into the mix, let’s call it:

- “Resource C” running HAProxy.

We make “Resource C” the entry point directing traffic to it and HAProxy would distribute incoming traffic to “Resource A” and “Resource B”.

Now let’s demonstrate load-balancing with HAProxy using docker containers as both application resources and HAProxy running resource.

New to docker? Find out more here and you could also play around with a quick setting up of docker containers, following instructions from this blog post.

Application Docker Containers:

For this step you would need docker installed. we would startup 2 docker containers which would play the role of our application resources for our analogy. Run the following commands to start required containers using a custom image from my repository, here is a helpful resource for docker newbees.

docker run — name resource-a -p 4568:4567 -P -d tundeaoni/tiny-app-for-lb-demodocker run — name resource-b -p 4567:4567 -P -d tundeaoni/tiny-app-for-lb-demo

Both running apps are accessible by making a request to the docker host(mine for example is: 192.168.99.100. If using a mac, run echo docker-machine env) at the bound network ports (4567 and 4568 in this case) from your browser or using curl in your *terminal.

HAProxy Running Docker Container:

Start up a docker container running HAProxy as follows:

docker run -d — name haproxy-running-resource \
-v /path-to/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:rw \
-p 5003:80 -P -d tundeaoni/haproxy-demo

The HAProxy container above is accessible from your docker host at the bound port, which in this case is 5003.

HAProxy Configuration:

In order to define the behaviour of HAProxy, the configuration file is volume mounted from your local machine. Below is a sample configuration file. Make sure to replace your-docker-machine-ip in the “backend section” with the exact value of your docker machine’s IP address and save the file as haproxy.cfg

global# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL).
ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /usr/local/etc/haproxy/errors/400.http
errorfile 403 /usr/local/etc/haproxy/errors/403.http
errorfile 500 /usr/local/etc/haproxy/errors/500.http
errorfile 503 /usr/local/etc/haproxy/errors/503.http
errorfile 504 /usr/local/etc/haproxy/errors/503.http
frontend localnodes
bind *:80
mode http
default_backend nodes

capture request header Referrer len 64
capture request header Content-Length len 10
capture request header User-Agent len 64
capture request header X-Forwarded-For len 32
backend nodes
mode http
balance roundrobin
option forwardfor
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server web01 your-docker-hostmachine-ip:4567 check
server web02 your-docker-hostmachine-ip:4568 check

You can read more about HAProxy configurations here.

A little about the configuration above:

  • Frontend section contains specifications about where HAProxy listens to connections and other related settings.
  • Backend section contains where HAProxy sends incoming connections.

Run docker ps you should see 3 containers running , 2 app containers and 1 HAProxy container.

Run curl http://your-docker-hostmachine-ip:<haproxy-port> . On each response you would notice both containers are rotated.

Resources

--

--

Tunde Alex-Oni

Muslim | Software + Devops Engineer | All round Professional | blah , blah , blah