Recently we encountered a scenario where we needed to look for an alternative for Amazon Web Services (AWS) Elastic Load Balancing (ELB) due to an existing IIS configuration used in an organisation.  We found that HAProxy was the best candidate in terms of simplicity & the suitability for scenario we were addressing.

This post will show you how you can leverage HAProxy to load balance IIS web servers hosted in AWS EC2 and explain briefly why HAProxy is best suited to address our scenario.

The scenario

Consider you have two web servers you need to load balanced; each hosts several websites configured using multiple IP addresses.  In this case, there is no need to handle SSL at the load balancer (LB) layer, the LB only passes through SSL requests to the backend servers.

Web server 1 hosts the following websites:

  • KloudWeb port 80 with IIS binding to 192.168.137.31:80
  • KloudWeb port 443 with IIS binding to 192.168.137.31:443
  • KloudMetro port 80 with IIS binding to 192.168.137.15:80
  • KloudMetro port 443 with IIS binding to 192.168.137.15:443
  • Note: 192.168.137.31 is the primary interface IP address of web server 1.

Web server 2 hosts the following websites:

  • KloudWeb port 80 with IIS binding to 192.168.137.187:80
  • KloudWeb port 443 with IIS binding to 192.168.137.187:443
  • KloudMetro port 80 binding to 192.168.137.107:80
  • KloudMetro port 443 binding to 192.168.137.107:443
  • Note: 192.168.137.187 is the primary interface IP address of web server 2.

Why Amazon Elastic Load Balancer is less ideal in this case?

ELB only delivers traffic and load balance the primary interface i.e. eth0.  To make this scenario work with ELB, the IIS binding configuration needs to be amended to either the following:

  • KloudWeb or KloudMetro will need to change ports other than port 80 or 443 for the HTTP and HTTPS respectively; or
  • Use different host headers

Those alternatives could not be employed as we needed to migrate environments as-is.  Given this, replacing ELB is the most viable option to support the scenario. Note: There are merits for binding different IPs for different sites, however a similar goal can be achieved with a single IP address by assigning custom ports on the binding settings in IIS – host headers. Further details on the pros and cons on both approaches can be found  here.

Why HAProxy?

HAProxy is a very popular choice for replacing ELB in many AWS scenarios.  It provides both the features of L4 & L7 traditional load balancers and a flexibility that is rarely found in a software based load balancer.  We also assessed alternatives such as LVS or NGINX – both of which are free for use, but decided to go ahead with HAProxy since it supports SSL pass-through using its tcp port forwarder feature and the simplicity it provides.

One thing to note: at the time of writing, HAProxy stable release 1.4 does not support SSL termination at the load balancer (there are 3rd party tools that can support them e.g. bundled with nginx). The newest version (in dev) now supports SSL offload capability therefore eliminating the need to install any components outside HAProxy to handle SSL.

The Preparation Steps

To prepare, we need the following info:

  • The Load Balancer “VIP” addresses
  • Backend addresses (since you need to bind the VIP addresses to the different backend addresses)
  • LB listener ports and backend server ports

Let’s get hands on

First of all, you may be surprised by how simple it is to configure HAProxy on AWS.  Key thing is to understand what goal or scenario you would like to achieve and (once again), the preparation to collect relevant information.

Instance creation

  • We have chosen to use the ‘vanilla’ Amazon Linux AMI in Sydney. Spin this instance up on the UI or command line
  • Assigned two IP addresses for this HAProxy instance to host the two websites
  • Created a security group which only allows SSH (port 22) and Web connections (port 80 & 443).  You can also separate them to limit  SSH connection from certain addresses for an additional security
  • Connect to your newly created instance (via Putty or the built-in AWS Java console)

Configure your HAProxy

  • Make sure you have changed as root or an account with a sudo right
  • Install haproxy – yum install haproxy
  • Once it is installed, browse to the /etc/haproxy directory and review the haproxy.cfg file
  • Backup the haproxy.cfg file – cp haproxy.cfg haproxy.cfg.backup
  • Modify the original file with the following configuration – vi haproxy.cfg

[code language=”bash”]
#———————————————————————
# Global settings
#———————————————————————
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the ‘-r’ option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats

#———————————————————————
# common defaults that all the ‘listen’ and ‘backend’ sections will
# use if not designated in their block
#———————————————————————
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

# KloudWeb & KloudMetro Web Servers
# ———————–

listen kloudwebhttp
bind 192.168.200.10:80
mode http
stats enable
stats auth admin:apassword
balance roundrobin
option httpchk /kloudlb/test.aspx
server webserver1 192.168.137.31:80
server webserver2 192.168.137.187:80

listen kloudwebhttps
bind 192.168.200.10:443
mode tcp
balance roundrobin
server webserver1 192.168.137.31:443
server webserver1 192.168.137.187:443

listen kloudmetrohttp
bind 192.168.200.11:80
mode http
stats enable
stats auth admin:apassword
balance roundrobin
option httpchk /kloudlb/test.aspx
server webserver1 192.168.137.15:80
server webserver2 192.168.137.107:80

listen kloudmetrohttps
bind 192.168.200.11:443
mode tcp
balance roundrobin
server webserver1 192.168.137.15:443
server webserver1 192.168.137.107:443
[/code]

Testing

Once you have modified the file, run HAProxy to test its functionality

  • On a SSH console, enter – service haproxy start
  • HAProxy will verify the configuration and start the service
  • From this point you can see the built-in dashboard of your new HAProxy configuration by going to the link below
    • http://<HAProxyIPaddress>/haproxy?stats
  • Hit or access your website (with IP or DNS)
  • Any new requests will update  the stats shown here in real time (see kloudmetrohttp for updated stats)

The HAProxy Configuration explained

Apart from the default configuration, this section briefly details the configuration file we used above. See the following documentation for more info.  There are ways you can leverage the vast features of HAProxy such as performing advanced health checks based on regular expression and modifying polling time which are beyond the scope of this blog post.

# listen <name> -- this specifies Haproxy listener group, you can define a logical name for your servers

# bind <IP addr of LB>:<LB listener port> -- The binding IP address & port

# mode <http or tcp> -- this is set to http (L7 load balancing) or TCP (L4 load balancing)

# stats enable -- Enable the Haproxy stats

# stats auth admin:<anypassword> -- Set the username and password for accessing the site

# balance roundrobin -- this sets the algorithm used for load balancing requests.

# option httpchk <uri> -- this configuration will perform an optional health check to put the listener in or out of service

# server <name> <server ip addr>:<server port> check port <server port> -- this sets the backend servers which will be load balanced.
Category:
Amazon Web Services, Cloud Infrastructure
Tags:
,

Join the conversation! 9 Comments

  1. I think you’ve failed to address the real difficulty with replacing ELBs.

    Amazon has a fairly high failure rate of instances, and in your solution, when one of (or the only) haproxy load balancing node dies or goes silent, effectively your site is then offline.

    I have spent considerable time solving this exact issue for a variety of different application stacks and would happily advise further if required.

    • Hi, Thanks for your comment. The scenario is for a proof of concept environment with limited traffic requirement and specifically highlighting when you should look for ELB alternatives. I agree that a high available solution appropriate for simulating a prod environment.

  2. how can you use haproxy to load balance to an ELB. This is because we except the web servers to use autoscale and ip not to be static.

    • Denise. You typically wouldn’t see HAProxy Load Balancing to an ELB – it is normally utilised as a replacement for ELBs. There are a few ways you can continue to use HAProxy in an elastically scaled environment but none them has the “automagic” capabilities of the AWS ELB.

      • The autoscale scenario you mentioned is actually better suited for ELB. This assumes that your web servers aren’t bound to multiple net interfaces (as above)

        You can configure autoscale web servers by setting up autoscaling normally, create a launch config and scaling policy. You then add ELB health check to the autoscaling group created earlier.

  3. can we configure HA Proxy in Windows Server 2012 Instance in AWS

    • Piyush – HAProxy is a Linux-based solution. While you could install it on Windows using Cygwin or similar it is unlikely to provide you with the stability or performance you’d want. There are commercial appliance instances you can buy on AWS that may suit your needs but they still typically require some familiarity with load balancing setups. HTH.

      • Per my colleague’s response, haproxy is a linux based software LB but there are alternatives available.

        One that comes to mind is NGINX. I personally haven’t tested if their windows binary is compatible with Windows Server 2012, but the features-set will support the above scenario.

  4. Hi, thanks for a nice and easy to understand blog. It was very helpful for us to setup round robin load balance for our website.

    In your blog above, the webserver1 has been repeated twice instead of webserver2. Was it intentional or a typo?
    server webserver1 192.168.137.31:443
    server webserver1 192.168.137.187:443

    Thanks and regards,
    Diwakar

Comments are closed.