Apr 21, 2009

Balanceo de carga con LVS (III)

Para finalizar la parte del balanceo de carga con LVS, correspondiente al conjunto de artículos que venimos desarrollando sobre la implementación de un Sistema de Alta Disponibilidad y Balanceo de Carga, vamos a exponer los comandos que nos permitirán monitorizar el estado de las conexiones del cluster.

En primer lugar vamos a listar la lista de servicios configurados y los servidores reales y virtuales que atenderán dichas peticiones. Para ello emplearemos la orden ipvsadm con las opciones -l (listar los servicios) y -n (no resolver los nombres de dominio).
root@ha1:~# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.20:21 lc persistent 600
-> 10.0.0.13:21 Masq 1 0 0
-> 10.0.0.12:21 Masq 1 0 0
TCP 192.168.1.20:80 lc
-> 10.0.0.12:80 Masq 1 0 0
-> 10.0.0.13:80 Masq 1 0 0
TCP 192.168.1.20:3306 lc
-> 10.0.0.13:3306 Masq 1 0 0
-> 10.0.0.12:3306 Masq 1 0 0
En el ejemplo anterior puede observarse que se han definido tres servicios, FTP, HTTP y MySQL, los cuales serán balanceados hacia los nodos traseros (10.0.0.12 y 10.0.0.13) a través de un algoritmo lc (Least Connection).

Vamos a hacer la prueba de abrir tres sesiones HTTP desde un PC cliente con dirección IP 192.168.1.150. Si en ese momento volvemos a ejecutar el mismo comando, podremos ver el estado de dichas conexiones.
root@ha1:~# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.20:21 lc persistent 600
-> 10.0.0.13:21 Masq 1 0 0
-> 10.0.0.12:21 Masq 1 0 0
TCP 192.168.1.20:80 lc
-> 10.0.0.12:80 Masq 1 2 0
-> 10.0.0.13:80 Masq 1 1 0
TCP 192.168.1.20:3306 lc
-> 10.0.0.13:3306 Masq 1 0 0
-> 10.0.0.12:3306 Masq 1 0 0
Como puede observarse en la salida anterior, se han balanceado un par de conexiones HTTP hacia el nodo 10.0.0.12 y otra hacia el nodo 10.0.0.13.

Otra forma de obtener más información acerca del estado de las conexiones que atraviesan el cluster es a través de la opción -c. Cada una de las conexiones balanceadas por el LVS será reflejada a través de una entrada en la tabla de sesiones hash.
root@ha1:~# ipvsadm -lnc
IPVS connection entries
pro expire state source virtual destination
TCP 14:46 ESTABLISHED 192.168.1.150:4330 192.168.1.20:80 10.0.0.13:80
TCP 14:36 ESTABLISHED 192.168.1.150:4329 192.168.1.20:80 10.0.0.12:80
TCP 14:56 ESTABLISHED 192.168.1.150:4331 192.168.1.20:80 10.0.0.12:80
El primer campo indica el protocolo del servicio. El segundo el tiempo que la regla permanecerá en la tabla. El tercer campo el estado de la conexión (establecida, finalizada, en espera, ...). Y los últimos tres campos, la dirección IP origen (cliente), la dirección IP del servidor virtual que atenderá la conexión y la dirección IP del servidor real al que será balanceada la conexión.

Debido a que se inició el demonio de sincronización en ambos nodos frontales (ver el artículo anterior), ambas máquinas tendrán replicada la misma tabla de conexiones. Por lo tanto si ejecutamos el mismo comando en el nodo HA2, obtendremos el siguiente resultado:
root@ha2:~# ipvsadm -lnc
IPVS connection entries
pro expire state source virtual destination
TCP 13:14 ESTABLISHED 192.168.1.150:4330 192.168.1.20:80 10.0.0.13:80
TCP 13:24 ESTABLISHED 192.168.1.150:4331 192.168.1.20:80 10.0.0.12:80
TCP 13:04 ESTABLISHED 192.168.1.150:4329 192.168.1.20:80 10.0.0.12:80
Visualizando el contenido de los ficheros /proc/net/ip_vs* podremos obtener información adicional sobre el sistema de balanceo, como por ejemplo datos estadísticos sobre las conexiones balanceadas.

Apr 14, 2009

Eliminar los kernels antiguos del gestor de arranque

A medida que vamos actualizando nuestro sistema Linux, también hay veces en las que se actualiza la pieza más importante de todo ese engranaje: el kernel.

Se podría definir al kernel de Linux, también conocido como núcleo, como aquella capa de abstracción entre el hardware y el software a nivel de usuario. O dicho de otra forma, es la parte encargada de proveer el soporte necesario para acceder, gestionar e interactuar con los distintos componentes físicos del sistema.

El kernel por sí solo no puede proveer toda la funcionalidad existente. De hecho estamos ante un software cuyo tamaño es muy pequeño (en comparación con la mayoría de los programas actuales). Por ese motivo lo que se hace es incluir en el núcleo todas aquellas características básicas o primordiales, y a su vez, el propio kernel será el encargado de iniciar el resto de funciones principales durante el arranque. Este conjunto de funcionalidades adicionales irán encapsuladas en lo que se conoce como módulos del sistema (por ejemplo soporte para montar un RAID, tarjeta inalámbrica, etc).

Cada vez que se actualiza el kernel, se genera una nueva entrada en el gestor de arranque, pasando esta última a ser la configuración activa. El resto de kernels son mantenidos por defecto tanto en el disco duro como en el gestor de arranque. Esto puede conllevar a que en nuestro GRUB (un típico gestor de arranque) vaya creciendo cada vez más la lista de kernels disponibles para arrancar el sistema.

Lo habitual va a ser tener un par de kernels: el más actual y la versión anterior (por si ocurre algún problema con el actual). El resto no nos sirven para nada, ocupan espacio en disco y ofuscan la lista del GRUB.

Para eliminar los kernels que no nos sirven, primero tenemos que conocer cuál es nuestro kernel actual (el que está en uso). Para ello ejecutaremos el siguiente comando:

~# uname -a
Linux javi-desktop 2.6.27-11-generic #1 SMP Thu Jan 29 19:24:39 UTC 2009 i686 GNU/Linux


A continuación listaremos todos los kernels instalados en el sistema:

~# aptitude search ~ilinux-image
i linux-image-2.6.27-11-generic - Linux kernel image for version 2.6.27 on x86/x86_64
i linux-image-2.6.27-7-generic - Linux kernel image for version 2.6.27 on x86/x86_64
i linux-image-2.6.27-9-generic - Linux kernel image for version 2.6.27 on x86/x86_64
i linux-image-generic - Imagen genérica del núcleo Linux

Y por último, eliminaremos los núcleos antiguos. Esta última orden también eliminará las entradas en el gestor de arranque.

~# aptitude purge linux-image-2.6.27-7-generic

NOTA: las pruebas se han realizado sobre un sistema operativo Kubuntu.

Apr 8, 2009

Balanceo de carga con LVS (II)

Una vez expuesta la teoría acerca del balanceo de carga con LVS, vamos a continuar desarrollando las configuraciones que nos permitirán implementar esta funcionalidad en el Sistema de Alta Disponibilidad y Balanceo de Carga que estamos desarrollando.

Para monitorizar y controlar los servidores reales del cluster LVS, así como para llevar a cabo la administración de las tablas de forwarding del kernel, emplearemos el demonio ldirectord, el cual será arrancado y detenido cuando sea necesario por Hearbeat.

Ldirectord comprobará el estado de los servidores reales (LB1 y LB2) en intervalos de tiempo predeterminados, con el objetivo de mantener actualizada la tabla de conexiones del servidor virtual (HA1 o HA2).

Ldirectord genera reglas ipvsadm para gestionar el cluster LVS. Si alguno de los nodos traseros deja de atender peticiones de alguno de los servicios configurados por el LVS, ldirectord creará una llamada a ipvsadm que hará que el balanceador deje de enviarle paquetes a dicho nodo y servicio que no responde.

Lo primero que vamos a hacer va a ser instalar el paquete ldirectord en los dos nodos frontales, HA1 y HA2.

~# aptitude install ldirectord

A continuación vamos a editar el fichero de configuración (/etc/ha.d/conf/ldirectord.cf) para establecer los servicios a controlar (Apache, MySQL y vsftpd). Dentro de cada uno de los servicios a monitorizar, indicaremos la dirección IP virtual que recibirá los paquetes (192.168.1.20) y las direcciones IP de los servidores reales a los cuales se les repartirá la carga (10.0.0.12 y 10.0.0.13). Este fichero será idéntico en ambos nodos frontales.

~# cat /etc/ha.d/conf/ldirectord.cf
# Tiempo máximo para comprobar el estado del servicio (segundos)
checktimeout=2

# Periodo de comprobación (segundos)
checkinterval=30

# Apache
virtual=192.168.1.20:80
real=10.0.0.12:80 masq
real=10.0.0.13:80 masq
service=http
protocol=tcp
scheduler=lc
checktype=negotiate
request="index.html"
receive="It works!"

# MySQL
virtual=192.168.1.20:3306
real=10.0.0.12:3306 masq
real=10.0.0.13:3306 masq
service=mysql
protocol=tcp
scheduler=lc
checktype=connect

# Vsftpd
virtual=192.168.1.20:21
real=10.0.0.12:21 masq
real=10.0.0.13:21 masq
service=ftp
protocol=tcp
persistent=600
scheduler=lc
checktype=connect
Como ha podido observarse, el fichero está formado por distintas secciones, una para cada tipo de servicio gestionado. Cada uno de estos bloques comienza por la dirección IP virtual del cluster por la que se atenderán las peticiones, y el puerto al que corresponde la clase de servicio especificado (virtual=X.X.X.X:Y). Es muy importante acordarse de tabular cada uno de los elementos que componen el bloque.

El primer elemento que aparece en cada una de las sección es la dirección o direcciones IP de los servidores reales, definidas a través de la etiqueta masq, mediante la cual estaremos indicando que se emplee un modelo LVS-NAT.

Otra de las etiquetas a destacar es la de scheduler, mediante la cual se señala el tipo de algoritmo a emplear de cara al balanceo de carga. En nuestro caso se va a emplear un Least Connection (lc), que lo que hace es asignar más trabajos a aquellos servidores que presentan menos carga de trabajo (para consultar el resto de algoritmos soportados se puede recurrir a la ayuda de ipvsadm).

También cabe mencionar el parámetro checktype, que cuando tenga el valor connect indicará a ldirectord que únicamente compruebe cada intervalo de tiempo definido (checkinterval) si el puerto está abierto (para ello enviará un paquete SYN al puerto configurado). Si dicho parámetro toma el valor negotiate, tendrá que negociar el estado de la conexión. Por ejemplo para el caso de HTTP, ldirectord solicitará a Apache la página web index.html (request) y comprobará su contenido (receive).

Para el caso del protocolo FTP configuraremos la opción de la persistencia. Debido a que este protocolo utiliza dos puertos (20 para datos y 21 para control), es necesario que todas las peticiones pertenecientes a una misma sesión vayan dirigidas siempre al mismo nodo (LB1 o LB2). De esta forma si por ejemplo una máquina con dirección IP 192.168.1.150 inicia una sesión FTP contra la dirección IP virtual 192.168.1.20, y este balanceador redirecciona la conexión hacia el nodo LB1, el resto de conexiones que tengan como origen la dirección IP 192.168.1.150 y servicio FTP, siempre irán al nodo LB1.

A través de la etiqueta persist=600 se configurará el tiempo de vida para dichas sesiones persistentes. Si no hay actividad durante ese periodo de tiempo, la sesión se considerará cerrada. Este parámetro también lo declarararíamos en caso de definir una sección para el protocolo HTTPS (tiene también el problema de la persistencia - ver el artículo anterior -).

Además, decir también que para el caso del protocolo FTP no es suficiente con declarar la etiqueta persist, también es necesario cargar un módulo (ip_vs_ftp) durante el arranque del sistema. Para ello incluiremos este módulo dentro del archivo /etc/modules (en ambos nodos frontales).

~# cat /etc/modules
...
ip_vs_ftp

Otro aspecto que hay que tener en cuenta es el de la sincronización de la tabla de conexiones. En un momento dado, el nodo activo puede tener abiertas varias conexiones HTTP. Todas estas conexiones serán almacenadas por ipvsadm en una tabla de estados (/proc/net/ip_vs_conn_sync). Para ello, el nodo activo enviará periódicamente mensajes multicast con los cambios de estado acaecidos en su tabla de conexiones. El balanceador pasivo recibirá estos mensajes e irá actualizando sus tablas

Si en un momento dado el nodo HA1 se cae y HA2 asume el papel de activo, este último tendrá registradas la mayoría de las conexiones establecidas contra el cluster, con lo que la mayor parte de las sesiones iniciadas podrán seguir accediendo a los mismos servicios que tenían abiertos con total normalidad.

Para realizar esta tarea, tendremos que arrancar el demonio de sincronización al inicio del sistema en ambos nodos, pero con la diferencia de que en el nodo configurado por defecto como activo tendrá el estado master, y en el pasivo, backup. Esta acción la ejecutaremos añadiendo la siguiente línea en el script de arranque /etc/rc.local.

root@ha1:~# cat /etc/rc.local
...
ipvsadm --start-daemon master
exit 0


root@ha2:~# cat /etc/rc.local
...
ipvsadm --start-daemon backup
exit 0


Y ya por último, si recordamos el archivo /etc/ha.d/haresources empleado por Hearbeat, podremos ver que este demonio era el encargado de detener e iniciar a ldirectord (estará arrancado en el nodo activo y parado en el pasivo).

~# cat /etc/ha.d/haresources
ha1 IPaddr2::192.168.1.20 IPaddr2::10.0.0.20 mysql-ndb-mgm ldirectord::ldirectord.cf LVSSyncDaemonSwap::master mon

Por este motivo será necesario que el proceso init no levante a ldirectord cuando arranque el sistema. Para ello, tendremos que ejecutar el siguiente comando en los dos nodos frontales.

~# update-rc.d -f ldirectord remove

Apr 3, 2009

Red Hat Certified Technician

La semana pasada me saqué la certificación RHCT (Red Hat Certified Technician) en las instalaciones que Red Hat tiene en Madrid.

La certificación la obtuve siguiendo el itinerario del curso RH300. Son cuatro días de clases intensivas y un quinto día dedicado a los exámenes. Mi número de certificado es el 605009365923602.

El temario es bastante interesante, ya que abarca el proceso de instalación y puesta en marcha de un sistema Red Hat Enterprise Linux, la secuencia de arranque (BIOS, gestor de arranque, kernel, init, runlevels, etc.), la creación de volúmenes lógicos y sistemas RAID, instalación de servicios (DHCP, DNS, NIS, HTTP, FTP, samba, NFS, SMTP, POP, IMAP, proxys, etc.), virtualización con XEN, securización de las máquinas y resolución de problemas:
  1. Gestión de paquetes.
  2. Inicialización del sistema y servicios del kernel.
  3. Servicios del sistema y seguridad.
  4. Administración del sistema de archivos.
  5. Administración de usuarios.
  6. Instalación y virtualización.
  7. Configuración de red.
  8. Seguridad de la red.
  9. Servicios de infraestructura de red.
  10. Servicios web.
  11. Servicios de archivos compartidos.
  12. Servicios de correo.
  13. Resolución de problemas.

Dentro de unas semanas intentaré sacarme la RHCE (Red Hat Certified Engineer).