On-Prem Solutions — load balancing with HAProxy

Nilesh Jayanandana
4 min readFeb 27, 2019

Recently, in a project that I’m involved in, there was a requirement to load balance their workloads. Take public cloud, Google, AWS, Azure etc, setting up a load balancer is fairly easy. It’s just a matter of couple of clicks in the console. This is not the case when you are going on-prem. You should be able to configure a load balancer on your own. In this tutorial, I’m going to guide you through on configuring HAProxy to get you going with load balancing.

Setting up web servers

First, let’s set up a couple of Virtual Machines with Apache web servers. I’m going to assume the base image would be Ubuntu 18.04 LTS for the rest of this guide.

In both VMs let’s quickly set up Apache by running the following commands.

$ sudo apt-get update
$ sudo apt-get install apache2 -y

Now let us change the default Apache welcome page to reflect the name of the server.
In VM 1

$ echo '<!doctype html><html><body><h1>Hello World from Machine 1!</h1></body></html>' | sudo tee /var/www/html/index.html

In VM 2

$ echo '<!doctype html><html><body><h1>Hello World from Machine 2!</h1></body></html>' | sudo tee /var/www/html/index.html

Setting up a Bastion Host

Okay. Now we set up another VM with Ubuntu being the base image. Do a curl on the internal IP addresses of VM1 and VM2 and check whether you get the hello world response we set up on the previous step.

Set up and configure HAProxy

Now we install HAProxy in our bastion host. To do that, enter the following in command line.

$ sudo apt-get -y install haproxy

This should get installed in a couple of minutes.

Now, you have to edit the haproxy config which is situated in /etc/haproxy/haproxy.cfg

$ sudo vi /etc/haproxy/haproxy.cfg

This will display a config file as following.

global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

At the bottom of the file, let’s insert our load balancing configurations.

frontend incoming_requsts
bind *:80
option forwardfor
default_backend webservers

The above snippet tells the haproxy to bind all the incoming requests attached to port 80 on any ip range and forward them to a backend service called web servers, which we will be defining below.

backend webservers
balance roundrobin
server webserver1 Your-Webserver1-IP:80 check
server webserver2 Your-Webserver2-IP:80 check
option httpchk

Here you should replace the text in bold with the relevant ip addresses of your web servers. Note here that the load balancing option we have given is round robin. Round robin selects servers in turns. This is the default algorithm. You can learn more about other options from here.

Now let’s save the config file and verify whether configs are correct by running the following command.

$ haproxy -f /etc/haproxy/haproxy.cfg -c

Alright! If it passes the verification, You can go ahead and apply the configuration by restarting the haproxy service.

$ sudo service haproxy restart

Now if you curl the ip address of your bastion host from your local machine, you should be able to see the response alternating from VM 1 and VM 2.

There you have it! This was a pretty basic tutorial and let me know if you have any queries on this.

Other Solutions

HAProxy isn’t the only kid in town. If you feel like HAProxy might be too complex for your needs, the following solutions may be a better fit:

  • Linux Virtual Servers (LVS) — A simple, fast layer 4 load balancer included in many Linux distributions
  • Nginx — A fast and reliable web server that can also be used for proxy and load-balancing purposes. Nginx is often used in conjunction with HAProxy for its caching and compression capabilities

UPDATE on CentOS

There is a weird issue with centOS SELinux where haproxy has an issue with the forwarding port. To fix this run the following commands.

yum install policycoreutils-pythonsudo semanage port --add --type http_port_t --proto tcp <forward-port>setsebool -P haproxy_connect_any=1

Clap for support.
Cheers!

--

--