Construyendo un clúster PostgreSQL de alta disponibilidad usando Patroni, etcd, HAProxy

Dio la casualidad de que, al momento de resolver el problema, no tenía un grado suficiente de experiencia para desarrollar y ejecutar esta solución solo. Y luego comencé a buscar en Google.


No sé cuál es la trampa, pero por enésima vez me enfrento al hecho de que, incluso si haces todo paso a paso como en el tutorial, preparas el mismo ambiente que el autor, entonces nada funciona. No tengo idea de qué se trata, pero cuando me encontré con esto de nuevo, decidí, y escribiré mi tutorial cuando todo salga bien. Uno que definitivamente funcionará.


Guías en linea


Dio la casualidad de que Internet no sufre la falta de varias guías, tutoriales, paso a paso y similares. Dio la casualidad de que tenía la tarea de desarrollar una solución para la organización conveniente y la construcción de un clúster tolerante a errores de PostgreSQL, cuyos requisitos principales eran la replicación de transmisión desde el servidor maestro a todas las réplicas y la entrada automática de la reserva cuando el servidor maestro fallaba.


En esta etapa, se definió el conjunto de tecnologías utilizadas:


  • PostgreSQL como DBMS
  • Patroni como solución de agrupamiento
  • etcd como almacenamiento distribuido para Patroni
  • HAproxy para organizar un único punto de entrada para aplicaciones que usan la base de datos

Instalación


Su atención: la construcción de un clúster PostgreSQL de alta disponibilidad utilizando Patroni, etcd, HAProxy.


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


etcd


No recomiendo instalar etcd en las mismas máquinas donde se ubicarán patroni y postgresql, ya que la carga del disco es muy importante para etcd. Pero para fines de capacitación, haremos exactamente eso.
Instalar etc.


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

Agregue el contenido al archivo / etc / default / etcd

[miembro]


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


TODAS LAS DIRECCIONES IP DEBEN SER VÁLIDAS. La lista de pares, el cliente, etc. DEBE ESTABLECER EN LA DIRECCIÓN IP DEL HOST


ETCD_LISTEN_PEER_URLS = " http://192.168.0.143:2380 " # la dirección de su máquina
ETCD_LISTEN_CLIENT_URLS = " http://192.168.0.143:2379,http://127.0.0.1:2379 " # la 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 = "nuevo"
ETCD_INITIAL_CLUSTER_TOKEN = "etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS = " http://192.168.0.143:2379 " # dirección de su máquina


Ejecuta el comando


 systemctl restart etcd 

PostgreSQL 9.6 + patroni


Lo primero que debe hacer es instalar tres máquinas virtuales para instalar el software necesario en ellas. Después de instalar las máquinas, si sigue mi tutorial, puede ejecutar este script simple que (casi) hace todo por usted. Ejecutar como root.


Tenga en cuenta que el script utiliza PostgreSQL versión 9.6, esto se debe a los requisitos internos de nuestra empresa. La solución no se probó 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 /etc/patroni.yml recién creado, debe colocar los siguientes contenidos, por supuesto, cambiando las direcciones IP en todos los lugares a las direcciones que utiliza.
Presta atención a los comentarios en este yaml. Cambie las direcciones a las suyas en cada máquina del clúster.


/etc/patroni.yml
 scope: pgsql #       namespace: /cluster/ #       name: postgres1 #       restapi: listen: 192.168.0.143:8008 #   ,      connect_address: 192.168.0.143:8008 #   ,      etcd: hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 #     ,      etcd    # this section (bootstrap) will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster # and all other cluster members will use it as a `global configuration` 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     ,    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 #   ,      connect_address: 192.168.0.143:5432 #   ,      data_dir: /data/patroni #    ,       bin_dir: /usr/lib/postgresql/9.6/bin #       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 las tres máquinas del clúster, de la misma forma que necesita colocar la configuración en el archivo /etc/patroni.yml en todas las máquinas.


Cuando realice 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 el resto de las 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 en la que se implementa HAproxy.


Para no hacer que la máquina HAproxy sea un punto único de falla, ejecútela en el contenedor Docker, luego será posible ejecutarla en el clúster del K8 y hacer que nuestro clúster de conmutación por error sea aún más confiable.


Cree un directorio donde pueda almacenar dos archivos: Dockerfile y haproxy.cfg. Ve a ello.


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, las últimas tres líneas del archivo haproxy.cfg deben enumerar las direcciones de sus máquinas. HAproxy se pondrá en contacto con Patroni, en los encabezados HTTP el servidor maestro siempre devolverá 200, y la 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 

Al estar en el directorio en el que se encuentran nuestros dos archivos, ejecutaremos secuencialmente los comandos de empaquetado del contenedor, así como su lanzamiento con el reenvío de puertos necesario:


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

Ahora, abriendo la dirección del navegador de su máquina con HAproxy y especificando el puerto 7000, verá estadísticas en su clúster.


En el estado ARRIBA, se ubicará el servidor que es el maestro y las réplicas en el estado ABAJO. Esto es normal, de hecho funcionan, pero se muestran de esta forma debido al hecho de que devuelven 503 a las solicitudes de HAproxy. Esto nos permite saber siempre cuál de los tres servidores es el maestro en este momento.


Conclusión


Eres increible! En solo 30 minutos, ha implementado un excelente clúster de base de datos productivo y a prueba de fallas con replicación de transmisión y aprovisionamiento automático. Si planea usar esta solución, consulte la documentación oficial de Patroni , y especialmente su parte con respecto a la utilidad patronictl, que proporciona un acceso conveniente para administrar su clúster.


Felicidades

Source: https://habr.com/ru/post/482314/


All Articles