Clúster con failover automático con Patroni + etcd + HAProxy
PostgreSQLNivel: AvanzadoDuración: 2–3 horasInstala y opera un clúster PostgreSQL con failover automático: en cada nodo Patroni gestiona PostgreSQL, la elección del leader se realiza en un etcd de 3 (o 5) miembros y las aplicaciones se conectan a los puertos de escritura (5000) y lectura (5001) de HAProxy, opcionalmente a través de una VIP de keepalived. Además de la instalación, incluye escenarios de operación para un clúster ya instalado: comprobación de estado, switchover, reincorporación del antiguo leader, reinit, alta/baja de nodos, edit-config, pause, actualización de Patroni, parada/arranque completos, sustitución de miembros de etcd y pérdida de la mayoría de etcd. La guía pg-install no se usa en los nodos Patroni (Patroni ejecuta initdb por sí mismo); para una HA sin Patroni, con failover manual, use la guía pg-streaming.
Topología: 3 nodos PostgreSQL + etcd (compartidos o separados) + HAProxy (+ VIP)
Escenarios
- Instalación: nuevo clúster Patroni — Se instala desde cero un clúster etcd + Patroni + HAProxy (+ VIP). En los servidores no debe existir ningún clúster PostgreSQL: initdb lo ejecuta Patroni (no se aplica pg-install).
- Runbook de operación: switchover, prueba de failover, modo de mantenimiento, cambio de parámetros — Prueba en orden las operaciones básicas en un clúster recién instalado: estado, switchover, prueba de failover (se detiene el leader, breve corte de escritura), modo de mantenimiento y cambio de parámetros. Aplíquelo en una ventana de mantenimiento.
- ¿Está sano el clúster? (comprobación de estado) — Solo lectura: roles, retardo, timeline, API REST, estado de etcd, slots, reinicios pendientes y modo de mantenimiento.
- Switchover planificado (pasar el leader a otro nodo) — Antes de un mantenimiento, el rol de leader pasa de forma controlada a una réplica; corte de escritura de unos segundos, sin pérdida de datos.
- Hubo failover y el antiguo leader no se reincorpora (pg_rewind / reinit) — El antiguo leader caído debe incorporarse como réplica al arrancar; si pg_rewind falla, el directorio de datos se reconstruye desde el leader.
- Reconstruir una réplica desde cero (reinit) — La réplica está dañada, muy retrasada o ha perdido WAL: se borra el directorio de datos y se reconstruye desde el leader (o desde un backup). El leader no se ve afectado.
- Añadir un nuevo nodo al clúster — Añada el nuevo nodo al final de la lista del formulario: se instala el software, se actualizan pg_hba y HAProxy en los nodos existentes y se incorpora como réplica.
- Quitar un nodo del clúster — Se retira de forma permanente un nodo réplica: se detiene Patroni, se limpian el registro en el DCS y el slot, y se elimina de HAProxy.
- Cambiar un parámetro de PostgreSQL o de Patroni (edit-config) — El parámetro se escribe en el DCS y se aplica en todos los nodos; para los que requieren reinicio, restart --pending (primero las réplicas).
- Detener el failover automático para mantenimiento (pause / resume) — En pause, Patroni no toca PostgreSQL ni hace failover; para mantenimiento de red/etcd o intervención manual. Al terminar, resume.
- Actualizar el software de Patroni (rolling) — El clúster se pone en pause y Patroni se actualiza y reinicia nodo a nodo; PostgreSQL no se detiene y no hay failover.
- Detener / arrancar todo el clúster (orden correcto) — Parada completa planificada (mantenimiento de almacenamiento o del centro de datos): primero las réplicas, después el leader y por último etcd; el arranque, en orden inverso.
- Sustituir o añadir un miembro de etcd (etcdctl member) — Se retira el miembro de etcd averiado y se añade un nuevo servidor (o se aumenta el número de miembros); se actualiza la lista de etcd de Patroni.
- Se perdió la mayoría de etcd: el leader pasó a solo lectura — Sin quorum de etcd, Patroni pone el leader en solo lectura y tampoco hay failover. Se recupera etcd o se reconstruye a partir de un único miembro.
Antes de empezar
- En los nodos PostgreSQL no hay ningún clúster PostgreSQL en ejecución ni creado previamente y … está vacío (Patroni crea el clúster por sí mismo). La guía pg-install no se ha aplicado en estos servidores.
- Todos los servidores tienen la misma versión del sistema operativo y están actualizados; los relojes están sincronizados por NTP (etcd y Patroni son sensibles a la deriva del reloj).
- RAM de … GB en los nodos PostgreSQL; … en un disco/LV aparte y del mismo tamaño en todos los nodos.
- Los datos de etcd (/var/lib/etcd) están en un disco de baja latencia (SSD). Un disco lento perturba la elección del leader; se recomienda que no comparta disco con datos de PostgreSQL con mucha E/S.
- Atención: el número de nodos etcd es … (par). Un número par no aumenta la tolerancia a fallos; use 3 o 5.
- Los servidores se alcanzan entre sí en estos puertos: PostgreSQL …, Patroni REST 8008, etcd 2379/2380, HAProxy 5000/5001/7000…, VRRP (protocolo IP 112)…. Estas reglas también están abiertas en los dispositivos de red intermedios.
- Los servidores pueden salir por HTTPS al repositorio PGDG (download.postgresql.org…, apt.postgresql.org…) y a github.com para etcd, o hay definido un mirror interno.
- La VIP … está libre (no la usa ningún servidor) y la red (virtualización/nube) permite VRRP y que la misma IP se mueva entre servidores. En entornos cloud normalmente no se permite; use en su lugar el load balancer de la nube.
- Atención: solo hay un servidor HAProxy para la VIP; si el servidor cae, la VIP no tiene adónde moverse.
- Privilegios de root o sudo en todos los servidores; ventana de mantenimiento y plan de vuelta atrás preparados.
- …: se puede instalar el mismo sistema operativo y la misma versión principal de PostgreSQL que en los demás nodos, tiene tanto disco para … como los demás nodos, el reloj está sincronizado por NTP y tiene acceso a …, 8008 y etcd 2379 de los demás nodos.
- … (…): disco de baja latencia (SSD), reloj sincronizado por NTP, acceso abierto a 2379/2380 de los demás miembros de etcd y a 2379 desde los nodos PostgreSQL; acceso a github.com o el archivo de etcd en /tmp.
Fases de la guía
- Preparación (todos los servidores) — Añadir los nombres de los servidores a /etc/hosts · Activar la sincronización horaria (chrony) · Parámetros del kernel y THP · Reglas de firewall (nodos PostgreSQL) · Reglas de firewall (servidores etcd) · Reglas de firewall (servidores HAProxy)
- Clúster etcd — Instalar el software de etcd · Instalar el software de etcd · Configuración de etcd: … · Crear el servicio systemd de etcd · Crear el servicio systemd de etcd · Arrancar etcd (a la vez en todos los nodos etcd) …
- Software de PostgreSQL y Patroni — Añadir el repositorio PGDG · Añadir el repositorio PGDG · Instalar PostgreSQL y Patroni · Desactivar el servicio independiente de PostgreSQL y preparar los directorios
- Configuración de Patroni — Escribir las contraseñas en el archivo de entorno · Vincular el archivo de entorno al servicio de Patroni · patroni.yml: … · Validar la configuración
- Arrancar el clúster — Arrancar Patroni en el primer nodo · Arrancar Patroni en los demás nodos: … · Comprobar el estado del clúster
- HAProxy — Instalar HAProxy · Instalar HAProxy · Escribir haproxy.cfg · Escribir haproxy.cfg · Validar y arrancar HAProxy · Validar y arrancar HAProxy
- VIP con keepalived — Instalar keepalived · Instalar keepalived · Configuración de keepalived: … · Arrancar keepalived · Arrancar keepalived
- Usuario de la aplicación y prueba de conexión — Usuario y base de datos de la aplicación · Asignar contraseña al usuario de la aplicación · Comprobar los endpoints de health check de la API REST · Probar la conexión a través de HAProxy · Cadena de conexión de la aplicación
- Después de la instalación — Hacer el backup por snapshot de etcd · Hacer el backup por snapshot de etcd · Configurar el backup (obligatorio) · Conectar la monitorización
- Estado del clúster — Miembros, roles y retardo
- Switchover planificado — Hacer el switchover
- Prueba de failover (detener el leader) — Detener Patroni en el nodo leader · Seguir al nuevo leader · Volver a arrancar el antiguo leader
- Modo de mantenimiento (pause) — Poner el clúster en modo de mantenimiento · Hacer el mantenimiento · Salir del modo de mantenimiento
- Cambio de parámetros — Cambiar el parámetro en todo el clúster · Aplicar los reinicios pendientes
- Comprobación de estado (solo lectura) — Miembros, roles, timeline y retardo · Últimos cambios de leader (history) · Endpoints de estado de la API REST · Estado de etcd · Retardo de replicación, slots y reinicios pendientes (en el leader) · Configuración y modo de mantenimiento
- Switchover planificado — Comprobación previa al switchover · Hacer el switchover · Verificar el nuevo leader y la reincorporación del antiguo
- Modo de mantenimiento (pause / resume) — Comprobación previa al pause · Poner el clúster en modo de mantenimiento (pause) · Hacer el mantenimiento · Salir del modo de mantenimiento (resume)
- Actualización de Patroni: preparación — Versión actual y versión destino de Patroni · Hacer copia de la configuración y validarla · Poner el clúster en modo de mantenimiento (pause)
- Actualización de Patroni: cierre — Salir del modo de mantenimiento (resume)
- Detener el clúster (réplica → leader → etcd) — Registrar el estado y los roles · Detener las aplicaciones · Detener Patroni en las réplicas · Detener Patroni en el leader · Detener etcd
- Arrancar el clúster (etcd → último leader → réplicas) — Arrancar etcd (a la vez en todos los miembros de etcd) · Verificar el estado de etcd · Arrancar primero Patroni en el último leader · Arrancar Patroni en las réplicas · Verificar el clúster y abrir las aplicaciones
- Diagnóstico: pérdida de la mayoría de etcd — Verificar los síntomas: no hay leader, PostgreSQL en solo lectura · Ver el estado de los miembros de etcd
- Vía A: recuperar los miembros de etcd — Vía A: arrancar los servicios de etcd · Verificar que Patroni se ha recuperado
- Verificación y prevención — Verificar etcd y Patroni y valorar failsafe