Table des matières

2021/04/03 (Neutriton) : PostgreSQL HA

Présences :

Jitsi : https://jitsi.belnet.be/neutriton Caldarium : https://caldarium.be/fr:contact

Météo

Moment informel durant lequel on exprime en peu de mots comment on se sent et si on a une attente forte pour la réunion.

Ce n'est pas un moment de discussion mais d'expression individuelle et ce n'est pas obligatoire 🙂

Attente(s) forte(s)

Si l'une ou l'autre personne exprime une attente forte, merci de vous en occuper en priorité ou de la noter dans le hub ou dans un point approprié.

Ordre du jour

Resources

Résumé des différents modes de HA: https://www.postgresql.org/docs/13/different-replication-solutions.html#HIGH-AVAILABILITY-MATRIX

Présentation de Patroni

Il faut vraiment voir Patroni comme un framework. Il va utiliser plusieurs pièces.

Etcd : permet à patroni de mettre dans la configuration et faire le quorum. Comme une db clé-valeur mais avec une notion de quorum. C'est simple à utiliser. Patroni supporte d'autres solutions pour gérer le quorum (voir la doc de Patroni). Il en faut trois pour avoir un quorum, mais pas obligé d'avoir trois PostgreSQL.

Debian fournit une commande magique qui boostrap tout pour nous :

snippet.shell
pg_createconfig_patroni 11 neutrinet

Patroni va communiquer avec la db qu'il gère et etcd. Il communique aussi avec les autres Patroni pour leur dire de synchroniser leurs données.

HAProxy va contacter Patroni pour lui demander qui est le primary et qui sont les replicas. Un des patroni va répondre, et HAProxy va rediriger les requêtes SQL vers la DB en primary.

Si la DB primary est déficiente, alors un des replicas va être élu en primary pour prendre le relais (c'est patroni qui s'occupe d'élire le primary).

Installation de etcd

On commence par etcd, qui est dans les repos debian 🙂 Bien entendu, on le fait pour les trois serveurs:

snippet.shell
apt install etcd

On crée un réseau privé pour etcd et patroni. psql-01 → 10.0.0.4 psql-02 → 10.0.0.3 psql-03 → 10.0.0.2

Dans /etc/default/etcd se trouve la config de etcd. On donne un nom au cluster (ex : ǹeutrinet)

snippet.conf
# nom du serveur
ETCD_NAME="psql-0X" 
# port d'écoute pour d'autres etcd
# on doit définir tout ça pour lui dire d'écouter sur localhost ET sur son ip privée
ETCD_LISTEN_PEER_URLS="http://10.0.0.4:2380"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379, http://10.50.20.41:2379" 
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.0.4:2380"
# on définit tous les membres du cluster
ETCD_INITIAL_CLUSTER="psql-01=http://10.0.0.4:2380,psql-02=http://10.0.0.3:2380,psql-03=http://10.0.0.2:2380" 
# si pas de configuration, tu fais quoi ? ben tu crées un nouveau cluster
ETCD_INITIAL_CLUSTER_STATE="new"
# token utilisé pour initialiser le cluster
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
# clients peuvent savoir combien de clients dans le cluster existent, comme ça le client est capable d'aller sur un autre serveur
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379, http://10.0.0.4:2379"

Quand on parle de client, ce sont les patroni (ce sont eux qui vont parler à etcd).

On supprime la config par défaut de etcd:

snippet.shell
rm /var/lib/etcd/default

On redémarre les etcd :

snippet.shell
systemctl restart etcd

Dans cette config, on n'a pas configuré la communication TLS, mais bon c'est qu'une démo 😉

Commandes pour vérifier le statut du cluster: - cluster-health → doit renvoyer cluster is healthy 🌻 - member list → doit renvoyer la liste des serveurs

Dans les logs on va voir quel serveur devient leader. Chaque serveur possède un id unique (on voit à qui correspond l'id avec la commande member list)

Installation de patroni

snippet.shell
apt install patroni postgresql-contrib postgresql-client postgresql haproxy

Il faut détruire le cluster db postgresql par défaut. Par défaut, Debian créé un cluster main et le démarre. Donc :

pg_ctlcluster 11 main stop
pg_lsclusters
pg_dropcluster 11 main

Pour manipuler le cluster, Debian fournit une commande patroni :

pg_createconfig_patroni 11 neutrinet

Patroni a déjà des valeurs par défaut. Par contre, il faut lui dire comment se connecter à etcd.

Patroni peut utiliser soit zookeeper, consul ou etcd pour gérer le quorum du cluster. Patroni peut juste se connecter à son etcd local et apprendre où se trouvent les autres Patroni.

Par défaut, Patroni crée deux utilisateurs : - postgres - replica

Dans /etc/patroni/11-neutrinet.yml on va modifier les IP publiques par les IP privées du cluster.

pg_hba : définit comment les clients psql peuvent se connecter à la db. En mode tcp, il faut définir un mot de passe. En mode socket, on utilise le système de permissions Unix. Colonne 1: tcp vs socket (host vs local), et puis j'ai plus suivi 😛

On active le cluster puis on redémarre le patroni:

systemctl enable patroni@11-neutrinet
systemctl restart patroni@11-neutrinet

Dans les logs, Patroni va fanfaronner que c'est lui le chef en agitant un cadenas: i am the leader with the lock

Et les autres vont dire qu'ils sont secondaires et qu'ils suivent leur chef…

Patroni possède une API REST avec laquelle on va un peu jouer. Notamment, des healtcheck pour savoir qui est le primary ou qui sont les replicas. On peut aussi forcer un primary à devenir replicas, etc.

On doit viser l'url sur l'IP privée (sur localhost ça ne va pas marcher) :

snippet.shell
curl http://10.0.0.4:8008/patroni | jq .

Pour avoir les infos du cluster:

snippet.shell
curl http://10.0.0.4:8008/cluster | jq .

Installation de HAProxy

On accélère, de toute façon la config va tenir sur quelques lignes.

On active les metrics prometheus fournies par HAProxy… Enfin si la version est suffisamment récente 😅

Puis on va faire un reverse proxy du port par défaut de psql (5432) vers le port défini dans patroni (ici on met 5442). HAProxy va regarder le endpoint /master pour savoir qui est le master parmi les trois serveurs. Si le serveur ne répond pas 200 OK, alors HAProxy va considérer que ce serveur n'est pas primary.

On fait pareil pour les replicas, sauf qu'on écoute sur le port 5433 et on regarde le endpoint /replica.

Dans les logs de HAProxy, on va bien que psql-02 et psql-03 sont considérés DOWN sur /master (code http 503 Service unavailable), et psql-01 est considéré DOWN sur /replica (donc c'est lui le primary).

Raison de la HA : ne pas courir en cas d'incident. Si un des deux Proxmox crash, cela ne doit pas générer de la panique chez Neutrinet. L'autre aspect, ce sont les mises à jour. Sans réplication, on doit couper tous les services pour mettre à jour.

En résumé : On a une VIP gérée par keepalived qui va se coller à une VM encore UP, et le HAProxy va détecter qui est le primary et qui sont les secondary. Mais, si on n'utilise pas le mode read-only, alors on peut virer le HAProxy. Mais alors comment on détecte le primary ? c'est keepalived qui peut tester ça grâce à l'API de patroni.

snippet.shell
curl -X OPTIONS -I http://10.0.0.3:8008/primary

Patroni simplifie les backups : on peut prendre un replica et le sortir du cluster mais il est tout de même mis à jour. C'est sur celui-là qu'on envoit les backups.

Comparaison avec d'autres outils de PostgreSQL HA

Alternatives sont - PAF (Postgresql Automatic Failover) - repmgr → pas vraiment HA

Patroni est sous licence MIT. PAF a pas vraiment de licence claire…

Personne n'a de connaissance sur PAF, donc on irait plutôt vers Patroni.

On décide d'utiliser Patroni \o/ ./ 🙆 \°/

Prochaine réunion

Prochain Neutriton (pfsense NAT) : 25/04 à 14h

Lieu : Jitsi et/ou Caldarium

Après ça, on aimerait faire un atelier dans la serre pour installer les VMs. On commencerait avec les sites statics (mediawiki, wikijs).

Météo de fin

Moment informel durant lequel on exprime en peu de mots comment, à titre personnel, la réunion a été vécue que ce soit positif ou négatif. Si une ou plusieurs tension est née durant la réunion, il est peut-être nécessaire d'envisager l'une ou l'autre réunion pour y remédier.