├── .gitignore ├── LICENSE ├── README.md ├── Vagrantfile ├── haproxy-setup.sh └── web-setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .vagrant/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Justin Ellison 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | vagrant-haproxy-demo 2 | ==================== 3 | 4 | Demo of HAProxy using Vagrant 5 | 6 | This is the toolset I used to present on load balancers at University of Nebraska at Kearney on 2/19/14. 7 | 8 | # What does the Vagrantfile do? 9 | * It sets up a 3 VM mini-network inside Virtualbox. The three hosts are haproxy (172.28.33.1), web1 (172.28.33.11), and web2 (172.28.33.12) 10 | * It sets up the following port forwards between your host's external interface and the internal VM's: 11 | 12 | | Host port | Guest machine | Guest port | Notes 13 | ------------|---------------|------------|--- 14 | | 8080 | haproxy | 8080 | HAProxy Admin Interface 15 | | 8081 | haproxy | 80 | Load Balanced Apache 16 | * It installs Apache on the two web servers, and configures it with a index page that identifies which host you're viewing the page on. 17 | * It installs HAProxy on the haproxy host, and drops a configuration file in place with the two webservers pre-configured. It doesn't require HAProxy to be the default gateway because it NAT's the source IP as well as the destination IP. 18 | 19 | # Prerequisites 20 | 1. Install [Vagrant](http://www.vagrantup.com/downloads.html) 21 | 2. Install [Virtualbox](https://www.virtualbox.org/wiki/Downloads) 22 | 3. Either clone this repo with ``` git clone https://github.com/justintime/vagrant-haproxy-demo.git ``` or just download the [current zip file](https://github.com/justintime/vagrant-haproxy-demo/archive/master.zip) and extract it in an empty directory. 23 | 24 | # Getting started 25 | 1. Open 3 terminal windows -- one for each host. Change to the directory containing the Vagrantfile from step 3 above. 26 | 2. In terminal #1, run ``` vagrant up haproxy && vagrant ssh haproxy ``` 27 | 3. In terminal #2, run ``` vagrant up web1 && vagrant ssh web1 ``` 28 | 4. In terminal #3, run ``` vagrant up web2 && vagrant ssh web2 ``` 29 | 5. Open up [http://localhost:8080/haproxy?stats](http://localhost:8080/haproxy?stats) in your host's browser. This is the HAProxy admin interface. 30 | 6. Open up [http://localhost:8081/](http://localhost:8081/) in your host's browser. This is the load balanced interface to the two web servers. **Note** this is port forwarded via your actual host, and will be accessible via your externally accessible IP address - you can access test the load balancer from another workstation if you wish. 31 | 7. Open up [http://172.28.33.11/](http://172.28.33.11/) in a browser to see if web1's Apache is working. 32 | 8. Open up [http://172.28.33.12/](http://172.28.33.12/) in a browser to see if web2's Apache is working. 33 | 5. To see the Apache access logs on web1 and web2, run ``` sudo tail -f /var/log/apache2/access.log ``` If you'd like to filter out the "pings" from the load balancer, run ``` sudo tail -f /var/log/apache2/access.log | grep -v OPTIONS ``` 34 | 6. To stop Apache on one of the webservers to simulate an outage, run ``` sudo service apache2 stop ``` To start it again, run ``` sudo service apache2 start ``` 35 | 7. To make changes to haproxy, edit the config file with ``` sudo nano /etc/haproxy/haproxy.cfg ``` When you want to apply the changes, run ``` sudo service haproxy reload ``` If you break things and want to reset back, just run ``` sudo cp /etc/haproxy/haproxy.cfg.orig /etc/haproxy/haproxy.cfg && sudo service haproxy reload ``` 36 | 8. When you're all done, type ``` exit ``` at the shell to get back to your local terminal. 37 | 9. To shut down the VM's, run ``` vagrant halt web1 web2 haproxy ``` 38 | 10. To remove the VM's from your hard drive, run ``` vagrant destroy web1 web2 haproxy ``` 39 | 11. If you wish to remove the cached image file from which these machines were created, run ``` vagrant box remove precise32 ``` 40 | 41 | # Reference material 42 | * [Vagrant](http://vagrantup.com) 43 | * [VirtualBox](http://www.virtualbox.org) 44 | * [HAProxy](http://haproxy.1wt.eu/) 45 | * [How to run HAProxy with TProxy for half-NAT setups](http://blog.loadbalancer.org/configure-haproxy-with-tproxy-kernel-for-full-transparent-proxy/) 46 | 47 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | VAGRANTFILE_API_VERSION = "2" 5 | 6 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 7 | config.vm.box = "precise32" 8 | config.vm.box_url = "http://files.vagrantup.com/precise32.box" 9 | config.vm.provider "virtualbox" do |v| 10 | v.customize ["modifyvm", :id, "--memory", 256] 11 | end 12 | 13 | config.vm.define :haproxy, primary: true do |haproxy_config| 14 | 15 | haproxy_config.vm.hostname = 'haproxy' 16 | haproxy_config.vm.network :forwarded_port, guest: 8080, host: 8080 17 | haproxy_config.vm.network :forwarded_port, guest: 80, host: 8081 18 | 19 | haproxy_config.vm.network :private_network, ip: "172.28.33.10" 20 | haproxy_config.vm.provision :shell, :path => "haproxy-setup.sh" 21 | 22 | end 23 | config.vm.define :web1 do |web1_config| 24 | 25 | web1_config.vm.hostname = 'web1' 26 | web1_config.vm.network :private_network, ip: "172.28.33.11" 27 | web1_config.vm.provision :shell, :path => "web-setup.sh" 28 | 29 | 30 | end 31 | config.vm.define :web2 do |web2_config| 32 | 33 | web2_config.vm.hostname = 'web2' 34 | web2_config.vm.network :private_network, ip: "172.28.33.12" 35 | web2_config.vm.provision :shell, :path => "web-setup.sh" 36 | 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /haproxy-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -f /etc/haproxy/haproxy.cfg ]; then 4 | 5 | # Install haproxy 6 | /usr/bin/apt-get -y install haproxy 7 | 8 | # Configure haproxy 9 | cat > /etc/default/haproxy < /etc/haproxy/haproxy.cfg < /var/www/index.html <${HOSTNAME}

${HOSTNAME}

9 |

This is the default web page for ${HOSTNAME}.

10 | 11 | EOD 12 | 13 | # Log the X-Forwarded-For 14 | perl -pi -e 's/^LogFormat "\%h (.* combined)$/LogFormat "%h %{X-Forwarded-For}i $1/' /etc/apache2/apache2.conf 15 | /usr/sbin/service apache2 restart 16 | 17 | fi 18 | 19 | --------------------------------------------------------------------------------