Skip to content

How to create a HAproxy Load Balancer with floating IP

homepage-banner

Background

An Internet-facing load balancer has a publicly available IP address. This allows it to route requests from clients over the Internet to the EC2 instances registered with the balancer. We use this approach to make your DB connectable from the Internet using a single, static EIP.

In this guide, we will use a simple 2+1 cluster in a private subnet, which includes two active nodes and one spare node.

Prerequisites

  1. Two instances with equal equipment, e.g., t2-micro Amazon Linux AMI (RedHat)
  2. Two public IP addresses
  3. One elastic IP address
  4. AWS API access (AWS Secret and AWS Key)
  5. HAproxy and Keepalived

How to Create an HAproxy Load Balancer with Floating IP

This guide explains how to install two HAproxy instances (Master 10.0.1.207 and Slave 10.0.1.190). The DB nodes use 10.0.1.11,10.0.1.12,10.0.1.13.

Installation

(1) Launch a t2.micro Amazon Linux instance from the EC2 console using the DB subnet.

(2) Enable Auto-assign Public IP.

(3) Add Storage and Tags as per your requirements.

(4) The security group should permit incoming traffic on the database port TCP 8563 and allow SSH for the configuration and installation of the packages. If you also want to use the HAproxy statistics server, open TCP 9090. Master and Slave need to exchange vitality information as well.

(5) Log into both instances using the SSH user ‘ec2-user’.

(6) Update system packages and install HAProxy and Keepalived. Ensure that you get the latest version of Keepalived from http://www.keepalived.org/download.html.

[ec2-user@ip-10-0-1-207 ~]$ sudo mkdir /usr/libexec/keepalived/
[ec2-user@ip-10-0-1-207 ~]$ sudo yum -y upgrade && sudo yum -y install haproxy keepalived && sudo reboot

(7) Use the packages from the repo in Point 6 OR install the latest Keepalived (additional packages required, see below).

[root@ip-10-0-1-207]# yum install -y openssl-devel kernel-devel kernel-headers gcc && wget http://www.keepalived.org/software/keepalived-1.3.2.tar.gz && tar xf keepalived* && cd keepalived-1.3.2 && mkdir /opt/keepalived && ./configure --prefix=/opt/keepalived && make && make install

If Keepalived has been compiled from the source, use the steps below. You also need the init script (attached to this article) and the sysconfig file of Keepalived.

[root@ip-10-0-1-207]# cp keepalived_initd.txt /etc/init.d/keepalived
[root@ip-10-0-1-207]# cp /root/keepalived-1.3.2/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@ip-10-0-1-207]# cp /root/keepalived-1.3.2/keepalived/etc/init/keepalived.conf /etc/init/
[root@ip-10-0-1-207]# ln -s /opt/keepalived/sbin/keepalived /usr/sbin/
[root@ip-10-0-1-207]# mkdir /etc/keepalived/
[root@ip-10-0-1-207]# cp /opt/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
[root@ip-10-0-1-207]# mkdir /usr/libexec/keepalived/
[root@ip-10-0-1-207]# useradd -M keepalived_script

Configuration

(1) Configure HAproxy Master and Slave (copy it to both instances)

[ec2-user@ip-10-0-1-207 ~]$ cat /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

defaults
        log     global
        mode    tcp
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client 50000
        timeout server 50000

listen stats :9090
        balance
        mode http
        stats enable
        stats uri /haproxy_stats
        stats auth admin:strongPassworD

listen DB_proxy :8563
        mode tcp
        option tcplog
        balance roundrobin

        serverip-10-0-1-11.eu-west-1.compute.internal 10.0.1.11:8563 weight 1 check rise 2 fall 3
        serverip-10-0-1-12.eu-west-1.compute.internal 10.0.1.12:8563 weight 1 check rise 2 fall 3
        serverip-10-0-1-13.eu-west-1.compute.internal 10.0.1.13:8563 weight 1 check rise 2 fall 3

(2) Configure Keepalived Master

[ec2-user@ip-10-0-1-207 ~]$ cat /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}

vrrp_instance VI_1 {
debug 2
interface eth0                  # interface to monitor
state MASTER
virtual_router_id 1             # Assign one ID for this route
priority 101                    # 101 on master, 100 on slave
unicast_src_ip 10.0.1.207       # Private IP
unicast_peer {
10.0.1.190
}
track_script {
chk_haproxy
}
notify_master "/usr/libexec/keepalived/notify.sh MASTER"
notify_backup "/usr/libexec/keepalived/notify.sh BACKUP"
notify_fault "/usr/libexec/keepalived/notify.sh FAULT"

}

(3) Configure Keepalived Slave

[ec2-user@ip-10-0-1-190 ~]$ cat /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}

vrrp_instance VI_1 {
debug 2
interface eth0                  # interface to monitor
state BACKUP
virtual_router_id 1             # Assign one ID for this route
priority 100                    # 101 on master, 100 on slave
unicast_src_ip 10.0.1.190       # Private IP
unicast_peer {
10.0.1.207
}
track_script {
chk_haproxy
}
notify_master "/usr/libexec/keepalived/notify.sh MASTER"
notify_backup "/usr/libexec/keepalived/notify.sh BACKUP"
notify_fault "/usr/libexec/keepalived/notify.sh FAULT"
}

(4) Keepalived will trigger a script when the HAproxy service fails on the current master, deploy the scripts (notify.sh, master.sh, backup.sh) on both instances ((!) change owner to keepalived_script if using the latest version of keepalived)

[root@ip-10-0-1-207 ec2-user]# cat /usr/libexec/keepalived/notify.sh
#!/bin/bash

STATE=$1
NOW=$(date +"%D %T")
KEEPALIVED="/tmp"

case $STATE in
        "MASTER") touch $KEEPALIVED/MASTER
                  echo "$NOW Becoming MASTER" >> $KEEPALIVED/COUNTER
                  /usr/libexec/keepalived/master.sh
                  exit 0
                  ;;
        "BACKUP") rm $KEEPALIVED/MASTER
                  echo "$NOW Becoming BACKUP" >> $KEEPALIVED/COUNTER
                  /usr/libexec/keepalived/backup.sh
                  exit 0
                  ;;
        "FAULT")  rm $KEEPALIVED/MASTER
                  echo "$NOW Becoming FAULT" >> $KEEPALIVED/COUNTER
                  /usr/libexec/keepalived/backup.sh
                  exit 0
                  ;;
        *)        echo "unknown state"
                  echo "$NOW Becoming UNKOWN" >> $KEEPALIVED/COUNTER
                  exit 1
                  ;;
esac

(5) Master Script (change owner to keepalived_script if using the latest version of keepalived)

[root@ip-10-0-1-207 ec2-user]# cat /usr/libexec/keepalived/master.sh
#!/bin/bash

exec >> /tmp/master.log
exec 2>&1
#set -x

AWS_ACCESS_KEY=Key
AWS_SECRET_KEY=Secret
export EC2_URL=https://ec2.eu-west-1.amazonaws.com
export EC2_HOME="/opt/aws/apitools/ec2"
export JAVA_HOME=/usr/lib/jvm/jre
export AWS_CLOUDWATCH_HOME=/opt/aws/apitools/mon
export AWS_PATH=/opt/aws
export AWS_AUTO_SCALING_HOME=/opt/aws/apitools/as
export AWS_ELB_HOME=/opt/aws/apitools/elb

EIP=34.249.49.35 # Elastic IP to be associated

INSTANCE_ID=$(curl -shttp://169.254.169.254/latest/meta-data/instance-id)
PRIVATE_IP=$(curl -shttp://169.254.169.254/latest/meta-data/local-ipv4)
/opt/aws/bin/ec2-associate-address -O $AWS_ACCESS_KEY -W $AWS_SECRET_KEY -U $EC2_URL $EIP -instance $INSTANCE_ID -p $PRIVATE_IP --allow-reassociation
echo "$(date) I'm master now"

(6) Backup Script (change owner to keepalived_script if using the latest version of keepalived)

[root@ip-10-0-1-207 ec2-user]# cat /usr/libexec/keepalived/backup.sh
#!/bin/bash

exec >> /tmp/backup.log
exec 2>&1
#set -x

echo "$(date) I'm backup nothing to do"

(7) Make keepalived scripts executable (both instances)

[root@ip-10-0-1-207 ec2-user]# chmod +x /usr/libexec/keepalived/*sh && chmod 700 /usr/libexec/keepalived/*sh

(8) Enable HAproxy und Keepalived on Start-up (both instances)

[root@ip-10-0-1-207 ec2-user]# chkconfig haproxy on && chkconfig keepalived on

(9) Start HAproxy and Keepalived on the master and check logs

[root@ip-10-0-1-207 ec2-user]# service haproxy start && service keepalived start
[root@ip-10-0-1-207 ec2-user]# tail -n 30 /var/log/messages

(10) Start HAproxy and Keepalived on the slave and check logs

[root@ip-10-0-1-207 ec2-user]# service haproxy start && service keepalived start
[root@ip-10-0-1-207 ec2-user]# tail -n 30 /var/log/messages
Leave a message