This guide will take you through how to setup HAProxy Load balancer on Fedora 30/Fedora 29. HAProxy provides high availability, load balancing and proxying for TCP and HTTP-based applications. There are different algorithms that HAProxy uses for load balancing. Some of the commonly used ones include;
- Roundrobin – This is the default algorithm and it enables HAProxy to select each server to server requests in turns according to their weights.
- leastconn – The server with the lowest number of connections receives the connections. It is recommended where very long sessions are expected, such as LDAP, SQL.
- source – With this algorithm, the source IP address is hashed and divided by the total weight of the running servers to designate which server will receive the request. This ensures that the same client IP address will always reach the same server as long as no server goes down or up. If the hash result changes due to the number of running servers changing, many clients will be directed to a different server.
There are quite a number of algorithms that HAProxy can use. You can read more about them on the documentation page.
Setup HAProxy Load Balancer on Fedora 30/Fedora 29
To basically demonstrate how HAProxy can run as a load balancer, this guide uses three virtual machines; one running as HAProxy load balancer and two other web servers serving basic html pages;
Install HAProxy on Fedora 30/Fedora 29
To begin with, run system update.
dnf update
dnf upgrade
Once the update is done, execute the command below to install HAProxy on Fedora 30/Fedora 29.
dnf install haproxy
Configure HAProxy on Fedora 30/Fedora 29
The main configuration file for HAProxy is /etc/haproxy/haproxy.cfg.
The default HAProxy configuration file without comments looks like in below;
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend main
bind *:5000
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
backend static
balance roundrobin
server static 127.0.0.1:4331 check
backend app
balance roundrobin
server app1 127.0.0.1:5001 check
server app2 127.0.0.1:5002 check
server app3 127.0.0.1:5003 check
server app4 127.0.0.1:5004 check
Well, in this guide, we are going to comment the frontend and backend sections and define our own configurations.
Below is our frontend configuration.
frontend lb_01
bind 192.168.43.62:80 # Bind HAProxy to port 80
default_backend webapp_backends # Define default backend servers
option forwardfor # Add HTTP header "X-Forwarded-For" to requests
- bind setting assigns a listener to a given IP address and port.
default_backend
gives the name of abackend
to send traffic to.- option forwardfor enables HTTP header “X-Forwarded-For” on all HAProxy requests sent to the server. This header contains a value representing the client’s IP address
The backend configuration section;
backend webapp_backends
balance roundrobin
server webapp_01.example.com 192.168.43.252:80 check
server webapp_02.example.com 192.168.43.174:80 check
- balance setting defines the roundrobin load balancer scheduling algorithm.
- server setting specify the servers available in the back end.
- check – enables health checks on the server. By default, a server is always considered available. If set, the server is available when accepting periodic TCP connections, to ensure that it is really able to serve requests.
Additionally, we are going to define the listener statistics section.
listen stats
bind 192.168.43.62:80 # Bind stats to port 80
stats enable # enable statistics reports
stats hide-version # Hide the version of HAProxy
stats refresh 30s # HAProxy refresh time
stats show-node # Shows the hostname of the node
stats auth admin:P@ssword # Authentication for Stats page
stats uri /lb_stats # Statistics URL
Finally, our HAProxy configuration file looks like in below (without comments);
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend lb_01
bind 192.168.0.102:80 # Bind HAProxy to port 80
default_backend webapp_backends # Define default backend servers
option forwardfor # Add HTTP header "X-Forwarded-For" to requests
backend webapp_backends
balance roundrobin
server webapp_01.example.com 192.168.0.110:80 check
server webapp_02.example.com 192.168.0.104:80 check
listen stats
bind 192.168.0.102:80 # Bind stats to port 80
stats enable # enable statistics reports
stats hide-version # Hide the version of HAProxy
stats refresh 30s # HAProxy refresh time
stats show-node # Shows the hostname of the node
stats auth admin:P@ssword # Authentication for Stats page
stats uri /lb_stats # Statistics URL
To read more about the configuration options used here, check the documentation page.
Run the configuration checks;
haproxy -c -f /etc/haproxy/haproxy.cfg
Configuration file is valid
Open HAProxy port on firewall.
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --reload
Running HAProxy
You can start and enable HAProxy to run on system boot by running the commands below;
systemctl restart haproxy
systemctl enable haproxy
Check the status of HAProxy.
systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2019-07-15 02:39:48 EAT; 1min 3s ago
Main PID: 12099 (haproxy)
Tasks: 2 (limit: 1143)
Memory: 2.3M
CGroup: /system.slice/haproxy.service
├─12099 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
└─12100 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
Jul 15 02:39:47 fedora29.example.com systemd[1]: Starting HAProxy Load Balancer...
Jul 15 02:39:48 fedora29.example.com systemd[1]: Started HAProxy Load Balancer.
Configure HAProxy Logging
In order to configure HAProxy standard logging, edit /etc/rsyslog.conf and enable UDP syslog reception on port 514 by removing comments (#) on the lines, #module(load=”imudp”) and #input(type=”imudp” port=”514″) as shown below.
vim /etc/rsyslog.conf
...
# Provides UDP syslog reception
# for parameters see http://www.rsyslog.com/doc/imudp.html
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")
...
Next, disable logging of messages sent to local2 facility on, (local2.none) on /var/log/messages and enable logging on /var/log/haproxy.log as shown below.
...
*.info;mail.none;authpriv.none;cron.none,local2.none /var/log/messages
local2.* /var/log/haproxy.log
Save the configuration file and run the command below to check for any errors.
rsyslogd -N1
Next, restart Rsyslog.
systemctl restart rsyslog
Restart HAProxy
systemctl restart haproxy
You should now be able to have HAProxy logs on /var/log/haproxy.log.
tail -f /var/log/haproxy.log
Jul 16 16:52:07 localhost haproxy[2050]: 192.168.0.103:45190 [16/Jul/2019:16:52:07.214] lb_01 webapp_backends/webapp_02.example.com 0/0/0/1/1 200 358 - - ---- 2/1/0/0/0 0/0 "GET / HTTP/1.1"
Jul 16 16:52:07 localhost haproxy[2050]: 192.168.0.103:45190 [16/Jul/2019:16:52:07.374] lb_01 webapp_backends/webapp_01.example.com 0/0/0/1/2 200 358 - - ---- 2/1/0/0/0 0/0 "GET / HTTP/1.1"
Configure Apache X-Forwarded-For Logging
Since we have configured HAProxy to add HTTP header “X-Forwarded-For” to all requests sent to the backend server (option forwardfor), you can configure logging for the same on the backend server. This ensures the IP address of the requesting client is captured instead of the HAProxy load balancer.
Therefore, login to the backend servers and configure Apache to log X-Forwarded-For headers. The default line we are changing is;
...
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
...
Hence, edit this line such that it looks like;
...
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
...
Save the file and run Apache configuration file syntax check command.
apachectl configtest
Syntax OK
Restart Apache
systemctl restart httpd
Testing HAProxy Load Balancer
To test HAProxy, navigate to the browser and enter the IP address of the HAProxy. When loaded and refreshed, the content from each web server is served in turns since we are using the roundrobin algorithm.
You can also check HAProxy statistics using the URL defined on the listen configuration section, http://IP-Address/lb_stats.
Well there you go. You HAProxy on Fedora 30/Fedora 29 is now running. To read more about HAProxy configuration, refer to HAProxy configuration page.
Related Tutorials
Configure HAProxy Load Balancer with SSL on Ubuntu 18.04/Debian 10/9
How to Install and Configure Pound as Apache HTTP Load balancer on Ubuntu 16.04