Paris, le 11 septembre 2020

Devrim Günduz a tweeté le 18 août à propos de la mise à disposition de Patroni dans les dépôts YUM, avant d’annoncer celle de la version 2.0. Mais peut-être vous demandez-vous comment mettre en place une architecture simple de Haute Disponibilité avec Patroni et etcd ? Au cas où, voici les instructions de l’un de nos DBAs Alexandre Pereira.

Avant toute chose, nous tenons à remercier Devrim, de chez EnterpriseDB. Il fait partie des major contributors de la communauté, et s’occupe entre autres des paquets RPM.

Patroni et etcd ?

portrait d'Alexandre À quoi sert Patroni ?

Patroni permet de créer une architecture de Haute Disponibilité pour PostgreSQL en utilisant Python, ainsi qu’un DCS (Distributed Configuration Store).

Le DCS, ici etcd, permet de garantir l’intégrité du cluster, c’est un élément indispensable pour la haute disponibilité avec Patroni.

Attention : ces instructions sont suggérées pour des tests, pas pour le déploiement en production !

Mise en place

Prérequis : 3 Machines (Virtuelles) - CentOS 7.8

  • patroni01 : 192.168.122.20
  • patroni02 : 192.168.122.21
  • patroni03 : 192.168.122.22

Installation de PostgreSQL (sur les 3 nœuds)

1 - Installation du dépôt PGDG :

[root@patroni01 ~]# yum install epel-release
[root@patroni01 ~]# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

2 - Installation de PostgreSQL 12 :

[root@patroni01 ~]# yum install postgresql12 postgresql12-server postgresql12-contrib -y

Installation et configuration du cluster etcd

1 - Installation de etcd (noeud 1, 2 & 3):

[root@patroni01 ~]# yum install etcd -y

2 - Configuration de etcd (sur les 3 nœuds).

[root@patroni01 ~]# cat /etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://127.0.0.1:2380,http://192.168.122.20:2380"
ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://192.168.122.20:2379"
ETCD_NAME="patroni01"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.122.20:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.122.20:2379"
ETCD_INITIAL_CLUSTER="patroni01=http://192.168.122.20:2380,patroni02=http://192.168.122.21:2380,patroni03=http://192.168.122.22:2380"
ETCD_INITIAL_CLUSTER_TOKEN="CHANGEME"
ETCD_INITIAL_CLUSTER_STATE="new"

Les paramètres suivants sont à adapter selon vos adresses IP et nom d’hôte sur chaque nœud:

  • ETCD_LISTEN_PEER_URLS : http://[IP_HOTE]:2380
  • ETCD_LISTEN_CLIENT_URLS : http://[IP_HOTE]:2379
  • ETCD_NAME : [NOM_HOTE]
  • ETCD_INITIAL_ADVERTISE_PEER_URLS : http://[IP_HOTE]>:2380
  • ETCD_ADVERTISE_CLIENT_URLS : http://[IP_HOTE]:2379
  • ETCD_INITIAL_CLUSTER : [NOM_HOTE1]=http://[IP_HOTE1]:2380,[NOM_HOTE2]=http://[IP_HOTE2]:2380,[NOM_HOTE3]=http://[IP_HOTE3]:2380

3 - Démarrage de etcd (sur les 3 nœuds) :

[root@patroni01 ~]# systemctl start --now etcd

4 - Vérifiez le statut du service une fois lancé sur les 3 machines.

[root@patroni03 ~]# systemctl status etcd
● etcd.service - Etcd Server
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; disabled; vendor preset: disabled)
   Active: active (running) since jeu. 2020-09-10 14:32:35 CEST; 2h 47min ago
 Main PID: 1619 (etcd)
   CGroup: /system.slice/etcd.service
           └─1619 /usr/bin/etcd --name=patroni03 --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://127...
sept. 10 14:32:35 patroni03 etcd[1619]: established a TCP streaming connection with peer cf60b991b1c433a3 (strea...riter)
sept. 10 14:32:35 patroni03 etcd[1619]: established a TCP streaming connection with peer cf60b991b1c433a3 (strea...riter)
sept. 10 14:32:35 patroni03 etcd[1619]: e7f40a2c7bc42d5b initialzed peer connection; fast-forwarding 8 ticks (el...eer(s)
sept. 10 14:32:35 patroni03 etcd[1619]: published {Name:patroni03 ClientURLs:[http://192.168.122.22:2379]} to cl...20038a
sept. 10 14:32:35 patroni03 etcd[1619]: ready to serve client requests
sept. 10 14:32:35 patroni03 etcd[1619]: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
sept. 10 14:32:35 patroni03 etcd[1619]: ready to serve client requests
sept. 10 14:32:35 patroni03 etcd[1619]: serving insecure client requests on 192.168.122.22:2379, this is strongl...raged!
sept. 10 14:32:35 patroni03 systemd[1]: Started Etcd Server.
sept. 10 17:16:09 patroni03 etcd[1619]: sync duration of 1.98973239s, expected less than 1s
Hint: Some lines were ellipsized, use -l to show in full.

Installation et configuration de Patroni

1 - Installation de patroni-etcd (noeud 1, 2 & 3):

[root@patroni01 ~]# yum install patroni-etcd python36-idna.noarch python36-cryptography python36-pyOpenSSL.noarch python36-certifi.noarch -y

Les paquets Python supplémentaires sont nécessaires au bon fonctionnement de Patroni 2.0, notamment pour la dépendance python-36urllib3.

2 - Configuration de Patroni (noeud 1): (Les configurations suivantes sont tirés des samples disponibles /usr/share/doc/patroni-2.0.0/)

[root@patroni01 ~]# mkdir -p /etc/patroni/
[root@patroni01 ~]# cat /etc/patroni/patroni.yml
scope: batman
#namespace: /service/
name: patroni01
restapi:
  listen: 192.168.122.20:8008
  connect_address: 192.168.122.20:8008
log:
  level: INFO
  dir: /var/log/patroni/main
etcd:
  hosts:
  - 192.168.122.20:2379
  - 192.168.122.21:2379
  - 192.168.122.22:2379
  username: root
  password: CHANGEME
  protocol: http
  cacert: None
bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      parameters:
  initdb:  # Note: It needs to be a list (some options need values, others are switches)
  - encoding: UTF8
  - data-checksums
  pg_hba:  # Add following lines to pg_hba.conf after running 'initdb'
  - host replication replicator 192.168.122.0/24 md5
  - host all all 0.0.0.0/0 md5
  users:
    admin:
      password: admin
      options:
        - createrole
        - createdb
postgresql:
  listen: "*:5432"
  connect_address: 192.168.122.20:5432
  data_dir: /var/lib/pgsql/12/data
  bin_dir: /usr/pgsql-12/bin
  pgpass: /tmp/pgpass0
  authentication:
    replication:
      username: replicator
      password: rep-pass
    superuser:
      username: postgres
      password: CHANGEME
    rewind:  # Has no effect on postgres 10 and lower
      username: rewind_user
      password: rewind_password
  parameters:
    unix_socket_directories: '.'
watchdog:
  mode: automatic # Allowed values: off, automatic, required
  device: /dev/watchdog
  safety_margin: 5
tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

3 - Configuration Patroni (noeud 2 & 3).
Tout comme etcd, adaptez la configuration (IPs, nom d’hôte, ports, etc…) :

[root@patroni02 ~]# mkdir -p /etc/patroni/
[root@patroni02 ~]# cat /etc/patroni/patroni.yml
scope: batman
name: patroni02
restapi:
  listen: 192.168.122.21:8008
  connect_address: 192.168.122.21:8008
log:
  level: INFO
  dir: /var/log/patroni/main
etcd:
  hosts:
  - 192.168.122.20:2379
  - 192.168.122.21:2379
  - 192.168.122.22:2379
  username: root
  password: CHANGEME
  protocol: http
  cacert: None
bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      parameters:
  initdb:  # Note: It needs to be a list (some options need values, others are switches)
  - encoding: UTF8
  - data-checksums
  pg_hba:  # Add following lines to pg_hba.conf after running 'initdb'
  - host replication replicator 192.168.122.0/24 md5
  - host all all 0.0.0.0/0 md5
  users:
    admin:
      password: admin
      options:
        - createrole
        - createdb
postgresql:
  listen: "*:5432"
  connect_address: 192.168.122.21:5432
  data_dir: /var/lib/pgsql/12/data
  bin_dir: /usr/pgsql-12/bin
  pgpass: /tmp/pgpass1
  authentication:
    replication:
      username: replicator
      password: rep-pass
    superuser:
      username: postgres
      password: CHANGEME
    rewind:  # Has no effect on postgres 10 and lower
      username: rewind_user
      password: rewind_password
  parameters:
    unix_socket_directories: '.'
  basebackup:
      - verbose
      - max-rate: 100M
watchdog:
  mode: automatic # Allowed values: off, automatic, required
  device: /dev/watchdog
  safety_margin: 5
tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false  

4 - Création répertoire de logs Patroni (sur les 3 nœuds):

[root@patroni01 ~]# install -o postgres -g postgres -m 0750 -d /var/log/patroni/main

5 - Exécution de Patroni (noeud 1):

[root@patroni01 ~]# systemctl start --now patroni
[root@patroni01 ~]# systemctl status patroni
● patroni.service - Runners to orchestrate a high-availability PostgreSQL
   Loaded: loaded (/usr/lib/systemd/system/patroni.service; disabled; vendor preset: disabled)
   Active: active (running) since mer. 2020-09-02 11:54:30 CEST; 3s ago
 Main PID: 1844 (patroni)
   CGroup: /system.slice/patroni.service
           ├─1844 /usr/bin/python3 /usr/bin/patroni /etc/patroni/patroni.yml
           ├─1871 /usr/pgsql-12/bin/postgres -D /var/lib/pgsql/12/data --config-file=/var/lib/pgsql/12/data/postgresql.conf --listen_addresses=* --port=5432...
           ├─1872 /usr/pgsql-12/bin/pg_isready -p 5432 -d postgres -h localhost -U postgres
           └─1874 postgres: batman: logger   
sept. 02 11:54:33 patroni01 patroni[1844]: ou en utilisant l'option -A, ou --auth-local et --auth-host au prochain
sept. 02 11:54:33 patroni01 patroni[1844]: lancement d'initdb.
sept. 02 11:54:33 patroni01 patroni[1844]: Succès. Vous pouvez maintenant lancer le serveur de bases de données en utilisant :
sept. 02 11:54:33 patroni01 patroni[1844]: /usr/pgsql-12/bin/pg_ctl -D /var/lib/pgsql/12/data -l fichier_de_trace start
sept. 02 11:54:34 patroni01 patroni[1844]: 2020-09-02 11:54:34.330 CEST [1871] LOG:  démarrage de PostgreSQL 12.4 on x86_64-pc-linux-gnu, compiled …39), 64-bit
sept. 02 11:54:34 patroni01 patroni[1844]: 2020-09-02 11:54:34.331 CEST [1871] LOG:  en écoute sur IPv4, adresse « 0.0.0.0 », port 5432
sept. 02 11:54:34 patroni01 patroni[1844]: 2020-09-02 11:54:34.331 CEST [1871] LOG:  en écoute sur IPv6, adresse « :: », port 5432
sept. 02 11:54:34 patroni01 patroni[1844]: 2020-09-02 11:54:34.347 CEST [1871] LOG:  écoute sur la socket Unix « ./.s.PGSQL.5432 »
sept. 02 11:54:34 patroni01 patroni[1844]: 2020-09-02 11:54:34.371 CEST [1871] LOG:  redirection des traces vers le processus de récupération des traces
sept. 02 11:54:34 patroni01 patroni[1844]: 2020-09-02 11:54:34.371 CEST [1871] ASTUCE :  Les prochaines traces apparaîtront dans le répertoire « log ».
Hint: Some lines were ellipsized, use -l to show in full.

6 - Exécution de Patroni (noeud 2 & 3):

[root@patroni02 ~]# systemctl start --now patroni
[root@patroni03 ~]# systemctl start --now patroni

7 - Vérification des noeuds :

[root@patroni03 ~]# patronictl -c /etc/patroni/patroni.yml list
+ Cluster: batman (6867826528984086342) ---------+----+-----------+
| Member    | Host           | Role    | State   | TL | Lag in MB |
+-----------+----------------+---------+---------+----+-----------+
| patroni01 | 192.168.122.20 | Leader  | running |  2 |           |
| patroni02 | 192.168.122.21 | Replica | running |  2 |         0 |
| patroni03 | 192.168.122.22 | Replica | running |  2 |         0 |
+-----------+----------------+---------+---------+----+-----------+

Conclusion

Pour faciliter l’installation dans cet exemple, nous utilisons 3 machines afin de constituer le service de Haute-Disponibilité Patroni/etcd.

Il est cependant recommandé de séparer le service etcd de la machine hébergeant Patroni/PostgreSQL (et donc un total de 6 machines).

En suivant les étapes d’installation et de configuration, il est alors facile d’ajouter un noeud supplémentaire en adaptant la configuration.

L’installation à travers le package présent dans les dépôts facilite d’autant plus la gestion de Patroni, offrant notamment un fichier d’unité systemd pour démarrer, redémarrer, recharger ou stopper Patroni.

De plus, des modèles de configurations sont disponibles dans le répertoire /usr/share/doc/patroni-2.0.0/.


DALIBO

DALIBO est le spécialiste français de PostgreSQL. Nous proposons du support, de la formation et du conseil depuis 2005.