Nantes, le 30 août 2023
check_patroni est une sonde Nagios conçue pour superviser un cluster haute disponibilité géré par Patroni. Elle existe depuis un peu plus d’un an et atteint désormais la version 1.0.0, marquant ainsi son passage en version stable.
Présentation
Cet outil propose une série de sondes permettant la supervision globale du cluster ainsi que celle de chaque nœud individuellement.
-
Sondes pour le cluster :
cluster_config_has_changed
: détecte les changements de la configuration dynamique depuis le dernier contrôle ;cluster_has_leader
: vérifie la présence d’un leader ou d’un standby leader dans le cluster ;cluster_has_replica
: s’assure que le nombre actuel de réplicas correspond au nombre attendu et qu’ils sont synchrones ;cluster_has_scheduled_action
: identifie les actions planifiées sur le cluster (switchover ou redémarrage) ;cluster_is_in_maintenance
: indique si le cluster est en mode maintenance ;cluster_node_count
: vérifie si le nombre de nœuds correspond aux attentes.
-
Sondes pour les nœuds :
node_is_alive
: vérifie si Patroni est opérationnel sur le nœud ;node_is_leader
: identifie si le nœud est un leader (ou un standby leader) ;node_is_pending_restart
: détecte si le nœud nécessite un redémarrage pour prendre en compte une configuration ;node_is_primary
: indique si le nœud est une instance primaire gérée par Patroni ;node_is_replica
: vérifie si le nœud est un réplica, et s’il est synchrone ou asynchrone ;node_patroni_version
: vérifie si le nœud utilise la version souhaitée de Patroni ;node_tl_has_changed
: détecte les changements récents de timeline sur le nœud.
Chaque sonde fournit également des données complémentaires (perf data) qui permettent d’avoir plus d’informations sur le nœud.
Installation
Installer check_patroni dans un environnement virtuel :
python3 -m venv .venv_check_patroni
. .venv_check_patroni/bin/activate
pip install --upgrade pip
pip install check_patroni
Tester la version :
check_patroni --version
Version 1.0.0
L’aide est accessible pour l’ensemble de la commande ou pour une sonde spécifique :
check_patroni --help
Usage: check_patroni [OPTIONS] COMMAND [ARGS]...
Nagios plugin that uses Patroni's REST API to monitor a Patroni cluster.
Options:
--config FILE Read option defaults from the specified INI file
[default: config.ini]
-e, --endpoints TEXT Patroni API endpoint. Can be specified multiple times
or as a list of comma separated addresses. The node
services checks the status of one node, therefore if
several addresses are specified they should point to
different interfaces on the same node. The cluster
services check the status of the cluster, therefore
it's better to give a list of all Patroni node
addresses. [default: http://127.0.0.1:8008]
--cert_file PATH File with the client certificate.
--key_file PATH File with the client key.
--ca_file PATH The CA certificate.
-v, --verbose Increase verbosity -v (info)/-vv (warning)/-vvv
(debug)
--version
--timeout INTEGER Timeout in seconds for the API queries (0 to disable)
[default: 2]
--help Show this message and exit.
Commands:
cluster_config_has_changed Check if the hash of the configuration...
cluster_has_leader Check if the cluster has a leader.
cluster_has_replica Check if the cluster has healthy replicas...
cluster_has_scheduled_action Check if the cluster has a scheduled...
cluster_is_in_maintenance Check if the cluster is in maintenance...
cluster_node_count Count the number of nodes in the cluster.
node_is_alive Check if the node is alive ie patroni is...
node_is_leader Check if the node is a leader node.
node_is_pending_restart Check if the node is in pending restart...
node_is_primary Check if the node is the primary with the...
node_is_replica Check if the node is a running replica...
node_patroni_version Check if the version is equal to the input
node_tl_has_changed Check if the timeline has changed.
Exemple de la sonde cluster_node_count
Pour obtenir de l’aide sur la sonde cluster_node_count
:
check_patroni cluster_node_count --help
Usage: check_patroni cluster_node_count [OPTIONS]
Count the number of nodes in the cluster.
The state refers to the state of PostgreSQL. Possible values are:
* initializing new cluster, initdb failed
* running custom bootstrap script, custom bootstrap failed
* starting, start failed
* restarting, restart failed
* running, streaming (for a replica V3.0.4)
* stopping, stopped, stop failed
* creating replica
* crashed
The role refers to the role of the server in the cluster. Possible values
are:
* master or leader (V3.0.0+)
* replica
* demoted
* promoted
* uninitialized
Check:
* Compares the number of nodes against the normal and healthy (running + streaming) nodes warning and critical thresholds.
* `OK`: If they are not provided.
Perfdata:
* `members`: the member count.
* `healthy_members`: the running and streaming member count.
* all the roles of the nodes in the cluster with their count (start with "role_").
* all the statuses of the nodes in the cluster with their count (start with "state_").
Options:
-w, --warning TEXT Warning threshold for the number of nodes.
-c, --critical TEXT Critical threshold for the number of nodes.
--healthy-warning TEXT Warning threshold for the number of healthy nodes
(running + streaming).
--healthy-critical TEXT Critical threshold for the number of healthy nodes
(running + streaming).
--help Show this message and exit.
Voici un exemple d’utilisation de cette sonde :
check_patroni -e http://10.20.30.51:8008 \
-e http://10.20.30.52:8008 \
-e http://10.20.30.53:8008 \
cluster_node_count
CLUSTERNODECOUNT OK - members is 3 | healthy_members=3 members=3 role_leader=1 role_replica=1 role_sync_standby=1 state_running=1 state_streaming=2
Cette sonde indique que le nombre de nœuds est de 3, tous en bonne santé. Il y a un leader, un réplica synchrone et un réplica asynchrone. Le leader est en statut running, les réplicas sont en statut streaming.
Vous pouvez créer un fichier de configuration pour éviter de saisir les mêmes paramètres à chaque fois. Par défaut, le fichier config.ini du répertoire courant est utilisé. Vous pouvez également spécifier un fichier avec l’option –config. Les options du fichier sont écrasées par celles saisies en ligne de commande.
cat << _EOF_ > config.ini
[options]
endpoints=http://10.20.30.51:8008, http://10.20.30.52:8008, http://10.20.30.53:8008
_EOF_
Seuils
Examinons maintenant la configuration avec une alerte warning si un nœud est perdu et une alerte critical en cas de perte de deux nœuds :
check_patroni -vv cluster_node_count \
--healthy-warning 3: \
--healthy-critical 2:
L’option -vv
permet de séparer les résultats du contrôle et les données de
performance sur deux lignes, améliorant ainsi la lisibilité. L’option -vvv
active le mode de débogage.
On utilise ici les conditions --healthy-warning
et --healthy-critical
. En
effet, les conditions --warning
et --critical
vérifient la présence des
nœuds quel que soit leur statut. Lorsqu’un nœud sort du cluster, Patroni fait le
ménage dans le DCS pour le faire disparaitre, cependant ce n’est pas
instantané. On détectera donc quand même la perte d’un nœud mais pas si un
nœud est marqué par Patroni avec un statut différent de running ou
streaming.
Voici les résultats obtenus :
- avec un cluster intact :
CLUSTERNODECOUNT OK - members is 3 | healthy_members=2;2:;1: members=3 role_leader=1 role_replica=2 state_running=2 state_stopped=1
- en arrêtant un nœud :
CLUSTERNODECOUNT WARNING - healthy_members is 2 (outside range 3:) | healthy_members=2;3:;2: members=2 role_leader=1 role_sync_standby=1 state_running=1 state_streaming=1
- et finalement avec deux nœuds arrêtés :
CLUSTERNODECOUNT CRITICAL - healthy_members is 1 (outside range 2:) | healthy_members=1;3:;2: members=2 role_leader=1 role_replica=1 state_running=1 state_stopped=1
Le formatage du check est spécifié avec la syntaxe [@][start:][end]
:
start
: peut être omis sistart
vaut 0 ;~
: signifie questart
vaut-infini
;- si la
end
est omis, on suppose queend
vaut+infini
; - pour inverser une condition on peut ajouter
@
devant l’expression.
Le fonctionnement de la librairie nagiosplugin est un peu surprenant. La
condition fournie doit décrire une plage de valeur pour laquelle on ne doit pas
déclencher d’erreur, une correspondance est trouvée si on obtient :
start ≤ VALUE ≤ end
.
Si on reprend l’exemple précédent :
--healthy-warning 3:
: on souhaite déclencher un warning quand on perd un nœud, autrement dit, l’état normal pour ce contrôle est d’avoir[3;+INF[
nœuds.--healthy-critical 2:
: on souhaite déclencher un critical quand on perd deux nœuds, autrement dit, l’état normal pour ce contrôle est d’avoir[2;+INF[
nœuds.
La condition peut aussi être inversée :
check_patroni cluster_node_count --healthy-warning @0:2 --healthy-critical @0:1
Fichier d’état
check_patroni peut utiliser un fichier d’état (state file) pour détecter les changements d’état d’un service. Deux services sont concernés :
cluster_config_has_changed
: ce service permet de spécifier un hash explicitement (--hash
) ou de laisser la sonde se débrouiller en utilisant un fichier d’état (--state-file
) ;node_tl_has_changed
: ce service permet de spécifier une timeline explicitement (--timeline
) ou de laisser la sonde se débrouiller en utilisant un fichier d’état (--state-file
).
Exemple d’utilisation de l’option --timeline
du service node_tl_has_changed
:
check_patroni node_tl_has_changed --timeline 7
NODETLHASCHANGED OK - The timeline is still 7. | is_timeline_changed=0;;@1:1 timeline=7
Exemple d’utilisation de l’option --state-file
du service node_tl_has_changed
:
check_patroni node_tl_has_changed --state-file check_patroni.state
NODETLHASCHANGED CRITICAL - The expected timeline was None got 7. | is_timeline_changed=1;;@1:1 timeline=7
Le premier lancement renvoie une erreur. En effet, il n’y a pas d’information dans le fichier d’état. Il faut enregistrer/acquitter le changement pour que l’information soit enregistrée et que l’alerte disparaisse. Ce sera le cas pour tout changement de timeline détecté.
check_patroni node_tl_has_changed --state-file check_patroni.state --save
check_patroni node_tl_has_changed --state-file check_patroni.state
NODETLHASCHANGED CRITICAL - The expected timeline was None got 7. | is_timeline_changed=1;;@1:1 timeline=7
NODETLHASCHANGED OK - The timeline is still 7. | is_timeline_changed=0;;@1:1 timeline=7
La configuration par sonde peut également être ajoutée dans le fichier de configuration :
cat << _EOF_ >> config.ini
[options.node_tl_has_changed]
state_file = check_patroni.state
_EOF_
On peut désormais lancer la sonde sans l’option --state-file
:
check_patroni node_tl_has_changed
NODETLHASCHANGED CRITICAL - The expected timeline was None got 7. | is_timeline_changed=1;;@1:1 timeline=7
Conclusion
check_patroni met à disposition une série de sondes qui permettent de détecter les changements d’état du cluster afin de les remonter dans Icinga ou Nagios. Les données complémentaires (perf data) peuvent être utilisées dans des outils de métrologie pour suivre l’évolution de l’état du cluster dans le temps.
Si vous trouvez des erreurs, ou souhaitez voir des améliorations implémentées dans l’outil ou en implémenter vous-même, n’hésitez pas à venir échanger sur le tracker du projet.
Un grand merci aux contributeurs qui se sont déjà manifestés et aux collègues qui m’ont aidé.
- PostgreSQL (406) ,
- Dalibo (167) ,
- Patroni (16) ,
- sonde (2) ,
- Nagios (8) ,
- Icinga (1) ,
- haute disponibilité (15)