Bu örneğimizde HAProxy load balancer sunucusuna istek gönderip, cevabı yine load balancer aracılığıyla web sunucularından alacağız. İstekler hiçbir zaman web sunucusuna direkt olarak iletilmeyecek. İsteklerin hangi web sunucular tarafından işleneceğine load balancer karar verir. Bu örnek vagrant ile layer 4 (transport layer) load balancing modeli üzerine kuruludur. HAProxy konfigürasyon bilgileri için burayı tıklayın.

Örnekte iki web sunucusunda apache ve diğer load balancer sunucusunda ise HAProxy çalışıyor olacak. Load balancer GUI host makinadan ulaşılabilir olacak ve bu şekilde web sunucuları ile ilgili istatistikleri görebileceğiz.


Not


Bu örnek vagrant üzerine kurulu olduğu için, Keepalived sanal IP beklendiği gibi çalışmayabilir ama aynı durumun normal sunucular üzerinde de ortaya çıkacağı anlamına gelmez.


Yaptığımız şey



Konfigürasyon


Sisteminizde vagrant ve Oracle VM yazılımlarının kurulu olduğunu varsayıyorum. Bununla birlikte ubuntu/trusty64 kutusunun sisteminize vagrant box add ubuntu/trusty64 komutu ile eklendiğini de varsayıyorum. Eğer emin değilseniz ls -l ~/.vagrant.d/boxes/ komutu ile kontrol edebilirsiniz.


Yeni proje klasörü yaratmak


mkdir lay4-hap1-web2
$ cd lay4-hap1-web2/

webserver.sh dosyası


#!/usr/bin/env bash

# BEGIN ########################################################################
echo -e "-- ----------------- --\n"
echo -e "-- BEGIN ${HOSTNAME} --\n"
echo -e "-- ----------------- --\n"

# VARIABLES ####################################################################
echo -e "-- Setting global variables\n"
APACHE_CONFIG=/etc/apache2/apache2.conf
LOCALHOST=localhost

# BOX ##########################################################################
echo -e "-- Updating packages list\n"
apt-get update -y -qq

# APACHE #######################################################################
echo -e "-- Installing Apache web server\n"
apt-get install -y apache2 > /dev/null 2>&1

echo -e "-- Adding ServerName to Apache config\n"
grep -q "ServerName ${LOCALHOST}" "${APACHE_CONFIG}" || echo "ServerName ${LOCALHOST}" >> "${APACHE_CONFIG}"

echo -e "-- Restarting Apache web server\n"
service apache2 restart

# TEST #########################################################################
echo -e "-- Creating a dummy index.html file\n"
cat > /var/www/html/index.html <<EOD
<html>
<head>
<title>${HOSTNAME}</title>
</head>
<body>
<h1>${HOSTNAME}</h1>
<p>Hi sir, I am going to serve you today!</p>
</body>
</html>
EOD

# END ##########################################################################
echo -e "-- -------------- --"
echo -e "-- END ${HOSTNAME} --"
echo -e "-- -------------- --"

haproxy.sh dosyası


#!/usr/bin/env bash

# BEGIN ########################################################################
echo -e "-- ------------- --\n"
echo -e "-- BEGIN HAPROXY --\n"
echo -e "-- ------------- --\n"

# BOX ##########################################################################
echo -e "-- Updating packages list\n"
apt-get update -y -qq

# HAPROXY ######################################################################
echo -e "-- Installing HAProxy\n"
apt-get install -y haproxy > /dev/null 2>&1

echo -e "-- Enabling HAProxy as a start-up deamon\n"
cat > /etc/default/haproxy <<EOF
ENABLED=1
EOF

echo -e "-- Configuring HAProxy\n"
cat > /etc/haproxy/haproxy.cfg <<EOF
global
log /dev/log local0
log localhost local1 notice
user haproxy
group haproxy
maxconn 2000
daemon

defaults
log global
mode http
option httplog
option dontlognull
retries 3
timeout connect 5000
timeout client 50000
timeout server 50000

frontend http-in
bind *:80
default_backend webservers

backend webservers
balance roundrobin
stats enable
stats auth admin:admin
stats uri /haproxy?stats
option httpchk
option forwardfor
option http-server-close
server webserver1 192.168.50.10:80 check
server webserver2 192.168.50.20:80 check
EOF

echo -e "-- Validating HAProxy configuration\n"
haproxy -f /etc/haproxy/haproxy.cfg -c

echo -e "-- Starting HAProxy\n"
service haproxy start

# END ##########################################################################
echo -e "-- ----------- --"
echo -e "-- END HAPROXY --"
echo -e "-- ----------- --"

Vagrantfile içeriği


# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"

# Configs for web server 1
config.vm.define :webserver1 do |webserver1_config|
webserver1_config.vm.provider :virtualbox do |vb_config|
vb_config.name = "Web Server 1 - lay4-hap1-web2"
end
webserver1_config.vm.hostname = "webserver1"
webserver1_config.vm.network "private_network", ip: "192.168.50.10"
webserver1_config.vm.provision :shell, path: "webserver.sh"
end

# Configs for web server 2
config.vm.define :webserver2 do |webserver2_config|
webserver2_config.vm.provider :virtualbox do |vb_config|
vb_config.name = "Web Server 2 - lay4-hap1-web2"
end
webserver2_config.vm.hostname = "webserver2"
webserver2_config.vm.network "private_network", ip: "192.168.50.20"
webserver2_config.vm.provision :shell, path: "webserver.sh"
end

# Configs for haproxy
config.vm.define :haproxy do |haproxy_config|
haproxy_config.vm.provider :virtualbox do |vb_config|
vb_config.name = "HAProxy - lay4-hap1-web2"
end
haproxy_config.vm.hostname = "haproxy"
haproxy_config.vm.network :forwarded_port, guest: 80, host: 8080
haproxy_config.vm.network "private_network", ip: "192.168.50.30"
haproxy_config.vm.provision :shell, path: "haproxy.sh"
end
end

Vagrant kutusunu başlatmak


$ vagrant up --provision
Bringing machine 'webserver1' up with 'virtualbox' provider...
Bringing machine 'webserver2' up with 'virtualbox' provider...
Bringing machine 'haproxy' up with 'virtualbox' provider...
==> webserver1: ......
==> webserver1: ......
==> webserver1: ......
==> webserver1: -- Setting global variables
==> webserver1: -- Updating packages list
==> webserver1: -- Installing Apache web server
==> webserver1: -- Adding ServerName to Apache config
==> webserver1: -- Restarting Apache web server
==> webserver1: * Restarting web server apache2
==> webserver1: ...done.
==> webserver1: -- Creating a dummy index.html file
==> webserver2: ......
==> webserver2: ......
==> webserver2: ......
==> webserver2: -- Setting global variables
==> webserver2: -- Updating packages list
==> webserver2: -- Installing Apache web server
==> webserver2: -- Adding ServerName to Apache config
==> webserver2: -- Restarting Apache web server
==> webserver2: * Restarting web server apache2
==> webserver2: ...done.
==> webserver2: -- Creating a dummy index.html file
==> haproxy: ......
==> haproxy: ......
==> haproxy: ......
==> haproxy: -- Installing HAProxy
==> haproxy: -- Enabling HAProxy as a start-up daemon
==> haproxy: -- Configuring HAProxy
==> haproxy: -- Validating HAProxy configuration
==> haproxy: Configuration file is valid
==> haproxy: -- Starting HAProxy
==> haproxy: * Starting haproxy haproxy
==> haproxy: ...done.

Kutulara girmek


# Server 1
$ vagrant ssh webserver1
vagrant@webserver1:~$

# Server 2
$ vagrant ssh webserver2
vagrant@webserver2:~$

# HAProxy
$ vagrant ssh haproxy
vagrant@haproxy:~$

Testler


Normal hayatta web sunucularına direkt ulaşımın kesilmesi lazım ama ben bunu bu örnekte yapmayacağım.


Web sunucusu 1


Aşağıdaki isteğin sonucu her zaman aynı olacak.


# Request
http://192.168.50.10/

# Response
webserver1
Hi sir, I am going to serve you today!

Web sunucusu 2


Aşağıdaki isteğin sonucu her zaman aynı olacak.


# Request
http://192.168.50.20/

# Response
webserver2
Hi sir, I am going to serve you today!

Load balancer


Aşağıdaki isteğin sonucu her zaman farklı olacak çünkü load balancer istekleri sunucular arasında paylaştırır.


# Request
http://192.168.50.30/

# Response
webserver1
Hi sir, I am going to serve you today!

# Request
http://192.168.50.30/

# Response
webserver2
Hi sir, I am going to serve you today!

# Request
http://192.168.50.30/

# Response
webserver1
Hi sir, I am going to serve you today!

Sistem yetersizliği testi


Web sunucusu 1 kapalı


Load balancer tüm istekleri web sunucusu 2'ye yönlendirecek.


Web sunucusu 2 kapalı


Load balancer tüm istekleri web sunucusu 1'e yönlendirecek.


Web sunucusu 1 ve 2 kapalı


Load balancer istekleri artık hiçbir yere yönlendiremeyecek ve aşağıdaki hata mesajı alınacak. Hata mesajı HAProxy config dosyasındaki ayarlar ile değiştirilebilir.


503 Service Unavailable
No server is available to handle this request.

HAProxy GUI


Visit http://192.168.50.30/haproxy?stats. Login with admin:admin.