If you want the TLDR version where you just copy/paste a few lines and the lab gets created then this will do the job, it's explained in more detail below. It's great with tools like Virtualbox and Vagrant that such a lab can be set up so easily, this would have taken days to build prior to virtualization!
#install software
sudo apt-get install virtualbox vagrant git
#configure host-only subnet address in virtualbox
VBoxManage hostonlyif create
VBoxManage hostonlyif ipconfig vboxnet0 --ip 172.28.128.1 --netmask 255.255.255.0
VBoxManage dhcpserver modify --ifname vboxnet0 --ip 172.28.128.1 --netmask 255.255.255.0 --lowerip 172.28.128.100 --upperip 172.28.128.250
#install the lab files, for some reason the box fails to auto-download so install it manually, should be fixed in future
git clone https://github.com/unixhead/haproxy-basic-lab && cd haproxy-basic-lab
vagrant box add hashicorp/precise32 https://vagrantcloud.com/hashicorp/boxes/precise32/versions/1.0.0/providers/virtualbox.box
#run the lab
vagrant up
Now there is a slight caveat in that I use Linux Mint and the current versions of Vagrant & Virtualbox aren't quite right, so I had to manually install Vagrant from the website, but never let the truth get in the way of a good story.
My Virtualbox host-only network uses the range 172.28.128.0/24 and the network to be created is shown below, a simple load balancer infront of two web servers. The client is also the hypervisor hosting the VMs. It's very similar to the configuration of the Vagrant tutorial system. Virtualbox by default uses 192.168.0.0/24 for the host-only networks but that overlaps with a few places I work so had to change it.
The files needed are listed below, save them all to the same directory and run "vagrant up" in it. You can download them all in one go from github with the command:
git clone https://github.com/unixhead/haproxy-basic-lab
Vagrantfile - The configuration for Vagrant itself providing 3 VMs using the Ubuntu 32 bit image. One is the HAProxy load balancer and two web servers.
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise32"
config.vm.provider "virtualbox" do |v|
v.memory = 1024
v.cpus = 1
end
config.vm.define "lb" do |config|
config.vm.hostname = "lb"
config.vm.network "private_network", ip: "172.28.128.10"
config.vm.provision :shell, path: "bootstrap-haproxy.sh"
end
config.vm.define "web1" do |config|
config.vm.hostname = "web1"
config.vm.network "private_network", ip: "172.28.128.11"
config.vm.provision :shell, path: "bootstrap-apache.sh"
end
config.vm.define "web2" do |config|
config.vm.hostname = "web2"
config.vm.network "private_network", ip: "172.28.128.12"
config.vm.provision :shell, path: "bootstrap-apache.sh"
end
end
bootstrap-apache.sh - This script runs on the webservers after Vagrant has built them. It installs Apache with PHP, then sets the web root to the current Vagrant project directory.
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2 php5
if ! [ -L /var/www ]; then
rm -rf /var/www
ln -fs /vagrant /var/www
fi
bootstrap-haproxy.sh - This runs on the load balancer after build, it installs HAProxy and copies the provided configuration file.
#!/usr/bin/env bash
apt-get update
apt-get install -y haproxy hatop
cp /vagrant/haproxy.cfg /etc/haproxy
echo "ENABLED=1" > /etc/default/haproxy
service haproxy start
haproxy.cfg - Basic HAProxy configuration for load balancing port 80 between two web servers.
frontend http
bind *:80
mode tcp
option tcplog
default_backend web-backend
backend web-backend
balance roundrobin
mode tcp
server web1 172.28.128.11:80 check
server web2 172.28.128.12:80 check
index.php - A basic web index to show which web server was accessed by printing the servers hostname. Both web-servers will load the same file.
<?php
echo gethostname() . "\n";
?>
To test it simply run Curl a few times against the IP address of the load balancer, the replies show that the web sessions are being balanced across both hosts:
matt@client haproxy-lab $ curl 172.28.128.10
web1
matt@client haproxy-lab $ curl 172.28.128.10
web2
matt@client haproxy-lab $ curl 172.28.128.10
web1
matt@client haproxy-lab $ curl 172.28.128.10
web2
matt@client haproxy-lab $ curl 172.28.128.10
web1
matt@client haproxy-lab $ curl 172.28.128.10
web2
matt@client haproxy-lab $ curl 172.28.128.10
web1
matt@client haproxy-lab $ curl 172.28.128.10
web2
matt@client haproxy-lab $ curl 172.28.128.10
web1
matt@client haproxy-lab $ curl 172.28.128.10
web2
matt@client haproxy-lab $ curl 172.28.128.10
web1