Manual para agregar una IP VIP en Patroni para PostgreSQL en Alta Disponibilidad

Introducción

Este manual forma parte de nuestra serie de manuales dedicada a la Instalación y Configuración de PostgreSQL en Alta Disponibilidad (HA) utilizando Patroni y etcd. En este documento específico, explicaremos cómo añadir una IP VIP (Virtual IP) a un clúster de Patroni, lo que permitirá que una dirección IP flotante se asocie al nodo líder del clúster de PostgreSQL, mejorando la alta disponibilidad y la resiliencia del servicio.

En un entorno de alta disponibilidad, especialmente en soluciones de bases de datos como PostgreSQL, la capacidad de asegurar que la IP del nodo líder sea accesible desde los clientes es esencial. Usar una IP VIP en un sistema de alta disponibilidad permite que la IP asociada con el nodo activo cambie dinámicamente en caso de un failover, asegurando que los clientes siempre puedan conectarse al nodo que esté proporcionando el servicio.

Objetivo del Manual

El objetivo de este manual es guiarte a través de los pasos necesarios para configurar y administrar una IP VIP en un clúster de PostgreSQL gestionado por Patroni. Cubriremos la creación de un script para gestionar la asignación y eliminación de la VIP, así como la configuración de los permisos necesarios para que este script funcione correctamente. También se abordará cómo integrar este proceso con la configuración de PostgreSQL y Patroni, para que el failover funcione de manera transparente.

Requisitos Previos

Antes de comenzar, asegúrate de tener lo siguiente configurado:

  • Un clúster de PostgreSQL funcionando con Patroni y etcd.
  • Acceso administrativo al servidor donde se ejecuta el clúster.
  • Herramientas instaladas como curl, jq, ip, y bash.
  • Configuración básica de red que permita la asignación de IPs en las interfaces de red necesarias.

Si aún no has configurado Patroni con PostgreSQL, te recomendamos seguir el Manual de Instalación de PostgreSQL en Alta Disponibilidad con Patroni y etcd disponible en el siguiente enlace: Manual de Instalación de PostgreSQL en Alta Disponibilidad con Patroni y etcd.

Creación del Script para Gestionar la IP VIP

El primer paso en este proceso es crear un script que se ejecutará cada vez que el nodo cambie de rol (de líder a réplica y viceversa). Este script gestionará la asignación y eliminación de la IP VIP en el nodo correcto.

Crear el script VIP

En este paso, crearemos un script llamado vip.sh que será responsable de agregar o eliminar la IP VIP de la interfaz de red en función del rol del nodo en el clúster. Abre un editor de texto en el servidor de PostgreSQL y crea el archivo:

sudo vi /etc/patroni/vip.sh

Una vez en el editor, agrega el siguiente contenido al script:

#!/bin/bash

VIP="192.168.1.220"  
IFACE="eth0"

# Consultar el estado de Patroni en el nodo actual
ROLE=$(curl -s http://$(hostname):8008/patroni | jq -r .role)

# Función para verificar si la IP existe en la interfaz
check_ip_exists() {
    ip addr show dev $1 | grep -q "$2"
}

# Verificar si el nodo es el master
if [[ "$ROLE" == "master" ]]; then
    echo "$(date) - Este nodo es ahora el líder. Agregando VIP $VIP a $IFACE" >> /var/log/patroni_vip.log
    ip addr add $VIP/24 dev $IFACE || echo "Error al agregar la VIP" >> /var/log/patroni_vip.log
else
    # Verificar si la IP ya existe en la interfaz antes de eliminarla
    if check_ip_exists $IFACE $VIP; then
        echo "$(date) - Este nodo es ahora una réplica. Eliminando VIP $VIP de $IFACE" >> /var/log/patroni_vip.log
        ip addr del $VIP/24 dev $IFACE || echo "Error al eliminar la VIP" >> /var/log/patroni_vip.log
    else
        echo "$(date) - La VIP $VIP no está configurada en $IFACE. No se eliminará." >> /var/log/patroni_vip.log
    fi
fi

Este script realiza las siguientes acciones:

  1. Consulta el rol actual del nodo: Utiliza curl para obtener el estado de Patroni en el nodo, determinando si el nodo es el líder (master) o una réplica.
  2. Verifica y configura la IP VIP: Si el nodo es el líder, agrega la VIP a la interfaz configurada (eth0). Si el nodo es una réplica, elimina la VIP si está presente.

Configurar los permisos del script

Una vez que hayas creado el archivo, es necesario establecer los permisos correctos para asegurar que el script sea ejecutable y accesible para los usuarios adecuados. Esto lo logramos con los siguientes comandos:

sudo chown etcd:db-etcd /etc/patroni/vip.sh
sudo chmod +x /etc/patroni/vip.sh

Esto garantiza que el script sea propiedad de los usuarios etcd y db-etcd, y sea ejecutable por el sistema.

Configuración de los Logs

Para poder hacer un seguimiento de los cambios realizados por el script, vamos a crear un archivo de log. Este archivo registrará las acciones realizadas al agregar o eliminar la IP VIP en el sistema.

Crear el archivo de logs

Crea el archivo de log con los siguientes comandos:

sudo touch /var/log/patroni_vip.log
sudo chown etcd:db-etcd /var/log/patroni_vip.log
sudo chmod 775 /var/log/patroni_vip.log

Esto crea el archivo de log y establece los permisos necesarios para que el script pueda escribir en él.

Integración con Patroni

Una vez que el script está listo, necesitamos configurarlo dentro de Patroni para que se ejecute automáticamente cuando el rol del nodo cambie. Esto se logra configurando el parámetro on_role_change en la sección de configuración de PostgreSQL en Patroni.

Paso 4: Modificar la configuración de Patroni

Abre el archivo de configuración de Patroni (/etc/patroni/patroni.yml) y añade la siguiente línea bajo la sección de callbacks:

callbacks: 
  on_role_change: "/etc/patroni/vip.sh"

Fichero de configuración completo

scope: keycloak-cluster
namespace: /service/
name: srvlropsql01

restapi:
  listen: 192.168.1.214:8008
  connect_address: 192.168.1.214:8008
  authentication:
    username: admin
    password: admin_password

etcd:
  hosts: 192.168.1.214:2379,192.168.1.215:2379,192.168.1.216:2379
  protocol: https
  cacert: /etc/etcd/etcd-ca.crt
  cert: /etc/etcd/server.crt
  key: /etc/etcd/server.key

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      callbacks: 
        on_role_change: "/etc/patroni/vip.sh"
      parameters:
        wal_level: replica
        hot_standby: "on"
        max_wal_senders: 10
        max_replication_slots: 10
        wal_keep_size: 256MB
  initdb:
    - encoding: UTF8
    - data-checksums
  users:
    replication:
      password: replicator_password
      options:
        - replication
    admin:
      password: admin_password
      options:
        - createrole
        - createdb
  post_init: 
    - createuser --superuser admin

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 192.168.1.214:5432
  data_dir: /var/lib/postgresql/15/main
  bin_dir: /usr/lib/postgresql/15/bin
  pgpass: /tmp/pgpass
  authentication:
    replication:
      username: replicator
      password: replicator_password
    superuser:
      username: postgres
      password: postgres_password
  parameters:
    archive_mode: "on"
    archive-command: 'pgbackrest --stanza=postgres archive-push %f'
    wal_level: replica
    max_wal_senders: 10
    max_replication_slots: 10
    wal_keep_size: 256MB
  pg_hba:
    - local all postgres trust
    - hostssl replication replicator 127.0.0.1/32 trust
    - hostssl replication replicator 192.168.1.215/32 trust
    - hostssl replication replicator 192.168.1.216/32 trust
    - hostssl replication replicator 192.168.1.214/32 trust
    - host replication replicator 127.0.0.1/32 trust
    - host replication replicator 192.168.1.215/32 trust
    - host replication replicator 192.168.1.216/32 trust
    - host replication replicator 192.168.1.214/32 trust
    - hostssl all all 192.168.1.0/24 trust
    - host all all 192.168.1.0/24 trust
    - hostssl all pgbackrest 192.168.1.0/24 trust
    - host all pgbackrest 192.168.1.0/24 trust
    - hostssl all all 0.0.0.0/0 md5
    - host all all 0.0.0.0/0 md5
tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false

Esto asegura que el script vip.sh se ejecute automáticamente cada vez que Patroni detecte un cambio de rol en el nodo.

Reiniciar Patroni

Con todo configurado, es necesario reiniciar el servicio de Patroni para aplicar los cambios:

Verificación de la Configuración

Para verificar que la IP VIP se ha asignado correctamente, puedes ejecutar el siguiente comando en el nodo líder (master):

ip a

Deberías ver la IP VIP (192.168.1.220) asociada con la interfaz eth0.

Output

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:8d:c0:4d brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 84152sec preferred_lft 84152sec
    inet 192.168.1.220/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe8d:c04d/64 scope link 
       valid_lft forever preferred_lft forever

Conclusión

Con este manual, hemos configurado un script en Patroni para gestionar una IP VIP en un clúster de PostgreSQL en alta disponibilidad. Este paso es crucial para garantizar que el clúster de PostgreSQL sea accesible incluso después de un failover, ya que la IP VIP siempre apunta al nodo que esté actuando como líder en todo momento. Esto mejora la disponibilidad y la resiliencia del servicio de bases de datos.

Este manual forma parte de nuestra serie más amplia sobre PostgreSQL en alta disponibilidad, y si deseas más detalles sobre la configuración de Patroni o la gestión de PostgreSQL, puedes consultar nuestros otros manuales.

:wq!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *