In this guide, we are going to learn how to install and configure Pound as an Apache http /https requests load balancer on Ubuntu 16.04.
So what exactly is Pound and how does it work?
Pound is an open source reverse-proxy as well as load balancing server platform. It accepts requests from HTTP/HTTPS clients and distributes them to one or more back-end Web servers. The HTTPS requests are decrypted and passed to the back-end servers as plain HTTP. If more than one back-end server is defined, Pound chooses one of them randomly, based on defined priorities. By default, Pound keeps track of sessions established between clients and back-end servers.
The functionality of Pound can be simply illustrated in the figure below.
Our deployment architecture will be like as shown in the figure above with:
– Pound Server IP: 192.168.10.47
– websrv01 IP: 10.10.1.33
– websrv01 IP: 172.16.0.28
Install Apache web server on all the servers, frontend (pound) and the back-end servers. After installing, start it and if firewall is running allow it through the firewall.
On debian based
apt-get install -y apache2
systemctl start apache2
ufw allow Apache
If you are using other distros for your backend servers, use the relevant package managers to install Apache.
Installing Pound
Pound is available on Ubuntu repositories and can be installed easily with a package manager.
apt-get install -y pound
Configuring Pound HTTP load balancing
The configuration file for pound is /etc/pound/pound.cfg. In order for pound to function properly, three objects have to defined in its configuration file.
- Listeners: Listeners define how Pound receives requests from the clients (browsers). Two types of listener may be defined: regular HTTP listener and HTTPS (HTTP over SSL/TLS) listeners. At the very least a listener must define the address and port to listen on, with additional requirements for HTTPS listeners.
- Services: Aservice defines of how the requests are answered. The services may be defined within a listener or at the top level (global).
When a request is received Pound attempts to match them to each service in turn, starting with the service defined in the listener itself and, if needed, continuing with the services defined at the global level. - Back-ends: The back-ends are the actual servers for the content requested. By itself, Pound supplies no responses – all contents must be received from a “real” web server. The back-end defines how the server should be contacted. Three types of back-ends may be defined:a regular backend which receives requests and returns responses, a redirect back-end in which case Pound will respond with a redirect response, without accessing any back-end at all, or an emergency back-end which will be used only if all other back-ends are fail. The connection between Pound and the back-ends is always via HTTP, regardless of the actual protocol used between Pound and the client.
Edit the pound configuration and make the changes as follows.
vim /etc/pound/pound.cfg
Within the configuration file, set the logging level to 3, common log format for Apache and specify the log facility.
## Logging: (goes to syslog by default)
## 0 no logging
## 1 normal
## 2 extended
## 3 Apache-style (common log format)
LogLevel 3
# Add this line to specify log facility
LogFacility local1
Define the listening address for the front-end Pound server abd the Back-end web servers,
## redirect all requests on port 80 ("ListenHTTP") to the local webserver (see "Service" below):
ListenHTTP
Address 192.168.10.47
Port 80
End
## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
# xHTTP 0 # Comment out this line
# If you are going to load balance https traffic uncomment the following lines
#ListenHTTPS
# Address 192.168.10.47
# Port 443
# Cert "/etc/ssl/pound.pem"
#End
Service
BackEnd
Address 10.10.1.33 # websrv01 back-end IP address
Port 80 # Listening port for back-end websrv01
Priority 5 # Priority of this backend
End
BackEnd
Address 172.16.0.28 # IP address for second web-server backend
Port 80
Priority 5
End
End
Save the configuration file and set pound to start on boot by editing the /etc/default/pound configuration file and changing the value of startup option from 0 to 1. After that restart pound.
sed -i 's/^startup=0/startup=1/' /etc/default/pound
systemctl restart pound
Since we have configured pound to forward all the requests to port 80 to the backend servers, let us configure apache on Pound server to listen on an alternative port, say 8080. Usually pound listens on port 8080 by default.
Edit the /etc/apache2/ports.conf configuration file and change the Listening port for apache.
vim /etc/apache2/ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
#Listen 80
Listen 8080
...
Edit the virtualhost default configuration file, /etc/apache2/sites-enabled/000-default.conf and substitute port 80 with 8080.
vim /etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:8080>
Save the configuration file and restart apache.
systemctl restart apache2
Configure Logging for Pound
For Rsyslog to log events from pound, edit the /etc/rsyslog.d/50-default.conf conf file and add the highlighted lines below.
vim /etc/rsyslog.d/50-default.conf
...
6 # First some standard log files. Log by facility.
7 #
8 auth,authpriv.* /var/log/auth.log
9 *.*;auth,authpriv.none;local1.none -/var/log/syslog
10 local1.* /var/log/pound.log
11 #cron.* /var/log/cron.log
...
Restart Rsyslog to effect the changes
systemctl restart rsyslog
Create a sample web content on the backend web servers. For example
vim /var/www/html/index.html
<!DOCTYPE html>
<html>
<body>
<h1><center>This is served from websrv01 backend web server.</center></h1>
</body>
</html>
Do the same for the second backend web server.
<!DOCTYPE html>
<html>
<body>
<h1><center>This is served from websrv02 backend web server.</center></h1>
</body>
</html>
Configure Apache on Backend servers to log requests for X-Forwarded-For, that is the original agent which sent the request.
If your backend server is CentOS, edit the configuration file /etc/httpd/conf/httpd.conf as follows.
vim /etc/httpd/conf/httpd.conf
...
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
# Comment the line below and edit it to look line the last line
# LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
...
If your backend server is an Ubuntu system, proceed as follows.
Enable remoteip module
a2enmod remoteip
Then Edit the /etc/apache2/apache2.conf configuration file and replace the contents of line 206 to 207 with the following lines.
vim /etc/apache2/apache2.conf
...
203 # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
204 # Use mod_remoteip instead.
205 #
206 RemoteIPHeader X-Forwarded-For
207 RemoteIPInternalProxy 192.168.10.47
208 LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
209 LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
...
After making the above changes. restart Apache
# systemctl restart httpd
# systemctl restart apache2
Now visit http://<pound-server-ip>, and refresh the page continuously.
You will notice that the home page continuously changes on every request.
And that is all it takes to get Pound HTTP(S) load balancer up and running.
Thanks for the thorough explanation! I’m actually using FreeBSD but the same principles apply.
Also note that the module
logio_module
must be enabled as well, or the %O directive will not work (maybe Ubuntu has it by default; unfortunately I run nginx on the Ubuntu boxes and therefore are clueless about Apache’s configuration over there).Thanks for your feedback Gwyneth Llewelyn