Création d'un cluster PostgreSQL haute disponibilité à l'aide de Patroni, etcd, HAProxy

Il se trouve que lorsque j'ai posé le problème, je n'avais pas suffisamment d'expérience pour développer et exécuter cette solution seul. Et puis j'ai commencé à googler.


Je ne sais pas quel est le problème, mais pour la énième fois, je suis confronté au fait que même si vous faites tout étape par étape comme dans le tutoriel, préparez le même environnement que celui de l'auteur, alors rien ne fonctionne jamais. Je ne sais pas de quoi il s'agit, mais quand je suis tombé à nouveau sur ce sujet, j'ai décidé - et j'écrirai mon tutoriel quand tout ira bien. Celui qui fonctionnera certainement.


Guides en ligne


Il se trouve que l'Internet ne souffre pas d'un manque de divers guides, tutoriels, étape par étape, etc. Il se trouve que j'ai été chargé de développer une solution pour l'organisation et la construction pratiques d'un cluster PostgreSQL à sécurité intégrée, dont les principales exigences étaient la réplication en continu du serveur maître vers toutes les répliques et l'entrée automatique de la réserve en cas de défaillance du serveur maître.


À ce stade, la pile de technologies utilisées a été définie:


  • PostgreSQL en tant que SGBD
  • Patroni comme solution de clustering
  • etcd comme stockage distribué pour Patroni
  • HAproxy pour l'organisation d'un point d'entrée unique pour les applications qui utilisent la base de données

L'installation


Votre attention - la construction d'un cluster PostgreSQL haute disponibilité utilisant Patroni, etcd, HAProxy.


Toutes les opérations ont été effectuées sur des machines virtuelles avec Debian 10 installé.


etcd


Je ne recommande pas d'installer etcd sur les mêmes machines où se trouveront patroni et postgresql, car la charge du disque est très importante pour etcd. Mais à des fins de formation, nous ferons exactement cela.
Installez etcd.


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

Ajoutez le contenu au fichier / etc / default / etcd

[membre]


ETCD_NAME = datanode1 # nom d'hôte de votre machine
ETCD_DATA_DIR = "/ var / lib / etcd / default.etcd"


TOUTES LES ADRESSES IP DEVRAIENT ÊTRE VALIDES. LISTER PEER, CLIENT, etc. DEVRAIT ÊTRE RÉGLÉ À L'ADRESSE IP DE L'HÔTE


ETCD_LISTEN_PEER_URLS = " http://192.168.0.143:2380 " # l'adresse de votre machine
ETCD_LISTEN_CLIENT_URLS = " http://192.168.0.143:2379,http://127.0.0.1:2379 " # l'adresse de votre machine


[cluster]


ETCD_INITIAL_ADVERTISE_PEER_URLS = " http://192.168.0.143:2380 " # adresse de votre machine
ETCD_INITIAL_CLUSTER = "datanode1 = http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380 " # adresses de toutes les machines du cluster etcd
ETCD_INITIAL_CLUSTER_STATE = "nouveau"
ETCD_INITIAL_CLUSTER_TOKEN = "etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS = " http://192.168.0.143:2379 " # l'adresse de votre machine


Exécutez la commande


 systemctl restart etcd 

PostgreSQL 9.6 + patroni


La première chose à faire est d'installer trois machines virtuelles pour y installer les logiciels nécessaires. Après avoir installé les machines, si vous suivez mon tutoriel, vous pouvez exécuter ce script simple qui fait (presque) tout pour vous. Exécuter en tant que root.


Veuillez noter que le script utilise PostgreSQL version 9.6, cela est dû aux exigences internes de notre société. La solution n'a pas été testée sur d'autres versions 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 

Ensuite, dans le fichier /etc/patroni.yml qui vient d'être créé, vous devez mettre le contenu suivant, en changeant bien sûr les adresses IP à tous les endroits par les adresses que vous utilisez.
Faites attention aux commentaires dans ce yaml. Modifiez les adresses en fonction des vôtres sur chaque machine du cluster.


/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 

Le script doit être exécuté sur les trois machines du cluster, tout comme vous devez placer la configuration dans le fichier /etc/patroni.yml sur toutes les machines.


Lorsque vous effectuez ces opérations sur toutes les machines du cluster, exécutez la commande suivante sur l'une d'entre elles


 systemctl start patroni systemctl start postgresql 

Attendez environ 30 secondes, puis exécutez cette commande sur les autres machines du cluster.


HAproxy


Nous utilisons le merveilleux HAproxy pour fournir un point d'entrée unique. Le serveur maître sera toujours disponible à l'adresse de la machine sur laquelle HAproxy est déployé.


Afin de ne pas faire de la machine HAproxy un point de défaillance unique, exécutez-la dans le conteneur Docker, plus tard il sera possible de l'exécuter dans le cluster K8 et rendre notre cluster de basculement encore plus fiable.


Créez un répertoire dans lequel vous pouvez stocker deux fichiers - Dockerfile et haproxy.cfg. Allez-y.


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 

Attention, les trois dernières lignes du fichier haproxy.cfg doivent lister les adresses de vos machines. HAproxy contactera Patroni, dans les en-têtes HTTP, le serveur maître renverra toujours 200 et la réplique renverra 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 

Étant dans le répertoire dans lequel se trouvent nos deux fichiers, nous exécuterons séquentiellement les commandes de conditionnement des conteneurs, ainsi que son lancement avec la redirection des ports nécessaires:


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

Maintenant, en ouvrant l'adresse du navigateur de votre machine avec HAproxy et en spécifiant le port 7000, vous verrez des statistiques sur votre cluster.


Dans l'état UP, le serveur maître sera localisé et les répliques dans l'état DOWN. C'est normal, en fait ils fonctionnent, mais ils sont affichés sous cette forme car ils renvoient 503 aux requêtes de HAproxy. Cela nous permet de toujours savoir exactement lequel des trois serveurs est le maître en ce moment.


Conclusion


Tu es incroyable! En seulement 30 minutes, vous avez déployé un excellent cluster de bases de données productives et à sécurité intégrée avec réplication en continu et provisionnement automatique. Si vous prévoyez d'utiliser cette solution, consultez la documentation officielle de Patroni , et en particulier sa partie concernant l'utilitaire patronictl, qui fournit un accès pratique pour gérer votre cluster.


Félicitations!

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


All Articles