Construction d'un cluster PostgreSQL haute disponibilité avec Patroni, etcd, HAProxy

Il se trouve qu'au moment de la mise en place de la tâche, je n'avais pas assez d'expérience pour développer et lancer cette solution seul. J'ai alors commencé à chercher sur Google.

Je ne sais pas quelle en est la raison, mais c'est la énième fois que je fais face au fait que même en suivant toutes les étapes du tutoriel et en préparant un environnement identique à celui de l'auteur, rien ne fonctionne jamais. Je n'ai aucune idée de ce qui se passe, mais quand cela m'est arrivé à nouveau, j'ai décidé d'écrire mon propre tutoriel, celui qui fonctionnera réellement.

Guides sur Internet

Il se trouve que l'internet ne manque pas de guides, de tutoriels, de pas à pas et de choses similaires. Il se trouve que j'ai été chargé de développer une solution pour organiser et construire un cluster PostgreSQL tolérant aux pannes, dont les principales exigences étaient la réplication en flux depuis le serveur Master vers toutes les répliques et l'insertion automatique d'un secours en cas de défaillance du serveur Master.

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

  • PostgreSQL en tant que SGBD
  • Patroni comme solution pour la mise en cluster
  • etcd en tant que stockage distribué pour Patroni
  • HAproxy pour organiser un point d'entrée unique pour les applications utilisant la base de données

Installation

Voici une 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 pour etcd, la charge sur les disques est très importante. Mais à des fins d'apprentissage, nous allons procéder ainsi.
Installons etcd.

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

Ajoutez le contenu au fichier /etc/default/etcd

[member]

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

TOUTES LES ADRESSES IP DOIVENT ÊTRE VALIDES. L'ADRESSE PEER, CLIENT etc DOIT ÊTRE CONFIGURÉE AVEC L'ADRESSE IP DE L'HÔTE

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380" # adresse de votre machine
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379" # 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 dans le cluster etcd
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379" # 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 le logiciel nécessaire. Une fois les machines installées, si vous suivez mon tutoriel, vous pouvez exécuter ce simple script qui fera (quasiment) tout pour vous. Il s'exécute en tant que root.

Veuillez noter que le script utilise la version PostgreSQL 9.6, ce qui est dû aux exigences internes de notre entreprise. 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 que vous venez de créer /etc/patroni.yml, vous devez placer le contenu suivant, en changeant bien sûr les adresses IP à tous les endroits où vous en avez besoin.
Veuillez faire attention aux commentaires dans ce yaml. Modifiez les adresses pour les remplacer par les vôtres, sur chaque machine du cluster.

/etc/patroni.yml

portée: pgsql # doit être identique sur tous les nœuds
namespace: /cluster/ # doit être identique sur tous les nœuds
name: postgres1 # doit être différent sur tous les nœuds

restapi:
    listen: 192.168.0.143:8008 # adresse du nœud où se trouve ce fichier
    connect_address: 192.168.0.143:8008 # adresse du nœud où se trouve ce fichier

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # listez ici tous vos nœuds, si vous installez etcd sur eux aussi

# cette section (bootstrap) sera écrite dans Etcd:///config après l'initialisation du nouveau cluster
# et tous les autres membres du cluster l'utiliseront comme une `configuration globale`
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: fr_FR.UTF8
    # init pg_hba.conf doit contenir les adresses de TOUS les ordinateurs utilisés dans le cluster
    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 # adresse du nœud où se trouve ce fichier
    connect_address: 192.168.0.143:5432 # adresse du nœud où se trouve ce fichier
    data_dir: /data/patroni # ce répertoire sera créé par le script décrit ci-dessus et les droits appropriés seront appliqués
    bin_dir:  /usr/lib/postgresql/9.6/bin # indiquez le chemin vers votre répertoire contenant 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 toutes les trois machines du cluster, et la configuration fournie doit être placée dans le fichier /etc/patroni.yml sur toutes les machines.

Lorsque vous aurez effectué 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 accessible à l'adresse de la machine sur laquelle HAproxy est déployé.

Pour éviter que la machine avec HAproxy ne devienne un point de défaillance unique, nous allons le lancer dans un conteneur Docker, que nous pourrons ensuite exécuter dans un cluster K8’s et rendre notre cluster tolérant aux pannes encore plus fiable.

Créez un répertoire où vous pourrez stocker deux fichiers — Dockerfile et haproxy.cfg. Accédez-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, dans les trois dernières lignes du fichier haproxy.cfg, les adresses de vos machines doivent être répertoriées. HAproxy s'adressera à Patroni, dans les en-têtes HTTP, le serveur maître renverra toujours 200, tandis que 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

Dans le répertoire contenant nos deux fichiers, exécutons successivement les commandes pour empaqueter le conteneur et le démarrer avec les ports nécessaires redirigés :

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

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

L'état UP sera celui du serveur qui est maître, tandis que les répliques seront dans l'état DOWN. C'est normal, en réalité, ils fonctionnent, mais ils s'affichent ainsi parce qu'ils renvoient 503 aux requêtes de HAproxy. Cela nous permet de toujours savoir avec précision lequel des trois serveurs est le maître en ce moment.

Conclusion

Vous êtes formidable ! En seulement 30 minutes, vous avez déployé un excellent cluster de bases de données tolérant aux pannes et performant avec réplication en continu et basculement automatique. Si vous envisagez d'utiliser cette solution, consultez la documentation officielle de Patroni, en particulier la partie concernant l'outil patronictl, qui offre un accès pratique à la gestion de votre cluster.

Félicitations !

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster