Cluster de Alta Disponibilidad de Servidores PostgreSQL con DRBD y Heartbeat

alfredo publicó esto el 01/10/09 en Bases de Datos, Herramientas. 3 comentarios

En este post vamos a ver cómo armar un cluster de alta disponibilidad de servidores PostgreSQL, con DRBD y Heartbeat.

Como en IPCorp nos gusta dormir tranquilos toda la solución va a estar soportada por GNU/Linux y en este ejemplo utilizaremos Ubuntu Server 9.04.

Requisitos

Se necesitan dos servidores o máquinas de similares características. En ambas es necesario tener una partición sin montar y sin formatear para el DRBD.

La capacidad de almacenamiento reservado en estas particiones permitirá almacenar como máximo la capacidad de la partición más chica.

Para el propósito de este instructivo denominaremos a los servidores: server1 y server2. Ambos equipos necesitan ser capaces de resolver los hostnames entre ellos, así que se debemos tener configurado algún servidor de DNS o agregar los nombres de hosts y sus IPs directamente en /etc/hosts. Ambos servidores deberían tener direcciones IP estáticas.

Vamos a suponer que cada servidor tiene un disco de 320Gb de los cuales particionaremos sin LVM, dejando un espacio libre para el volúmen compartido a través de la red. Esto depende del cálculo del tamaño estimado de la base de datos que vamos a replicar.

Hostname Dirección IP Partición para DRBD
server1 10.0.0.2 /dev/sda3
server2 10.0.0.3 /dev/sda3

Los clientes de la base de datos se comunicarán a la IP Virtual 10.0.0.1, además vamos a necesitar los siguientes paquetes instalados, necesarios para poder configurar correctamente el servidor:

sudo aptitude install hearbeat drbd8-utils build-essential libreadline5-dev zlib1g-dev

Configuración de DRBD

Primero vamos a guardar una copia del archivo de configuración original:

mv /etc/drbd.conf /etc/drbd_backup.conf

Editamos el archivo /etc/drbd.conf y reemplazamos su contenido por:

global {usage-count no;}
common { syncer {rate 100M;} }
resource pg {
        protocol C;
        startup {
                wfc-timeout 15;
                degr-wfc-timeout 60;
        }
        on server1 {
                device /dev/drbd0;
                disk /dev/sda3;
                address 10.0.0.2:7788;
                meta-disk internal;
        }
        on server2 {
                device /dev/drbd0;
                disk /dev/sda3;
                address 10.0.0.3:7788;
                meta-disk internal;
        }
}

Ahora copiamos este archivo en el servidor secundario e iniciamos el servicio en ambas máquinas. Posteriormente creamos el recurso compartido en ambas máquinas:

sudo /etc/init.d/drbd start
sudo drbdadm create-md pg

Dónde “pg” es el mismo nombre que le pusimos al tag “resource” en el archivo de configuración del “drbd”.

Ahora es necesario establecer el nodo primario del cluster. Para este ejemplo elegimos el server1 por lo que en ésta máquina ejecutamos el siguiente comando y luego damos formato a la partición compartida:

sudo drbdadm -- --overwrite-data-of-peer primary all
sudo mke2fs -j /dev/drbd0

Con el siguiente comando podemos ver el estado actual de la sincronización de los recursos del cluster:

cat /proc/drbd

Si todo salió bien, vamos a ver algo parecido a esto:

version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r---
    ns:82020 nr:1188 dw:82916 dr:5438 al:27 bm:18 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

Instalación de la base de datos PostgreSQL

La instalación de PostgreSQL será a través de la compilación del código fuente porque debemos hacer algunas modificaciones al programa pg_ctl para que todo funcione correctamente.

Luego de bajar los fuentes del PostgreSQL descomprimimos, y modificamos el código de la aplicación pg_ctl, más precisamente buscamos la leyenda “no server runnig” dentro del código y reemplazamos la palabra “runnig” por cualquier otra.

Esto tiene una explicación y es que Heartbeat verifica si un servicio está corriendo o no buscando la cadena “running” u “ok” al pedir su status, entonces cuando heartbeat le pregunta a PostgreSQL si está ejecutándose correctamente él responde “no server running” y heartbeat supone que todo está bien aunque realmente no sea así.

El archivo fuente de esta aplicación esta en postgresql-8.X.XX/src/bin/pg_ctl/ y se llama pg_ctl.c.

Un vez hecho este pequeño parche sólo nos falta compilarlo e instalarlo:

cd postgresql-8.X.XX
./configure
make
make install

Siguiendo el procedimiento regular de instalación, el próximo paso necesario es crear el usuario postgres. Agregamos la ruta /usr/local/pgsql/bin al path del sistema, y debemos crear la carpeta donde se van a alojar los datos y darle los permisos de esa carpeta al usuario postgres:

adduser postgres

Todos los pasos anteriores debemos hacerlo en ambos nodos, los que siguen sólo en el nodo principal:

mkdir /opt/postgresql/data
chown postgres.postgres -R /opt/postgresql/data

La ruta “/opt/postgresql/data” es el lugar donde quiero alojar los datos y queda a criterio de cada uno. Para inicializar la base de datos es necesario estar logueado como el usuario postgres y hacer:

initdb -D /opt/postgresql/data

Configuración de Heartbeat

En el nodo primario copiamos los archivos de configuración de ejemplo o simplemente creamos archivos nuevos:

cp /usr/share/doc/heartbeat/authkeys /etc/ha.d/
cp /usr/share/doc/heartbeat/ha.cf.gz /etc/ha.d/
cp /usr/share/doc/heartbeat/haresources.gz /etc/ha.d/
gzip -d ha.cf.gz
gzip -d haresources.gz

Editamos el archivo authkeys y ponemos:

auth 2
2 sha1 mipasswordsecreta

“mipasswordsecreta” es la password para que los nodos se puedan comunicar con cierto nivel de seguridad. Ahora es necesario darle permisos sólo a root por cuestiones de seguridad:

chmod 600 /etc/ha.d/authkeys

y en el archivo ha.cf comentamos todo y agregamos:

logfile /var/log/ha-log
logfacility local0
keepalive 2 #cada cuanto segundos verifica que este vivo
deadtime 30 #cuantos segundos espera hasta que lo considera muerto
initdead 120 # este valor es para cuando no bootean los dos juntos, en ese caso espera 120 segundos para empezar el proceso
bcast eth0 # placa de red por la que verifica el estado de los otros nodos
udpport 694 # puerto UDP por el que se va a enviar el latido
auto_failback on
node server1 # nodo que participa
node server2 # nodo que participa

y por último debemos modificar el archivo haresources. Ahí declaramos los servicios que queremos monitorear y que deben estar siempre disponibles. El equipo server1 es el servidor principal y los otros van a verificar que no caiga. En cuanto caiga una máquina, la otra tomará el control levantando los servicios monitoreados y tomando la IP Virtual. Dentro de haresources ingresamos:

server1 IPaddr::10.0.0.1 drbddisk::pg Filesystem::/dev/drbd0::/opt/postgresql::ext3::defaults postgresql

Les voy a explicar que significa cada parte de este archivo. En primer lugar definimos cuál va a ser el nodo principal en este caso server1. IPaddr::10.0.0.1 es el script que asigna la IP virtual que tendrá el cluster y el cual será el punto de acceso, con drbddisk::pg le decimos que recurso DRBD queremos brindar, luego con Filesystem::/dev/drbd0::/opt/postgresql::ext3::defaults montamos el dispositivo virtual drbd0 en la carpeta /opt/postgresql y por último decimos que arranque postgresql.

En indispensable copiar el archivo de arranque de PostgreSQL a /etc/ha.d/resources.d y modificar la variable de entorno PGDATA para que apunte a la carpeta /opt/postgresql/data que es el lugar donde van a residir las bases de datos:

cp postgresql-8.x.xx/contrib/start-scripts/linux /etc/ha.d/resources.d/postgresql
chmod +x /etc/ha.d/resources.d/postgresql

Luego copiamos los archivos de configuración a todos los nodos:

scp -r /etc/ha.d/ root@server2:/etc/

Ahora es cuestión de levantar los servicios en todos los nodos:

sudo /etc/init.d/heartbeat start

Comprobación

Ya estamos en condiciones de levantar el motor de base de datos mediante la siguiente sentencia:

/etc/ha.d/resources.d/postgresql start

Y sólo resta crear la base de datos y restaurar desde un backup anterior o empezar a crear las tablas, índices, vistas, etc., desde cero.

Luego para probar que se estén replicando correctamente los datos, en el nodo secundario ejecutamos el comando “watch cat /proc/drbd” mientras que en el nodo principal bajamos el servicio de hearbeat. Antes de bajar el servicio en el nodo secundario deberíamos tener la siguiente salida:

version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r---
    ns:1188 nr:82020 dw:83208 dr:3313 al:15 bm:17 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

Luego bajamos a heartbeat:

/etc/init.d/hearbeat stop

Y deberíamos ver lo siguiente:

version: 8.3.0 (api:88/proto:86-89)
GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829 build by ivoks@ubuntu, 2009-01-17 07:49:56
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r---
    ns:1328 nr:82280 dw:83608 dr:3542 al:15 bm:17 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

El agregado de nuevos nodos al cluster diría que es casi trivial.


3 comentarios

Trackbacks and Pingbacks


Dejá un comentario

Imagen CAPTCHA CAPTCHA Audio
Refrescar imagen