Setup Load-balancer On Linux (RHEL/CentOS) Using HAProxy


Hello There! Long time no see 😦 After a long time, I am writing a post here on this blog (this was in draft for long). Hope you have all been well 🙂

In this post, I will demonstrate how we can setup a Load-balancer on Linux (RHEL/CentOS) Using HAProxy. What is a Load-balancer, you may ask 😉 Well, Load-balancer or LB is a device (could be a dedicated network device like F5 or a server) that distributes network/application traffic among multiple nodes. Suppose, we have 2 Apache web-servers both serving the same web-site. Without an LB, all traffic will go to 1 web-server only & it will create a lot of traffic on that server. With an LB in action, we can distribute the incoming traffic between our 2 web-servers. This way, each server will have lesser load & more efficiency. This is Active/Active load-balancing. Both the nodes are active. I won’t be discussing it in detail here. You can refer to Wikipedia article for more info.

What is HAProxy, you may again ask 😉 HAProxy is an open-source load-balancing solution for Unix like servers. Its an application that can be installed on a server & that server will act as a Load-balancer.

Enough introduction 😉 Lets start with this demo 🙂

Lab Description : –

Load-balancer : –  hostname – server, IP – 10.134.39.234

Web-server1 : –  hostname – node1, IP – 10.134.39.235

Web-server2 : –  hostname – node2, IP – 10.134.39.236

Download HAProxy installer. Download the installer from official website.

Unpack the installer. Unpack the installer tarball.  We are using the source code to install it.

[root@server tmp]# tar -xf haproxy-1.5.14.tar.gz

Build the installer & Run it. Make sure to install openssl-devel & pcre-devel packages before you compile the source code or else it will throw build errors.

[root@server tmp]# yum install openssl-devel pcre-devel
[root@server haproxy-1.5.14]# make TARGET=linux2632 ARCH=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1
gcc -Iinclude -Iebtree -Wall  -O2 -g -fno-strict-aliasing       -DENABLE_POLL  -DCONFIG_HAPROXY_VERSION=\"1.5.14\" -DCONFIG_HAPROXY_DATE=\"2015/07/02\" \
              -DBUILD_TARGET='"linux2632"' \
              -DBUILD_ARCH='"native"' \
              -DBUILD_CPU='"generic"' \
              -DBUILD_CC='"gcc"' \
              -DBUILD_CFLAGS='"-O2 -g -fno-strict-aliasing"' \
              -DBUILD_OPTIONS='"USE_POLL=default"' \
               -c -o src/haproxy.o src/haproxy.c
make: gcc: Command not found
make: *** [src/haproxy.o] Error 127

You can see the it still threw an error 😉 Because it couldn’t find the GCC compiler 🙂 So we will install gcc first & re-build the installer.

[root@server haproxy-1.5.14]# make TARGET=linux2632 ARCH=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1
[root@server haproxy-1.5.14]# make install
gcc -Iinclude -Iebtree -Wall  -O2 -g -fno-strict-aliasing       -DENABLE_POLL  -DCONFIG_HAPROXY_VERSION=\"1.5.14\" -DCONFIG_HAPROXY_DATE=\"2015/07/02\" \
              -DSBINDIR='"/usr/local/sbin"' \
               -c -o src/haproxy-systemd-wrapper.o src/haproxy-systemd-wrapper.c
gcc  -g -o haproxy-systemd-wrapper src/haproxy-systemd-wrapper.o
install -d "/usr/local/sbin"
install haproxy "/usr/local/sbin"
install haproxy-systemd-wrapper "/usr/local/sbin"
install -d "/usr/local/share/man"/man1
install -m 644 doc/haproxy.1 "/usr/local/share/man"/man1
install -d "/usr/local/doc/haproxy"
for x in configuration architecture haproxy-en haproxy-fr; do \
                install -m 644 doc/$x.txt "/usr/local/doc/haproxy" ; \
        done

HAProxy has now been installed.

Create Configuration file. Create a new file at below location with the contents shown.

[root@server haproxy-1.5.14]# vi /etc/rsyslog.d/haproxy.conf
local0.* /var/log/haproxy.log

Edit rsyslog.conf file. Now we will edit rsyslog.conf file to include below lines. Ignore if already present.

[root@server haproxy-1.5.14]# vi /etc/rsyslog.conf
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

Restart rsyslog daemon to reload configuration.

[root@server haproxy-1.5.14]# service rsyslog restart
Shutting down system logger:                               [  OK  ]
Starting system logger:                                    [  OK  ]

Configure HAProxy’s configuration settings. Since HAProxy was installed from source code, it won’t be running as an OS defined process. We will have to create its configuration directories & files alongwith its start/stop init.d scripts. Our installation provided us with sample config file & we will be using that.
Carefully follow below steps.

[root@server haproxy-1.5.14]# find / -name haproxy.cfg
/tmp/haproxy-1.5.14/examples/haproxy.cfg
[root@server haproxy-1.5.14]# mkdir -p /etc/haproxy
[root@server haproxy-1.5.14]# cp -p /tmp/haproxy-1.5.14/examples/haproxy.cfg /etc/haproxy/haproxy.cfg
[root@server haproxy-1.5.14]# cp /usr/local/sbin/haproxy /usr/sbin/
[root@server haproxy-1.5.14]# find / -name haproxy.init
/tmp/haproxy-1.5.14/examples/haproxy.init
[root@server haproxy-1.5.14]# cp /tmp/haproxy-1.5.14/examples/haproxy.init /etc/init.d/haproxy
[root@server haproxy-1.5.14]# chmod 755 /etc/init.d/haproxy
[root@server haproxy-1.5.14]# useradd --system haproxy
[root@server haproxy-1.5.14]# service haproxy status
haproxy is stopped

At this point, the general configurations have been made. But if I try to start HAProxy service, it will fail 😉

[root@server haproxy-1.5.14]# service haproxy start
[ALERT] 223/055712 (12426) : parsing [/etc/haproxy/haproxy.cfg:105] : error opening file  for custom error message .
[ALERT] 223/055712 (12426) : Error(s) found in configuration file : /etc/haproxy/haproxy.cfg
[ALERT] 223/055712 (12426) : Fatal errors found in configuration.
Errors found in configuration file, check it with 'haproxy check'.

If you closely take a look at the error message, you will find that HAProxy was unable to locate the error file that it uses to diplay error messages. So, we will create the custom error file that HAProxy will use to show error messages, if there are any 🙂

[root@server haproxy-1.5.14]# mkdir -p /etc/haproxy/errors/
[root@server haproxy-1.5.14]# cp /tmp/haproxy-1.5.14/examples/errorfiles/503.http /etc/haproxy/errors/503.http

Lets start HAProxy service now.

[root@server haproxy-1.5.14]# service haproxy start
Starting haproxy: [WARNING] 223/060737 (12706) : parsing [/etc/haproxy/haproxy.cfg:24]: keyword 'redispatch' is deprecated in favor of 'option redispatch', and will not be supported by future versions.
[WARNING] 223/060737 (12706) : parsing [/etc/haproxy/haproxy.cfg:26] : the 'contimeout' directive is now deprecated in favor of 'timeout connect', and will not be supported in future versions.
[WARNING] 223/060737 (12706) : parsing [/etc/haproxy/haproxy.cfg:27] : the 'clitimeout' directive is now deprecated in favor of 'timeout client', and will not be supported in future versions.
[WARNING] 223/060737 (12706) : parsing [/etc/haproxy/haproxy.cfg:28] : the 'srvtimeout' directive is now deprecated in favor of 'timeout server', and will not be supported in future versions.
[WARNING] 223/060737 (12706) : parsing [/etc/haproxy/haproxy.cfg:60] : 'capture' ignored because backend 'LB' has no frontend capability.

So it started with a few obvious warnings 😉 We still haven’t made any modifications to HAProxy configuration file /etc/haproxy/haproxy.cfg Lets edit it with below contents. I am putting the details in the comments itself.

[root@server haproxy-1.5.14]# vi /etc/haproxy/haproxy.cfg
# this config needs haproxy-1.1.28 or haproxy-1.2.1
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
#chroot /usr/share/haproxy
uid 99
gid 99
daemon
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
timeout http-request 20
timeout queue 86400
timeout connect 86400
timeout client 86400
timeout server 86400
timeout http-keep-alive 30
timeout check 20

#Defining the details of our front-end i.e. Load-balancer. This is IP of our LB. 
frontend LB
bind 10.134.39.234:80
reqadd X-Forwarded-Proto:\ http
#frontend LBS #bind 10.134.39.234:443 ssl crt /etc/ssl/shashank.pem #reqadd X-Forwarded-Proto:\ https
#default_backend LB Here we will define LB alongwith our 2 web-servers.
backend LB 10.134.39.234:80
#redirect scheme https if !{ ssl_fc }
mode http
stats enable
stats hide-version
stats uri /stats
stats realm Haproxy\ Statistics
stats auth haproxy:shashank
balance roundrobin
option httpchk
option httpclose
option forwardfor
cookie LB insert
server node1 10.134.39.235:80 cookie node1 check
server node2 10.134.39.236:80 check backup

capture cookie vgnvisitor= len 32

rspidel ^Set-cookie:\ IP= # do not let this cookie tell our internal IP address

errorloc 502 http://10.134.39.234/error502.html
errorfile 503 /etc/haproxy/errors/503.http

If you carefully read the above configuration file, you will see that there is a directive stats auth haproxy:shashank There are your credentials to login to HAProxy web front end. HAProxy provides with a web-console to administer its tasks & show the status. So, haproxy is the user-name (it was created earlier) & shashank is password. You will also see web-server details in the file above 🙂 Remember that node1 & node2 are hostnames to our web-servers. So, after editing the config file, restart HAProxy service & you will see this 😉

[root@server haproxy-1.5.14]#
Message from syslogd@localhost at Aug 12 06:10:47 ...
haproxy[12804]: backend LB has no server available!

Message from syslogd@localhost at Aug 12 06:10:47 ...
haproxy[12804]: backend LB has no server available!

Create a simple webpage to demonstrate Load-balancer. We will now create a simple page to be served by our webservers. You may use any webpage. Otherwise just paste the following text into a file called index.html under your DocumentRoot on both the web-servers. Make sure to change node1 to node2 on other node 😉

Shashank Srivastava HAProxy Load-balancer Demo Page

Demonstrating HAProxy Load-balancing Our Web-servers!

Welcome to WatILearnd2day.wordpress.com! Here is our Load-balancer in action!

It is serving our Apache web-server from node1.shashank.com.

Test Load-balancer. If everything has been correctly setup, open your browser & type in IP address of your load-balancer. It will show you from which web-server its serving the web-page. Keep on refreshing the page & you will see web-page being served from both web-servers.

HAProxy

HAProxy3

Now try stopping Apache service on any web-server & then refresh the web-page. HAProxy will server the page from other web-server.

[root@node1 ~]# service httpd stop
Stopping httpd: [ OK ]

As I told you HAProxy has a web-based console for its administration, you can go to IP_address_of_LB/stats page to see that. Credentials are mentioned in your HAProxy config file.

HAProxy1

Now stop Apache on both the servers. Then refresh the web-page. It will show you an error 🙂

HAProxy2

That’s all from today 🙂 Hope this post was easy to understand & follow.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s