alumno@pc:~$ bash ejercicio-haproxy.sh
Powershell.exe -executionpolicy bypass -file ejercicio-haproxy.ps1
NOTAS:
$DIR_BASE especifica donde se descargarán las imágenes y se crearán las MVs.
$HOME/CDA1516 y en Windows en C:\\CDA1516
.vdi.zip de http://ccia.ei.uvigo.es/docencia/CDA/1516/practicas
y copiarlos en el directorio anterior ($DIR_BASE) para que el script haga el resto.
DIR_BASE ($HOME/CDA1516 ó C:\\CDA1516)
base_cda.vdi (0,8 GB comprimida, 2,8 GB descomprimida):
Imagen genérica (común a todas las MVs) que contiene las herramientas a utilizar
| login | password |
|---|---|
| root | purple |
| usuario1 | usuario1 |
swap1024.vdi: Disco de 1 GB formateado como espacio de intercambio (SWAP)
VBoxManage startvm CLIENTE_<id> VBoxManage startvm BALANCEADOR_<id> VBoxManage startvm APACHE1_<id> VBoxManage startvm APACHE2_<id>
Herramienta de balanceo de carga basada en proxies HAproxy
cliente:~# startx
balanceador:~# echo 1 > /proc/sys/net/ipv4/ip_forward
/etc/apache2/apache2.conf
para realizar la evaluación del rendimiento sin la opción de reutilización de conexiones.
apache1:~# nano /etc/apache2/apache2.conf ... KeepAlive Off ...
apache2:~# nano /etc/apache2/apache2.conf ... KeepAlive Off ...
Nota:
apache1:~# nano /var/www/index.html ... ... <h1> Servidor por APACHE_UNO </h1> ...
apache1:~# nano /var/www/sesion.php ... ... <h1> Servidor por la máquina APACHE_UNO </h1> ...
apache2:~# nano /var/www/index.html ... ... <h1> Servidor por APACHE_DOS </h1> ...
apache2:~# nano /var/www/sesion.php ... ... <h1> Servidor por la máquina APACHE_DOS </h1> ...
Nota:
sleep.php usado en las pruebas
apache1~:# nano /var/www/sleep.php apache2~:# nano /var/www/sleep.php
Correcciones a realizar (marcadas con <-- AQUI)
<html>
<title> Retardos de x segundos </title>
<body>
<h1> Prueba con retardo de x segundos </h1>
<p> hora de inicio: <?php echo date('h:i:s'); ?> </p>
<?php
for ($i=0; $i < 20000; $i++) { // <-- AQUI (20000 iteraciones)
$str1 = sha1(rand()*rand()); // <-- AQUI (anadir $)
$str2 = sha1(rand()*rand()); // <-- AQUI (anadir $)
$str3 = sha1($str1+$str2); // <-- AQUI (anadir $)
}
?>
<p> hora de fin: <?php echo date('h:i:s'); ?> </p>
</body>
</html>
Comprobación
apache1~:# php /var/www/sleep.php apache2~:# php /var/www/sleep.php
Se realizarán varias pruebas de carga sobre el servidor Apache ubicado en la máquina apache1
ab) incluida en la distribución del servidor Apache
ab: (página man).
Pasos a realizar
iptables
balanceador:~# echo 1 > /proc/sys/net/ipv4/ip_forward balanceador:~# iptables -t nat -A PREROUTING \ --in-interface eth0 --protocol tcp --dport 80 \ -j DNAT --to-destination 10.10.10.11
Nota: la regla iptables establece una redirección del puerto 80 de la máquina balanceador
al mismo puerto de la máquina apache1 para el tráfico procedente de la red externa (interfaz de entrada eth0).
apache1:~# /etc/init.d/apache2 start
Nota: Desde la máquina cliente [193.147.87.33] se puede abrir en un navegador web la
URL http://193.147.87.47 para comprobar que el servidor está arrancado y que la
redirección del puerto 80 está funcionando.
Pruebas a realizar:
cliente:~# ab -n 2000 -c 10 http://193.147.87.47/index.html cliente:~# ab -n 2000 -c 50 http://193.147.87.47/index.html
Envía 2000 peticiones HTTP sobre la URI ''estática'', manteniendo, respectivamente, 10 y 50 conexiones concurrentes. (aprox 1-2 minutos)
sleep.php) que introduce un retardo mediante un bucle ''activo'' de 20000 iteraciones
que busca forzar el uso de CPU con cálculos de hashes SHA1 y concatenaciones de cadenas.
/var/www/sleep.php
Pruebas a realizar:
cliente:~# ab -n 250 -c 10 http://193.147.87.47/sleep.php cliente:~# ab -n 250 -c 30 http://193.147.87.47/sleep.phpEnvía 250 peticiones HTTP sobre la URI ''dinámica'', manteniendo, respectivamente, 10 y 30 conexiones concurrentes. (aprox 5-7 minutos)
En cada ejecución del comando ab se muestran las estadísticas optenidas. Para el tipo de prueba informal, basta prestar atención a los parámetros Requests per second (num. peticiones por segundo) ó
Time per request (tiempo en milisegundos para procesar cada petición).
iptables (HAproxy se encargará de retransmitir ese tráfico
sin necesidad de redireccionar los puertos)
balanceador:~# iptables -t nat -F balanceador:~# iptables -t nat -Z
apache1:~# /etc/init.d/apache2 start apache2:~# /etc/init.d/apache2 start
whezee-backports
(repositorio adicional con versiones recientes de paquetes incluidos en la versión estable o paquetes adicionales no incluidos)
/etc/apt/sources.list
deb http://ftp.es.debian.org/debian wheezy-backports main
balanceador:~# apt-get update
balanceador:~# apt-get install haproxy
balanceador:~# cd /etc/haproxy
balanceador:/etc/haproxy/# mv haproxy.cfg haproxy.cfg.original
balanceador:/etc/haproxy/# nano haproxy.cfg
Contenido a incluir:
global
daemon
maxconn 256
user haproxy
group haproxy
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
mode http
log global
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen granja_cda
bind 193.147.87.47:80
mode http
stats enable
stats auth cda:cda
balance roundrobin
server uno 10.10.10.11:80 maxconn 128
server dos 10.10.10.22:80 maxconn 128
Define (en la sección listen) un ''proxy inverso'' de nombre granja_cda que:
http (la otra alternativa es el modo tcp, pero no analiza
las peticiones/respuestas HTTP, sólo retransmite paquetes TCP)
80 de la dirección 193.147.87.47
round-robin
uno y dos) en el puerto 80 de las direcciones 10.10.10.11
y 10.10.10.22
cda:cda
Más detalles en Opciones de configuración HAPproxy 1.5
Antes de hacerlo es necesario habilitar en /etc/default/haproxy el arranque de HAproxy desde los scripts de inicio, estableciendo la
variable ENABLED=1
balanceador:/etc/haproxy/# nano /etc/default/haproxy
...
ENABLED=1
balanceador:/etc/haproxy/# /etc/init.d/haproxy stop # ya estaba arrancado
balanceador:/etc/haproxy/# /etc/init.d/haproxy start
-d y -V habilitan los mensajes de DEBUG)
balanceador:/etc/haproxy/# haproxy -d -V -f /etc/haproxy/haproxy.cfg
Nota: Si no se ha deshabilitado la opción KeepAlive de Apache, es necesario esperar 5 segundos entre las recargas para que se agote el tiempo de espera para cerrar completamente la conexión HTTP y que pase a ser atendida por otro servidor.
ab
Pruebas a realizar:
cliente:~# ab -n 2000 -c 10 http://193.147.87.47/index.html cliente:~# ab -n 2000 -c 50 http://193.147.87.47/index.html cliente:~# ab -n 250 -c 10 http://193.147.87.47/sleep.php cliente:~# ab -n 250 -c 30 http://193.147.87.47/sleep.php
Los resultados deberían de ser mejores que con la prueba anterior con un servidor Apache único (al menos en el caso del script sleep.php)
cda)
apacheN:~# tail /var/log/apache2/error.log apacheN:~# tail /var/log/apache2/access.log
En todos los casos debería figurar como única dirección IP cliente la IP interna de la máquina balanceador [10.10.10.1]. ¿Por qué?
balanceador:/etc/haproxy/# /etc/init.d/haproxy stop
balanceador:~# nano /etc/haproxy/haproxy.cfg
Contenido a incluir: (añadidos marcados con <- aqui)
global
daemon
maxconn 256
user haproxy
group haproxy
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
mode http
log global
timeout connect 10000ms
timeout client 50000ms
timeout server 50000ms
listen granja_cda
bind 193.147.87.47:80
mode http
stats enable
stats auth cda:cda
balance roundrobin
cookie PHPSESSID prefix # <- aqui
server uno 10.10.10.11:80 cookie EL_UNO maxconn 128 # <- aqui
server dos 10.10.10.22:80 cookie EL_DOS maxconn 128 # <- aqui
El parámetro cookie especifica el nombre de la cookie que se usa como identificador único de la sesión del cliente
(en el caso de aplicaciones web PHP se suele utilizar por defecto el nombre PHPSESSID)
Para cada ''servidor real'' se especifica una etiqueta identificativa exclusiva mediante el parámetro cookie
Con esa información HAproxy reescribirá las cabeceras HTTP de peticiones y respuestas para seguir la pista
de las sesiones establecidas en cada ''servidor real'' usando el nombre de cookie especificado (PHPSESSID)
cliente -> balanceador HAproxy : cookie original + etiqueta de servidor
balanceador HAproxy -> servidor : cookie original
balanceador:/etc/haproxy/# /etc/init.d/haproxy start
whireshark y ponerlo en escucha sobre
el interfaz eth0 (fijar como filtro la cadena http para que solo muestre las peticiones
y respuestas HTTP)
cliente:~# wireshark &
http://193.147.87.47/sesion.php
(comprobar el incremento del contador [variable de sesión])
lynx
(o desde una pestaña de ''incógnito'' de Iceweasel para forzar la creación
de una nueva sesión)
cliente:~# lynx -accept-all-cookies http://193.147.87.47/sesion.php
wireshark y comprobar las peticiones/respuestas HTTP capturadas
Verificar la estructura y valores de las cookies PHPSESSID intercambiadas
SetCookie en la cabecera de la respuesta
Cookie en la cabecera de las peticiones)
http://193.147.87.47/index.html realizadas en la Tarea 2
una vez que está configurado y en uso el balanceador HAProxy.
Entrega: FAITIC
Fecha límite: hasta el viernes 18/12/2015