Construcción de un clúster de PostgreSQL de alta disponibilidad usando Patroni, etcd, HAProxy

Resulta que, en el momento de plantear la tarea, no tenía suficiente experiencia para desarrollar e implementar esta solución por mi cuenta. Así que empecé a buscar en Google.

No sé cuál es el problema, pero ya es la enésima vez que me encuentro con que, incluso si sigo todos los pasos como en el tutorial y preparo un entorno igual al del autor, todavía nunca funciona nada. No tengo idea de cuál es el asunto, pero cuando me encontré con esto una vez más, decidí que escribiría mi propio tutorial cuando todo funcione. Uno que sin duda funcionará.

Guías en Internet

Resulta que Internet no sufre de la falta de diversas guías, tutoriales, paso a paso y cosas por el estilo. Me fue encomendado desarrollar una solución para organizar y construir un clúster de PostgreSQL resistente a fallos, cuyas principales exigencias eran la replicación en streaming desde el servidor maestro a todas las réplicas y la conmutación automática en caso de fallo del servidor maestro.

En esta etapa se definió la pila de tecnologías utilizadas:

  • PostgreSQL como sistema de gestión de bases de datos
  • Patroni como solución para la agrupación
  • etcd como almacenamiento distribuido para Patroni
  • HAproxy para organizar un único punto de entrada para las aplicaciones que utilizan la base de datos

Instalación

A continuación, la construcción de un clúster de PostgreSQL de alta disponibilidad utilizando Patroni, etcd y HAProxy.

Todas las operaciones se realizaron en máquinas virtuales con el sistema operativo Debian 10 instalado.

etcd

No recomiendo instalar etcd en las mismas máquinas donde estarán Patroni y PostgreSQL, ya que para etcd es muy importante la carga en los discos. Pero con fines de aprendizaje, haremos precisamente eso.
Instalemos etcd.

#!/bin/bash
apt-get update
apt-get install etcd

Agregue el contenido al archivo /etc/default/etcd

[member]

ETCD_NAME=datanode1 # nombre del host de su máquina
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

TODAS LAS DIRECCIONES IP DEBEN SER VÁLIDAS. ESCUCHAR PEER, CLIENTE ETC DEBE ESTAR CONFIGURADO A LA DIRECCIÓN IP DEL HOST

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380" # dirección de su máquina
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379" # dirección de su máquina

[cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380" # dirección de su máquina
ETCD_INITIAL_CLUSTER="datanode1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380" # direcciones de todas las máquinas en el clúster etcd
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379" # dirección de su máquina

Ejecute el comando

systemctl restart etcd

PostgreSQL 9.6 + patroni

Lo primero que hay que hacer es instalar tres máquinas virtuales para cargar el software necesario. Después de instalar las máquinas, si sigues mi tutorial, puedes ejecutar este simple script que (casi) lo hará todo por ti. Se ejecuta con privilegios de root.

Ten en cuenta que el script utiliza la versión 9.6 de PostgreSQL, esto se debe a los requisitos internos de nuestra empresa. La solución no ha sido probada en otras versiones de PostgreSQL.

#!/bin/bash
apt-get install gnupg -y
echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" >> /etc/apt/sources.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt-get update
apt-get install postgresql-9.6 python3-pip python3-dev libpq-dev -y
systemctl stop postgresql
pip3 install --upgrade pip
pip install psycopg2
pip install patroni[etcd]
echo "
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target

[Service]
Type=simple

User=postgres
Group=postgres

ExecStart=/usr/local/bin/patroni /etc/patroni.yml

KillMode=process

TimeoutSec=30

Restart=no

[Install]
WantedBy=multi-user.targ
" > /etc/systemd/system/patroni.service
mkdir -p /data/patroni
chown postgres:postgres /data/patroni
chmod 700 /data/patroniпо
touch /etc/patroni.yml

A continuación, en el archivo recién creado /etc/patroni.yml debes colocar el siguiente contenido, por supuesto, modificando las direcciones IP en todos los lugares a las que tú uses.
Presta atención a los comentarios en este archivo yaml. Cambia las direcciones por las tuyas, en cada máquina del clúster.

/etc/patroni.yml

scope: pgsql # debe ser el mismo en todos los nodos
namespace: /cluster/ # debe ser el mismo en todos los nodos
name: postgres1 # debe ser diferente en todos los nodos

restapi:
    listen: 192.168.0.143:8008 # dirección del nodo donde se encuentra este archivo
    connect_address: 192.168.0.143:8008 # dirección del nodo donde se encuentra este archivo

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # enumere aquí todos sus nodos, en caso de que instale etcd en ellos

# esta sección (bootstrap) se escribirá en Etcd:///config después de inicializar un nuevo clúster
# y todos los demás miembros del clúster lo utilizarán como una `configuración global`
bootstrap:
    dcs:
        ttl: 100
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
            use_pg_rewind: true
            use_slots: true
            parameters:
                    wal_level: replica
                    hot_standby: "on"
                    wal_keep_segments: 5120
                    max_wal_senders: 5
                    max_replication_slots: 5
                    checkpoint_timeout: 30

    initdb:
    - encoding: UTF8
    - data-checksums
    - locale: en_US.UTF8
    # init pg_hba.conf debe contener direcciones de TODAS las máquinas utilizadas en el clúster
    pg_hba:
    - host replication postgres ::1/128 md5
    - host replication postgres 127.0.0.1/8 md5
    - host replication postgres 192.168.0.143/24 md5
    - host replication postgres 192.168.0.144/24 md5
    - host replication postgres 192.168.0.145/24 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 192.168.0.143:5432 # dirección del nodo donde se encuentra este archivo
    connect_address: 192.168.0.143:5432 # dirección del nodo donde se encuentra este archivo
    data_dir: /data/patroni # este directorio será creado por el script descrito arriba y se establecerán los permisos necesarios
    bin_dir:  /usr/lib/postgresql/9.6/bin # indique la ruta a su directorio con postgresql
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: postgres
            password: postgres
        superuser:
            username: postgres
            password: postgres
    create_replica_methods:
        basebackup:
            checkpoint: 'fast'
    parameters:
        unix_socket_directories: '.'

tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

El script debe ejecutarse en todas las tres máquinas del clúster, y también es necesario colocar la configuración proporcionada en el archivo /etc/patroni.yml en todas las máquinas.

Cuando haya realizado estas operaciones en todas las máquinas del clúster, ejecute el siguiente comando en cualquiera de ellas.

systemctl start patroni
systemctl start postgresql

Espere unos 30 segundos, luego ejecute este comando en las demás máquinas del clúster.

HAproxy

Utilizamos el maravilloso HAproxy para proporcionar un único punto de entrada. El servidor maestro siempre estará disponible en la dirección de la máquina donde se desplegó HAproxy.

Para evitar que la máquina con HAproxy se convierta en un único punto de fallo, lo ejecutaremos en un contenedor Docker; más adelante, se podrá implementar en un clúster K8's y hacer que nuestro clúster tolerante a fallos sea aún más confiable.

Cree un directorio donde pueda almacenar dos archivos: Dockerfile y haproxy.cfg. Navegue a él.

Dockerfile

FROM ubuntu:latest

RUN apt-get update 
    && apt-get install -y haproxy rsyslog 
    && rm -rf /var/lib/apt/lists/*

RUN mkdir /run/haproxy

COPY haproxy.cfg /etc/haproxy/haproxy.cfg

CMD haproxy -f /etc/haproxy/haproxy.cfg && tail -F /var/log/haproxy.log

Tenga cuidado, en las tres últimas líneas del archivo haproxy.cfg deben estar listadas las direcciones de sus máquinas. HAproxy se conectará a Patroni, en los encabezados HTTP el servidor maestro siempre devolverá 200, mientras que el réplica devolverá 503.

haproxy.cfg

global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen postgres
    bind *:5000
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server postgresql1 192.168.0.143:5432 maxconn 100 check port 8008
    server postgresql2 192.168.0.144:5432 maxconn 100 check port 8008
    server postgresql3 192.168.0.145:5432 maxconn 100 check port 8008

Estando en el directorio donde se encuentran nuestros dos archivos, ejecutaremos secuencialmente los comandos para empaquetar el contenedor y luego iniciar su ejecución con el reenvío de los puertos necesarios:

docker build -t my-haproxy .
docker run -d -p5000:5000 -p7000:7000 my-haproxy 

Ahora, al abrir en su navegador la dirección de su máquina con HAproxy y especificar el puerto 7000, podrá ver las estadísticas de su clúster.

El servidor que esté en estado UP será el maestro, mientras que las réplicas estarán en estado DOWN. Esto es normal; de hecho, están funcionando, pero se muestran de esta manera porque devuelven 503 a las solicitudes de HAproxy. Esto nos permite saber con certeza cuál de los tres servidores es el maestro en este momento.

Conclusión

¡Eres increíble! En solo 30 minutos has desplegado un excelente clúster de bases de datos tolerante a fallos y de alto rendimiento con replicación en flujo y con un conmutador automático. Si planeas usar esta solución, consulta la documentación oficial de Patroni, especialmente la parte relacionada con la herramienta patronictl, que proporciona un acceso conveniente para administrar tu clúster.

¡Felicidades!

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster