API REST Patroni
Patroni dispose d’une API REST riche, utilisée par Patroni lui-même lors de la course au leader, par l’outil patronictl afin d’effectuer des basculements, des basculements planifiés, des réinitialisations, des redémarrages ou des rechargements, par HAProxy ou tout autre équilibreur de charge pour effectuer des vérifications de santé HTTP, et bien entendu également utilisée pour la surveillance. Ci-dessous figure la liste des points d’accès de l’API REST de Patroni.
Points de terminaison de vérification de santé
Pour toutes les requêtes de vérification de santé GET, Patroni renvoie un document JSON indiquant l’état du nœud, accompagné du code d’état HTTP. Si vous ne souhaitez pas ou n’avez pas besoin du document JSON, vous pouvez envisager d’utiliser la méthode HEAD ou OPTIONS au lieu de GET.
Les requêtes suivantes vers l’API REST de Patroni renvoient le code d’état HTTP 200 uniquement lorsque le nœud Patroni fonctionne en tant que primaire avec verrou de leader :
GET /GET /primaryGET /read-write
GET /standby-leader: renvoie le code d’état HTTP 200 uniquement lorsque le nœud Patroni est en cours d’exécution en tant que leader dans un cluster de secours .GET /leader: renvoie le code d’état HTTP 200 lorsque le nœud Patroni détient le verrou leader. La différence principale avec les deux précédents points d’accès est qu’elle ne tient pas compte de l’état d’exécution de PostgreSQL en tant queprimaryoustandby_leader.GET /replica: point de terminaison de vérification de santé de la réplique. Il renvoie le code d’état HTTP 200 uniquement lorsque le nœud Patroni est dans l’étatrunning, que son rôle estreplicaet que l’étiquettenoloadbalancen’est pas définie.GET /replica?replication_state=<required state>: point de contrôle de réplique. En plus des vérifications effectuées parreplica, il vérifie également que l’état de réplication correspond à celui requis. Principalement utile avecreplication_state=streaming, afin d’exclure les répliques encore en cours de synchronisation pendant une récupération archivée.GET /replica?lag=<max-lag>: point de contrôle de réplique. En plus des vérifications effectuées parreplica, il vérifie également le délai de réplication et renvoie le code d’état 200 uniquement lorsque ce délai est inférieur à la valeur spécifiée. La clé cluster.last_leader_operation provenant du DCS est utilisée pour la position WAL du leader et le calcul du délai sur la réplique, pour des raisons de performance. max-lag peut être spécifié en octets (entier) ou sous forme lisible par l’humain, par exemple 16kB, 64MB, 1GB.GET /replica?lag=1048576GET /replica?lag=1024kBGET /replica?lag=10MBGET /replica?lag=1GB
GET /replica?tag_key1=value1&tag_key2=value2: point de contrôle de réplique. En outre, il vérifie également les balises définies par l’utilisateurkey1etkey2ainsi que leurs valeurs respectives dans la section tags de la configuration YAML. Si une balise n’est pas définie pour une instance, ou si la valeur dans la configuration YAML ne correspond pas à la valeur demandée, le service renvoie le code d’état HTTP 503.
Dans les requêtes suivantes, comme nous vérifions l’état de leader ou de standby-leader, Patroni ne prend pas en compte les étiquettes définies par l’utilisateur, qui seront ignorées.
GET /?tag_key1=value1&tag_key2=value2GET /leader?tag_key1=value1&tag_key2=value2GET /primary?tag_key1=value1&tag_key2=value2GET /read-write?tag_key1=value1&tag_key2=value2GET /standby_leader?tag_key1=value1&tag_key2=value2GET /standby-leader?tag_key1=value1&tag_key2=value2GET /read-only: comme le point d’accès précédent, mais inclut également le primaire.GET /synchronousouGET /sync: renvoie le code d’état HTTP 200 uniquement lorsque le nœud Patroni fonctionne en réplica synchrone.GET /read-only-sync: comme le point d’accès précédent, mais inclut également le primaire.GET /quorum: renvoie le code d’état HTTP 200 uniquement lorsque ce nœud Patroni est répertorié comme nœud de quorum danssynchronous_standby_namessur le primaire.GET /read-only-quorum: comme le point d’accès précédent, mais inclut également le primaire.GET /asynchronousouGET /async: renvoie le code d’état HTTP 200 uniquement lorsque le nœud Patroni fonctionne en réplica asynchrone.GET /asynchronous?lag=<max-lag>ouGET /async?lag=<max-lag>: point de contrôle de basculement asynchrone. En plus des vérifications provenant deasynchronousouasync, il vérifie également le délai de réplication et renvoie le code d’état 200 uniquement lorsque ce délai est inférieur à la valeur spécifiée. La clé cluster.last_leader_operation provenant du DCS est utilisée pour la position WAL du leader et le calcul du délai sur la réplique, pour des raisons de performance. max-lag peut être spécifié en octets (entier) ou sous forme lisible par l’humain, par exemple 16kB, 64MB, 1GB.GET /async?lag=1048576GET /async?lag=1024kBGET /async?lag=10MBGET /async?lag=1GB
GET /health: renvoie le code d’état HTTP 200 uniquement lorsque PostgreSQL est en cours d’exécution.GET /liveness: renvoie le code d’état HTTP 200 si la boucle de battement de cœur Patroni fonctionne correctement, et 503 si la dernière exécution remonte à plus dettlsecondes sur le serveur primaire ou à plus de2*ttlsecondes sur la réplique. Peut être utilisé pourlivenessProbe.GET /readiness?lag=<max-lag>&mode=apply|write: renvoie le code d’état HTTP 200 lorsque le nœud Patroni fonctionne en tant que leader ou lorsque PostgreSQL est actif, en réplication et pas trop en retard par rapport au leader. Le paramètre lag définit la marge maximale de retard autorisée pour une instance de secours, avec une valeur par défaut demaximum_lag_on_failover. Le retard peut être spécifié en octets ou en valeurs lisibles par l’humain, par exemple 16kB, 64MB ou 1GB. Le paramètre mode indique si le WAL doit être appliqué (rejoué) ou simplement reçu (écrit). La valeur par défaut est apply.
Lorsqu’il est utilisé comme Kubernetes readinessProbe, il garantit que les nouveaux pods démarrés ne deviennent prêts qu’après avoir rattrapé le leader. Cela, combiné à un PodDisruptionBudget, protège contre une terminaison prématurée du leader lors d’un redémarrage progressif des nœuds. Il garantit également que les répliques incapables de suivre la réplication ne traitent pas le trafic en lecture seule. Ce point d’accès peut être utilisé pour readinessProbe lorsque l’utilisation des endpoints Kubernetes pour les élections de leader n’est pas possible (OpenShift).
Le point d’entrée liveness est très léger et n’exécute aucune requête SQL. Les sondes doivent être configurées de manière à commencer à échouer environ au moment où la clé leader expire. Avec la valeur par défaut de ttl, qui est 30s, les sondes devraient ressembler à l’exemple suivant :
Point de terminaison de surveillance
Le GET /patroni est utilisé par Patroni lors de la course au leader. Il peut également être utilisé par votre système de surveillance. Le document JSON produit par cette extension a la même structure que le JSON produit par les points d’entrée de vérification de santé.
Exemple : un cluster sain
Exemple : un cluster déverrouillé
Exemple : Un cluster déverrouillé avec le mode de sécurité du DCS activé
Exemple : Un cluster avec le mode pause activé
Récupérez les métriques Patroni au format Prometheus via l’endpoint GET /metrics.
Valeurs d’état PostgreSQL
La métrique patroni_postgres_state fournit une représentation numérique de l’état actuel de l’instance PostgreSQL. Cela est utile pour les systèmes de surveillance et d’alerte qui doivent suivre les changements d’état au fil du temps. Les valeurs numériques sont générées à l’aide de la méthode statique PostgresqlState.get_metrics_description().
| Valeur | Nom d’état | Description |
|---|---|---|
| 0 | initdb | Initialisation du nouveau cluster |
| 1 | initdb_failed | Échec de l’initialisation du nouveau cluster |
| 2 | custom_bootstrap | Exécution du script d’amorçage personnalisé |
| 3 | custom_bootstrap_failed | Échec du script d’amorçage personnalisé |
| 4 | creating_replica | Création d’une réplique à partir du primaire |
| 5 | running | PostgreSQL fonctionne normalement |
| 6 | starting | PostgreSQL démarre |
| 7 | bootstrap_starting | Démarrage après l’amorçage personnalisé |
| 8 | start_failed | Échec du démarrage de PostgreSQL |
| 9 | restarting | PostgreSQL redémarre |
| 10 | restart_failed | Échec du redémarrage de PostgreSQL |
| 11 | stopping | PostgreSQL s’arrête |
| 12 | stopped | PostgreSQL est arrêté |
| 13 | stop_failed | Échec de l’arrêt de PostgreSQL |
| 14 | crashed | PostgreSQL a planté |
Valeurs d’état de PostgreSQL
Ces valeurs numériques sont fixes et ne changeront jamais afin de préserver la compatibilité ascendante avec les systèmes de surveillance existants. Si de nouveaux états sont ajoutés à l’avenir, ils seront affectés à de nouvelles valeurs numériques sans modifier les valeurs existantes.
Points de terminaison d’état du cluster
- L’endpoint
GET /clustergénère un document JSON décrivant la topologie et l’état actuels du cluster :
- Le point d’accès
GET /historyfournit une vue sur l’historique des basculements ou des basculements planifiés du cluster. Le format est très similaire au contenu des fichiers d’historique dans le répertoirepg_wal. La seule différence réside dans le champ horodatage, qui indique quand la nouvelle ligne temporelle a été créée.
Point d’entrée de configuration
GET /config : Obtenir la version actuelle de la configuration dynamique :
PATCH /config : Modifiez la configuration existante.
L’appel d’API REST ci-dessus met à jour la configuration existante et renvoie la configuration mise à jour.
Vérifions que le nœud a bien appliqué cette configuration. Tout d’abord, il doit commencer à imprimer des lignes de journalisation toutes les 5 secondes (loop_wait=5). Le changement de “max_connections” nécessite un redémarrage, donc le drapeau “pending_restart” doit être exposé :
Suppression des paramètres :
Si vous souhaitez supprimer (réinitialiser) un paramètre, appliquez une mise à jour avec null :
L’appel ci-dessus retire postgresql.parameters.max_connections de la configuration dynamique.
PUT /config : Il est également possible d’effectuer la réécriture complète d’une configuration dynamique existante sans condition :
Points de terminaison de basculement planifié et de basculement
basculement planifié
Le point de terminaison /switchover ne fonctionne que lorsque le cluster est sain (un leader est présent). Il permet également de planifier un basculement planifié à une heure donnée.
Lors de l’appel de l’endpoint /switchover, un candidat peut être spécifié mais n’est pas obligatoire, contrairement à l’endpoint /failover. Si aucun candidat n’est fourni, tous les nœuds du cluster éligibles participeront à la course au leader après le départ du leader.
Dans le corps JSON de la requête POST, vous devez spécifier le champ leader. Les champs candidate et scheduled_at sont facultatifs et peuvent être utilisés pour planifier un basculement à une heure précise.
Selon la situation, les requêtes peuvent renvoyer des codes d’état HTTP et des corps différents. Le code d’état 200 est retourné lorsque le basculement planifié ou le basculement s’est terminé avec succès. Si le basculement planifié a été correctement planifié, Patroni renvoie le code d’état HTTP 202. En cas d’erreur, un code d’état d’erreur (l’un des codes 400, 412 ou 503) est retourné, accompagné de détails dans le corps de la réponse.
DELETE /switchover peut être utilisé pour supprimer le basculement planifié actuellement prévu.
Exemple : effectuer un basculement planifié vers une station de secours saine
Exemple : effectuer un basculement planifié vers un nœud spécifique
Exemple : planifier un basculement planifié du leader vers un autre nœud de secours sain du cluster à une heure précise.
basculement
Le point de terminaison /failover peut être utilisé pour effectuer un basculement manuel lorsque aucun nœud sain n’est disponible (par exemple, vers un réplica asynchrone si tous les réplicas synchrones ne sont pas suffisamment sains pour être promus). Toutefois, il n’existe aucune obligation pour un cluster de ne pas avoir de leader : le basculement peut également être exécuté sur un cluster sain.
Dans le corps JSON de la requête POST, vous devez spécifier le champ candidate. Si le champ leader est spécifié, un basculement planifié est déclenché à la place.
Exemple :
[!AVERTISSEMENT]
Faites preuve de prudence lors de l’utilisation de cette API, car cela peut entraîner une perte de données dans certaines situations. Dans la plupart des cas, l’endpoint de basculement planifié répond aux besoins de l’administrateur.
Les points de terminaison POST /switchover et POST /failover sont utilisés par patronictl_switchover
et patronictl_failover
respectivement.
DELETE /switchover est utilisé par patronictl flush cluster-name basculement planifié
.
| Basculer | Basculer planifié | |
|---|---|---|
| Nécessite un leader spécifié | non | oui |
| Nécessite un candidat spécifié | oui | non |
| Peut être exécuté en pause | oui | oui (uniquement vers un candidat spécifique) |
| Peut être planifié | non | oui (si non en pause) |
Comparaison entre basculement et basculement planifié
Standby sain
Plusieurs vérifications doivent être effectuées par un membre d’un cluster afin de pouvoir participer à la course au rôle de leader lors d’un basculement planifié ou de devenir leader en tant que candidat au basculement ou au basculement planifié :
- être accessible via l’API Patroni ;
- ne pas avoir l’étiquette
nofailoverdéfinie surtrue;
- ne pas avoir l’étiquette
- avoir le watchdog entièrement fonctionnel (si requis par la configuration) ;
- en cas de basculement planifié dans un cluster sain ou de basculement automatique, ne pas dépasser le décalage maximal de réplication (
maximum_lag_on_failoverparamètre de configuration ) ;
- en cas de basculement planifié dans un cluster sain ou de basculement automatique, ne pas dépasser le décalage maximal de réplication (
- en cas de basculement planifié dans un cluster sain ou de basculement automatique, ne pas avoir un numéro de timeline inférieur à celui du cluster si
check_timelineparamètre de configuration est défini surtrue;
- en cas de basculement planifié dans un cluster sain ou de basculement automatique, ne pas avoir un numéro de timeline inférieur à celui du cluster si
- en mode synchrone :
- En cas de basculement planifié (avec ou sans candidat) : être inclus dans la liste des membres
/sync;
- En cas de basculement planifié (avec ou sans candidat) : être inclus dans la liste des membres
- En cas de basculement dans des clusters sains ou défaillants, cette vérification est omise.
[!AVERTISSEMENT]
En cas de basculement manuel dans un cluster sans leader, un candidat peut être promu même si : - il n’est pas membre du
/synclorsque le mode synchrone est activé ; - son retard dépasse le retard maximal de réplication autorisé ; - son numéro de timeline est inférieur au dernier numéro de timeline connu du cluster.
Point d’arrêt de redémarrage
POST /restart: Vous pouvez redémarrer Postgres sur le nœud spécifique en effectuant l’appelPOST /restart. Dans le corps JSON de la requêtePOST, il est possible de spécifier de manière optionnelle certaines conditions de redémarrage :- restart_pending : booléen, si défini à
true, Patroni redémarrera PostgreSQL uniquement lorsque le redémarrage est en attente afin d’appliquer certaines modifications de configuration de PostgreSQL. - role : effectuer le redémarrage uniquement si le rôle actuel du nœud correspond au rôle fourni dans la requête POST.
- postgres_version : effectuer le redémarrage uniquement si la version actuelle de PostgreSQL est inférieure à celle spécifiée dans la requête POST.
- timeout : durée d’attente avant que PostgreSQL ne commence à accepter les connexions. Remplace
primary_start_timeout. - schedule : horodatage avec fuseau horaire, planifier le redémarrage à une date future.
- restart_pending : booléen, si défini à
DELETE /restart: supprimer le redémarrage planifié
Les points de terminaison POST /restart et DELETE /restart sont utilisés par patronictl_restart
et patronictl flush cluster-name restart
respectivement.
Point de terminaison de rechargement
L’appel POST /reload ordonne à Patroni de relire et d’appliquer le fichier de configuration. Cela équivaut à envoyer le signal SIGHUP au processus Patroni. Si vous avez modifié certains paramètres de Postgres nécessitant un redémarrage (comme shared_buffers), vous devez toujours effectuer explicitement le redémarrage de Postgres en appelant l’endpoint POST /restart ou à l’aide de patronictl restart
.
Le point de terminaison reload est utilisé par patronictl_reload .
Réinitialiser le point de terminaison
POST /reinitialize : réinitialiser le répertoire de données PostgreSQL sur le nœud spécifié. Cette opération ne peut être exécutée qu’aux répliques. Une fois appelée, elle supprime le répertoire de données et déclenche pg_basebackup ou une autre méthode alternative de création de réplique replica creation method
.
L’appel peut échouer si Patroni est en boucle de récupération (redémarrage) d’une instance Postgres défaillante. Pour contourner ce problème, il est possible de spécifier {"force":true} dans le corps de la requête.
Vous pouvez spécifier {“from-leader”:true} dans le corps de la requête pour obtenir directement un basebackup depuis le nœud leader. Cela est utile lors de l’exécution d’un reinit lorsque tous les nœuds répliques échouent.
Le point de terminaison de réinitialisation est utilisé par patronictl_reinit .