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 :
- Comparatif des gestionnaires de VIP dans un cluster Patroni : épisode 1 (KEEPALIVED) (David Baffaleuf) [ContainerPostgreSQL]
- Haute disponibilité de PostgreSQL avec Patroni (Ludovic AUGEREAU) [PostgreSQL]
- Kubegres : l’opérateur Kubernetes clé en main pour PostgreSQL (David Baffaleuf) [ContainerDevopsPostgreSQL]
- Migrer d’un cluster Galera MariaDB 10.3 vers MariaDB 10.5 avec la réplication logique (David Baffaleuf) [ContainerMySQLNon classé]
- AWS : Configurer un cluster PostgreSQL HD avec Corosync/Pacemaker sur des EC2 Amazon (Emmanuel RAMI) [AWSPostgreSQL]