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 de terminaison 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. Contrairement àGET /primaryet àGET /standby-leader, cette vérification ne dépend pas du fait que PostgreSQL s’exécute 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 rattrapage lors d’une récupération depuis les archives. -
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 retard de réplication et renvoie le code d’état 200 uniquement lorsque ce retard 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 retard 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 étiquettes définies par l’utilisateurkey1etkey2ainsi que leurs valeurs respectives dans la section tags de la configuration YAML. Si une étiquette n’est pas définie pour une instance, ou si la valeur dans la configuration YAML ne correspond pas à la valeur demandée, le code d’état HTTP 503 est renvoyé.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=value2
-
GET /read-only: comme le point de terminaison 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éplique synchrone. -
GET /read-only-sync: comme le point de terminaison 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 de terminaison 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éplique asynchrone. -
GET /asynchronous?lag=<max-lag>ouGET /async?lag=<max-lag>: point de contrôle de réplique asynchrone. En plus des vérifications effectuées parasynchronousouasync, il vérifie également le retard de réplication et renvoie le code d’état 200 uniquement lorsque ce retard 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 retard 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 le retard maximal autorisé pour une réplique, 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 rejoué (apply) ou simplement reçu (write). 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 de terminaison peut être utilisé pour readinessProbe lorsque l’utilisation des endpoints Kubernetes pour les élections de leader n’est pas possible (OpenShift).
Le point de terminaison liveness est très léger et n’exécute aucune requête SQL. Les sondes devraient ê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 ce point de terminaison a la même structure que le JSON produit par les points de terminaison de vérification de santé.
Exemple : un cluster sain
Exemple : un cluster déverrouillé
Exemple : Un cluster déverrouillé avec le mode failsafe du DCS activé
Exemple : Un cluster avec le mode pause activé
Récupérez les métriques Patroni au format Prometheus via le point de terminaison 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 rétrocompatibilité 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
- Le point de terminaison
GET /clustergénère un document JSON décrivant la topologie et l’état actuels du cluster :
- Le point de terminaison
GET /historyfournit une vue sur l’historique des basculements planifiés ou des basculements 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 timeline a été créée.
Point de terminaison 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 devrait commencer à afficher des lignes de journal toutes les 5 secondes (loop_wait=5). Le changement de “max_connections” nécessite un redémarrage, donc le drapeau “pending_restart” devrait être affiché :
Suppression des paramètres :
Si vous souhaitez supprimer (réinitialiser) un paramètre, il suffit d’envoyer un PATCH avec la valeur 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 de manière inconditionnelle :
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 l’exécution d’un basculement planifié à une heure donnée.
Lors de l’appel du point de terminaison /switchover, un candidat peut être spécifié mais n’est pas obligatoire, contrairement au point de terminaison /failover. Si aucun candidat n’est fourni, tous les nœuds éligibles du cluster participeront à la course au leader après la rétrogradation 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 l’exécution d’un basculement planifié à 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 n’importe quelle réplique saine
Exemple : effectuer un basculement planifié vers un nœud spécifique
Exemple : planifier un basculement planifié du leader vers n’importe quelle autre réplique saine 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 une réplique asynchrone si toutes les répliques 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 :
Soyez très prudent lors de l’utilisation de ce point de terminaison, car cela peut entraîner une perte de données dans certaines situations. Dans la plupart des cas, le point de terminaison 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 switchover
.
| Basculement | Basculement 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é
Réplique de secours saine
Un membre d’un cluster devrait satisfaire plusieurs critères 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; - 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 retard 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 avoir un numéro de timeline inférieur à celui du cluster si
check_timelineparamètre de configuration est défini surtrue; - en mode synchrone
:
- En cas de basculement planifié (avec ou sans candidat) : être listé parmi les membres de la clé
/sync; - En cas de basculement dans des clusters sains ou défaillants, cette vérification est omise.
- En cas de basculement planifié (avec ou sans candidat) : être listé parmi les membres de la clé
En cas de basculement manuel dans un cluster sans leader, un candidat sera autorisé à être promu même si :
- il ne figure pas parmi les membres de la clé
/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 de terminaison 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 le point de terminaison POST /restart ou à l’aide de patronictl_restart
.
Le point de terminaison de rechargement est utilisé par patronictl_reload .
Point de terminaison de réinitialisation
POST /reinitialize : réinitialiser le répertoire de données PostgreSQL sur le nœud spécifié. Cette opération n’est autorisée que sur les répliques. Une fois appelée, elle supprime le répertoire de données et démarre pg_basebackup ou une autre méthode de création de réplique
.
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 .