05/07/2016 - HAPROXY, VAGRANT
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.
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.
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.
mkdir lay4-hap1-web2
$ cd lay4-hap1-web2/
#!/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 "-- -------------- --"
#!/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 "-- ----------- --"
# -*- 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 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.
# Server 1
$ vagrant ssh webserver1
vagrant@webserver1:~$
# Server 2
$ vagrant ssh webserver2
vagrant@webserver2:~$
# HAProxy
$ vagrant ssh haproxy
vagrant@haproxy:~$
Normal hayatta web sunucularına direkt ulaşımın kesilmesi lazım ama ben bunu bu örnekte yapmayacağım.
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!
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!
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!
Load balancer tüm istekleri web sunucusu 2'ye yönlendirecek.
Load balancer tüm istekleri web sunucusu 1'e yönlendirecek.
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.
Visit http://192.168.50.30/haproxy?stats
. Login with admin:admin
.