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