Using HAProxy for loadbalancing 2 web servers in docker

In this blog I will share the steps I made to use HAProxy (running in a docker container) to loadbalance my web requests between two apache web servers.
I will also show how to add a health check so HAProxy will be able to detect when a webserver is down.

The two apache webservers in this blog are assumed to be available at hostname ‘apache1’ and ‘apache2’.

haproxy-loadbalance-architecture

Quickly try out yourself?

I created a github project which includes a single script to build and run two apache servers and the haproxy server to schedule between them. All you need is docker and a minute or two to let the scripts build the containers : https://github.com/J-Technologies/haproxy-ping-demo

Create the files needed for the HAProxy docker container

We need to create three files to be able to create the docker image:
– Dockerfile (this is the file which is used to build the docker image)
– haproxy.cfg (this is the haproxy configuration file)
– start.bash (this is the script to start haproxy)

Step 1: The Dockerfile file

The Dockerfile is used to build build the docker image and contains the scripts to install and run haproxy.

# Pull base image.
FROM ubuntu:trusty

RUN
  sed -i ‘s/^# (.*-backportss)/1/g’ /etc/apt/sources.list &&
  apt-get update &&
  apt-get install -y haproxy=1.5.3-1~ubuntu14.04.1 &&
  sed -i ‘s/^ENABLED=.*/ENABLED=1/’ /etc/default/haproxy &&
  rm -rf /var/lib/apt/lists/*

# Add files.
ADD haproxy.cfg /etc/haproxy/haproxy.cfg
ADD start.bash /haproxy-start

# Define default command.
CMD [“bash”, “/haproxy-start”]

# Expose ports.
EXPOSE 80
EXPOSE 81

This Dockerfile first installs and enables haproxy, copies the haproxy.cfg and start.bash files and finally exposes port 80 and port 81.

We still need to create the haproxy.cfg and start.bash which are copied to the docker container.
I’ll explain that in the following two steps.

Step 2: The haproxy.cfg file

The haproxy.cfg file contains the configuration used by haproxy and contains the following:

global
    daemon
    maxconn 256

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend http-in
    bind *:80
    default_backend apacheservers

backend apacheservers
    server apache1 apache1 maxconn 32
    server apache2 apache1 maxconn 32

listen stats :81
  stats enable
  stats uri /

This configuration file configures HAProxy to listen to 80 and load-balance all requests to the apacheservers called apache1 and apache2 (with the same hostname).

The script also configures port 81 to serve the statics page.

Step 3: The start.bash file

The last file we need to create is start.bash which is used to start HAProxy when the docker image is started.
This script contains the following content:

#!/bin/bash
HAPROXY=”/etc/haproxy”
OVERRIDE=”/haproxy-override”
PIDFILE=”/var/run/haproxy.pid”
CONFIG=”haproxy.cfg”
ERRORS=”errors”

cd “$HAPROXY”

# Symlink errors directory
if [[ -d “$OVERRIDE/$ERRORS” ]]; then
  mkdir -p “$OVERRIDE/$ERRORS”
  rm -fr “$ERRORS”
  ln -s “$OVERRIDE/$ERRORS” “$ERRORS”
fi

# Symlink config file.
if [[ -f “$OVERRIDE/$CONFIG” ]]; then
  rm -f “$CONFIG”
  ln -s “$OVERRIDE/$CONFIG” “$CONFIG”
fi

exec haproxy -f /etc/haproxy/haproxy.cfg -d -p “$PIDFILE”

Step 4: Building and starting the HAProxy docker container

 

To build the docker image, run the following command in the folder that contains the file just created:

docker build -t haproxy ./haproxy

To start the HAProxy image, run the following command:

docker run -d -it -p 80:80 -p 81:81 –name haproxy haproxy

At this moment, we are up and running!
You can now access the loadbalanced web page at:

http://%5Bip-of-server-with-haproxy%5D:80

The HAProxy statics page is available at:

http://%5Bip-of-server-with-haproxy%5D:81

 

Optional step: Adding a ping health check to HAProxy

It is possible to enable a health check to HAProxy.
HAProxy will send ping to the web servers to check active if a server is still up.

To enable the ping, change the backend section of the haproxy.cfg to the following:

backend apacheservers
    option httpchk GET /ping.html
    http-check expect string pong
    server apache1 apache1 maxconn 32 check
    server apache2 apache1 maxconn 32 check

HAProxy expects a “pong” result on the /ping.html request so make sure to add this ping.html file to the root of the webserver with the text “pong”.
When HAProxy does not receive the pong request anmore, it will not schedule any http request to this webserver.
HAProxy will continue to send ping messages and as soon as the webserver responds again it will be scheduled in again.

Another optional step: Enable sticky sessions

HAProxy can add a cookie to the requests which contains the backend server to make sure the client will contact the same backend server to preserve sessions (when used).
To enable this, change the backend section to the following:

backend apacheservers
    option httpchk GET /ping.html
    http-check expect string pong
    cookie SERVERID insert indirect nocache    
    server apache1 apache1 maxconn 32 check
    server apache2 apache1 maxconn 32 check

 

Geef een reactie

Gelieve met een van deze methodes in te loggen om je reactie te plaatsen:

WordPress.com logo

Je reageert onder je WordPress.com account. Log uit /  Bijwerken )

Google+ photo

Je reageert onder je Google+ account. Log uit /  Bijwerken )

Twitter-afbeelding

Je reageert onder je Twitter account. Log uit /  Bijwerken )

Facebook foto

Je reageert onder je Facebook account. Log uit /  Bijwerken )

Verbinden met %s