0

Comparatif des gestionnaires de VIP dans un cluster Patroni : épisode 2 (VIP-MANAGER)

twitterlinkedinmail

Dans l’article précédent, nous avions évalué keepalived comme solution simple et généraliste pour gérer une VIP dans un cluster Patroni.

Aujourd’hui nous allons tester une solution plus spécialisée, vip-manager de Cybertec. Cybertec est une entreprise basée en Autriche et contribue au développement de l’écosystème PostgreSQL en proposant des outils notamment autour de la sécurisation avec du TDE, du Data Masking ou encore de l’encryption de procédures PL/PGSQL.

Le fonctionnement de vip-manager est similaire à keepalived: sur chaque noeud un service monitore le statut de leader maintenu par Patroni, et en fonction d’un changement de rôle, tombe la VIP sur le noeud qui devient Replica, ou la remonte sur celui qui devient Leader. La différence, c’est qu’il est dédié à Patroni / PostgreSQL alors que keepalived peut servir d’autres types de produits.

Schéma

La configuration sera la même qu’avec keepalived, avec la même VIP…

Installation et configuration

L’installation se fait soit depuis les sources soit depuis un package RPM ou DEB disponible sur le github de Cybertec.

root@pgpat1:~# wget https://github.com/cybertec-postgresql/vip-manager/releases/download/v1.0.1/vip-manager_1.0.1-1_amd64.deb
root@pgpat1:~# dpkg -i vip-manager_1.0.1-1_amd64.deb 
Selecting previously unselected package vip-manager.
(Reading database ... 31523 files and directories currently installed.)
Preparing to unpack vip-manager_1.0.1-1_amd64.deb ...
Unpacking vip-manager (1.0.1-1) ...
Setting up vip-manager (1.0.1-1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/vip-manager.service → /lib/systemd/system/vip-manager.service.

Le fichier YAML de configuration par défaut se trouve sous /etc/default/vip-manager.yml:

root@pgpat1:~# vi /etc/default/vip-manager.yml 
(...)
interval: 1000
trigger-key: "/service/pg-cluster/leader"
trigger-value: "pgpat1"
ip: 10.186.157.199 # the virtual ip address to manage
netmask: 24 # netmask for the virtual ip
interface: eth0 #interface to which the virtual ip will be added
hosting-type: basic # possible values: basic, or hetzner.
dcs-type: etcd # etcd or consul
dcs-endpoints:
  - http://127.0.0.1:2379
  - https://10.186.157.60:2379
  - https://10.186.157.216:2379
  - https://10.186.157.3:2379
etcd-user: "root"
etcd-password: "*******"
retry-num: 2
retry-after: 250  #in milliseconds
verbose: false

La liste des arguments est référencée dans le github, je ne m’attarde donc pas dessus, rien de particulier sinon ne pas se tromper dans l’URL qui sera testée (trigger-key) et qui porte le format namespace/scope/leader, en référence aux paramètres de Patroni. Si namespace n’est pas indiqué dans le fichier /etc/patroni/patroni.yml, sa valeur par défaut sera ‘service’. Quant au scope, c’est le nom du cluster:

root@pgpat1:~# grep scope /etc/patroni/patroni.yml
scope: pg-cluster

Faire la même chose sur le noeud n°2 (pgpat2 dans note cas) en adaptant la valeur de trigger-value, et redémarrer les services sur chaque noeud:

root@pgpat1:~# systemctl restart vip-manager.service

root@pgpat1:~# systemctl status vip-manager.service
● vip-manager.service - Manages Virtual IP for Patroni
   Loaded: loaded (/lib/systemd/system/vip-manager.service; enabled; vendor preset: enabled)
  Drop-In: /run/systemd/system/vip-manager.service.d
           └─zzz-lxc-service.conf
   Active: active (running) since Mon 2022-03-07 08:24:54 UTC; 7s ago
 Main PID: 4708 (vip-manager)
    Tasks: 7 (limit: 4619)
   CGroup: /system.slice/vip-manager.service
           └─4708 /usr/bin/vip-manager --config=/etc/default/vip-manager.yml

Mar 07 08:24:54 pgpat1 vip-manager[4708]:         trigger-key : /service/pg-cluster/leader
Mar 07 08:24:54 pgpat1 vip-manager[4708]:         trigger-value : pgpat1
Mar 07 08:24:54 pgpat1 vip-manager[4708]:         verbose : false
Mar 07 08:24:54 pgpat1 vip-manager[4708]:         version : false
Mar 07 08:24:54 pgpat1 vip-manager[4708]: 2022/03/07 08:24:54 IP address 10.186.157.199/24 state is false, desired false
Mar 07 08:24:54 pgpat1 vip-manager[4708]: 2022/03/07 08:24:54 IP address 10.186.157.199/24 state is false, desired true
Mar 07 08:24:54 pgpat1 vip-manager[4708]: 2022/03/07 08:24:54 Configuring address 10.186.157.199/24 on eth0
Mar 07 08:24:54 pgpat1 vip-manager[4708]: 2022/03/07 08:24:54 Sent gratuitous ARP reply
Mar 07 08:24:54 pgpat1 vip-manager[4708]: 2022/03/07 08:24:54 Sent gratuitous ARP request
Mar 07 08:24:54 pgpat1 vip-manager[4708]: 2022/03/07 08:24:54 IP address 10.186.157.199/24 state is true, desired true

On peut alors vérifier que la VIP est bien montée sur le Leader, et démontée sur le Replica:

root@ubuntu20:~# lxc list pgpat
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
|  NAME  |  STATE  |         IPV4          |                     IPV6                      |   TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat1 | RUNNING | 10.186.157.60 (eth0)  | fd42:a4e7:fd78:5160:216:3eff:feaf:c4a5 (eth0) | CONTAINER | 0         |
|        |         | 10.186.157.199 (eth0) |                                               |           |           |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat2 | RUNNING | 10.186.157.216 (eth0) | fd42:a4e7:fd78:5160:216:3eff:fe8c:9004 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat3 | RUNNING | 10.186.157.3 (eth0)   | fd42:a4e7:fd78:5160:216:3eff:fe8c:fd27 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+

Tests de bascule:

Comme pour keepalived, nous voulons tester le temps de bascule de la VIP. Nous allons cette fois lancer dans une boucle une connexion à l’instance PostgreSQL chaque seconde, en nous alignant sur le temps de détection de changement d’état configuré pour vip-manager (paramètre interval: 1000 dans /etc/default/vip-manager.yml ), et faire un switchover suivi d’un switchback :

Switchover / switchback:

root@pgpat1:~# patronictl -c /etc/patroni/patroni.yml switchover --master pgpat1 --candidate pgpat2 --force
Current cluster topology
+--------+----------------+---------+---------+----+-----------+
| Member | Host           | Role    | State   | TL | Lag in MB |
+ Cluster: pg-cluster (7069750172117562885) --+----+-----------+
| pgpat1 | 10.186.157.60  | Leader  | running | 29 |           |
| pgpat2 | 10.186.157.216 | Replica | running | 29 |         0 |
+--------+----------------+---------+---------+----+-----------+
2022-03-07 10:12:51.43321 Successfully switched over to "pgpat2"

root@pgpat1:~# patronictl -c /etc/patroni/patroni.yml switchover --master pgpat2 --candidate pgpat1 --force
Current cluster topology
+--------+----------------+---------+---------+----+-----------+
| Member | Host           | Role    | State   | TL | Lag in MB |
+ Cluster: pg-cluster (7069750172117562885) --+----+-----------+
| pgpat1 | 10.186.157.60  | Replica | running | 30 |         0 |
| pgpat2 | 10.186.157.216 | Leader  | running | 30 |           |
+--------+----------------+---------+---------+----+-----------+
2022-03-07 10:13:30.66680 Successfully switched over to "pgpat1"

Vérification de bascule de la VIP:

root@ubuntu20:~# watch lxc list pgpat
Every 2,0s: lxc list pgpat                                                                                                                                                                         ubuntu20: Mon Mar  7 11:18:51 2022
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
|  NAME  |  STATE  |         IPV4          |                     IPV6                      |   TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat1 | RUNNING | 10.186.157.60 (eth0)  | fd42:a4e7:fd78:5160:216:3eff:feaf:c4a5 (eth0) | CONTAINER | 0         |
|        |         | 10.186.157.199 (eth0) |                                               |           |           |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat2 | RUNNING | 10.186.157.216 (eth0) | fd42:a4e7:fd78:5160:216:3eff:fe8c:9004 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat3 | RUNNING | 10.186.157.3 (eth0)   | fd42:a4e7:fd78:5160:216:3eff:fe8c:fd27 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+

+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
|  NAME  |  STATE  |         IPV4          |                     IPV6                      |   TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat1 | RUNNING | 10.186.157.60 (eth0)  | fd42:a4e7:fd78:5160:216:3eff:feaf:c4a5 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat2 | RUNNING | 10.186.157.216 (eth0) | fd42:a4e7:fd78:5160:216:3eff:fe8c:9004 (eth0) | CONTAINER | 0         |
|        |         | 10.186.157.199 (eth0) |                                               |           |           |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat3 | RUNNING | 10.186.157.3 (eth0)   | fd42:a4e7:fd78:5160:216:3eff:fe8c:fd27 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+

+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
|  NAME  |  STATE  |         IPV4          |                     IPV6                      |   TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat1 | RUNNING | 10.186.157.60 (eth0)  | fd42:a4e7:fd78:5160:216:3eff:feaf:c4a5 (eth0) | CONTAINER | 0         |
|        |         | 10.186.157.199 (eth0) |                                               |           |           |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat2 | RUNNING | 10.186.157.216 (eth0) | fd42:a4e7:fd78:5160:216:3eff:fe8c:9004 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+
| pgpat3 | RUNNING | 10.186.157.3 (eth0)   | fd42:a4e7:fd78:5160:216:3eff:fe8c:fd27 (eth0) | CONTAINER | 0         |
+--------+---------+-----------------------+-----------------------------------------------+-----------+-----------+

Effets sur la connexion:

root@ubuntu20:~# while(true)
> do
> psql -U postgres -h 10.186.157.199 -p 5432 -c '\conninfo'
> sleep 1
> done
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
psql: error: could not connect to server: Connection refused
	Is the server running on host "10.186.157.199" and accepting
	TCP/IP connections on port 5432?
psql: error: could not connect to server: Connection refused
	Is the server running on host "10.186.157.199" and accepting
	TCP/IP connections on port 5432?
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".
You are connected to database "postgres" as user "postgres" on host "10.186.157.199" at port "5432".

On voit qu’on ne perd que 2 connexions lors de la bascule. Côté réseau dans les 3/4 des cas on ne voit même pas le changement d’un hop à l’autre tant le processus est infiniment plus rapide que keepalived. A noter que keepalived était aussi configuré pour tester l’état du cluster toutes les 1 secondes (advert_int 1).

Conclusion

En conclusion, vip-manager, en étant spécialement conçu pour Patroni, permet de remplir très efficacement le rôle de gestionnaire de VIP. Lors des tests, il semble nettement plus efficace que keepalived en termes de temps de bascule. A suivre avec intérêt donc …

A+ bonne semaine à toutes et tous.
~David

Continuez votre lecture sur le blog :

twitterlinkedinmail

David Baffaleuf

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.