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
- 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 etcdAgregue 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="" # dirección de su máquina
ETCD_LISTEN_CLIENT_URLS="" # dirección de su máquina
[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="" # dirección de su máquina
ETCD_INITIAL_CLUSTER="datanode1=" # 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="" # dirección de su máquina
Ejecute el comando
systemctl restart etcdPostgreSQL 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.ymlA 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: falseEl 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 postgresqlEspere 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.logTenga 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 , especialmente la parte relacionada con la herramienta patronictl, que proporciona un acceso conveniente para administrar tu clúster.
¡Felicidades!
Fuente: habr.com
