On-Prem Solutions — load balancing with HAProxy
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.
log /dev/log local0
log /dev/log local1 notice
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
daemon# Default SSL material locations
crt-base /etc/ssl/private# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
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.
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.
server webserver1 Your-Webserver1-IP:80 check
server webserver2 Your-Webserver2-IP:80 check
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.
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.