Configuration de check_postgres avec Nagios¶
Introduction¶
Ce document présente la configuration de Nagios pour la supervision de serveurs PostgreSQL en réplication.
Liste des sondes¶
La supervision d’un serveur PostgreSQL passe par la surveillance de sa disponibilité, des indicateurs sur son activité, l’identification des besoins de maintenance, et le suivi de la réplication le cas échéant. Voici les sondes check_postgres à mettre en place sur ces différents aspects.
Disponibilité :
- connection : réalise un test de connexion pour vérifier que le serveur est accessible.
- backends : compte le nombre de connexions au serveur comparé au paramètre max_connections.
Vacuum :
autovac_freeze
: vérifie l’âge des bases de données par rapport au nombre de transactions, cela permet de prédire le déclenchement de l’autovacuum en mode freeze.txn_wraparound
: vérifie si l’âge des bases de données est proche d’une valeur qui provoquerait un bouclage des identifiants de transaction.bloat
: vérifie le volume de données « mortes » et la fragmentation des tables et des index.last_analyze
: vérifie si le dernier analyze (relevé des statistiques relatives aux calculs des plans d’exécution) est trop ancien.last_vacuum
: vérifie si le dernier vacuum (relevé des espaces réutilisables dans les tables) est trop ancien.
Activité :
locks
: vérifie le nombre de verrous ;lockwait
: vérifie l’absence de blocages (en attente de verrous) ;wal_files
: compte le nombre de segments du journal de transaction présents dans le répertoirepg_wal
;query_time
: identifie les requêtes en cours d’exécution depuis trop longtemps.
Configuration :
settings_checksum
: indique si la configuration a été modifiée depuis la dernière vérification.
Réplication :
archive_ready
: compte le nombre de segments du journal de transaction en attente d’archivage.hot_standby_delay
: calcule le délai de réplication entre un primaire et un secondaire.
Principes¶
Pour la supervision de PostgreSQL avec Nagios, le programme utilisé est check_postgres.pl. Il s’agit d’un script Perl qui fournit un ensemble de sondes pour surveiller une instance de PostgreSQL.
Il y a deux possibilités d’utilisation de check_postgres.pl
. On peut soit l’installer sur le serveur PostgreSQL et l’exécuter à travers une connexion SSH, soit l’installer sur la machine hébergeant Nagios, la connexion à PostgreSQL se fait alors par le réseau :
- Dans le premier cas, il faut configurer un accès SSH à la machine pour y exécuter des commandes en mode batch. Il faut pour cela créer une paire de clés SSH sans passphrase pour éviter la demande de mot de passe. Il faut donc disposer d’un client SSH pour le lancement des commandes depuis la machine de supervision.
- Dans le second cas, il faut disposer de Perl et du client PostgreSQL en ligne de commande
psql
sur le serveur nagios, qui est utilisé parcheck_postgres
pour obtenir les informations du serveur PostgreSQL.
check_postgres.pl
doit pouvoir se connecter au serveur PostgreSQL, on doit donc connaître les informations de connexion : nom d’hôte ou adresse IP, port TCP, utilisateur. Le mot de passe est stocké dans le fichier $HOME/.pgpass
de l’utilisateur Unix exécutant check_postgres
. La connexion doit être autorisée par la configuration du fichier $PGDATA/pg_hba.conf
de l’instance. Enfin, une action doit être indiquée à check_postgres
, l’action correspondant à la sonde à exécuter.
Installation et configuration système¶
La dernière version de check_postgres
est à télécharger à cette URL : https://bucardo.org/check_postgres/
Connexion directe¶
Pour lancer check_postgres
depuis la machine de supervision, il faut y installer check_postgres.pl
dans un répertoire accessible par l’utilisateur système qui lance les commandes Nagios, l’idéal étant de le placer dans le répertoire correspondant à la macro $USER1$
. Lancer le programme sans options pour vérifier si des dépendances ne sont pas nécessaires au niveau Perl.
Connexion via SSH¶
Pour lancer check_postgres
à travers une connexion SSH, il faut :
- Créer un utilisateur dédié sur chaque machine PostgreSQL à superviser
- Installer
check_postgres
dans un répertoire accessible par cet utilisateur, il doit être dans lePATH
. - Créer une paire de clés SSH pour l’utilisateur système qui lance les commandes Nagios sur le serveur de supervision, sans passphrase.
- Ajouter la clé publique SSH, contenue dans
$HOME/.ssh/id_rsa.pub
de cet utilisateur dans le fichier$HOME/.ssh/authorized_keys
de l’utilisateur dédié sur chacune des machines PostgreSQL - Tenter la connexion au moins une fois pour accepter la clé SSH de chaque machine (Host key) PostgreSQL
Configuration de PostgreSQL¶
L’accès aux serveurs PostgreSQL pour la supervision doit se faire par l’intermédiaire d’un superutilisateur de l’instance. Ceci est nécessaire pour la réalisation de certaines actions. Dans la procédure qui suit, x.y.z.t
est à remplacer par l’adresse IP de la machine de supervision.
- Recharger la configuration par un « reload » du service
Test de connexion¶
Connexion directe¶
Pour valider le fonctionnement correct de check_postgres
, adapter et lancer la commande suivante depuis la machine de supervision, avec l’utilisateur qui lance les commandes Nagios :
sudo -u nagios_user /chemin/vers/check_postgres.pl --action=connection --host=machine_postgres --port=5432 --dbuser=nagios --perflimit=0 --showtime=0
Un résultat équivalent à celui-ci doit être affiché :
Connexion via SSH¶
Nagios fournit un plugin pour exécuter des commandes par l’intermédiaire de SSH, il s’agit de check_by_ssh
, pour tester la connexion au serveur PostgreSQL comme le ferait Nagios, adapter et lancer la commande suivante :
sudo -u utilisateur_nagios /chemin/vers/check_by_ssh -l utilisateur_distant -H hote_distant -C "check_postgres.pl --action=connection --host=machine_postgresql --port=5432 --dbuser=nagios --perflimit=0 --showtime=0"
Comme l’accès direct, cette commande doit afficher un résultat similaire à :
Configuration de Nagios¶
La configuration de Nagios passe par plusieurs étapes. Il faut d’abord créer les commandes (blocs « command ») pour indiquer comment lancer check_postgres
, puis définir des services correspondants à chacune des sondes à lancer, définir des groupes d’hôtes pour regrouper les sondes PostgreSQL et enfin configurer les hôtes pour leur ajouter ces groupes et les options particulières pour les sondes.
Selon la configuration de Nagios, les fichiers de configuration définis dans les paragraphes suivants doivent être créés dans un répertoire identifié par une directive cfg_dir
où leur chemin doit être déclaré avec des directives cfg_file
dans le fichier de configuration principal (nagios.cfg
).
Pour factoriser une partie de la configuration, Nagios offre la possibilité de définir des variables (ou macro) au niveau des hôtes, utilisables dans les déclaration de services.
Déclaration des commandes¶
Connexion directe¶
define command {
command_name check_postgres_autovac_freeze
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ --action=autovac_freeze $ARG3$
}
define command {
command_name check_postgres_backends
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ --action=backends
}
# Une commande par base
define command {
command_name check_postgres_bloat
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db $ARG3$ --action=bloat $ARG4$
}
define command {
command_name check_postgres_connection
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ --action=connection
}
# donner les listes des bases
define command {
command_name check_postgres_last_analyze
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db $ARG3$ --action=last_analyze $ARG4$
}
# donner les listes des bases
define command {
command_name check_postgres_last_vacuum
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db $ARG3$ --action=last_vacuum $ARG4$
}
# donner les listes des bases
define command {
command_name check_postgres_locks
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db $ARG3$ --action=locks $ARG4$
}
define command {
command_name check_postgres_query_time
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db postgres --action=query_time $ARG3$
}
define command {
command_name check_postgres_settings_checksum
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db postgres --action settings_checksum -w $ARG3$
}
define command {
command_name check_postgres_txn_wraparound
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db postgres --action txn_wraparound
}
define command {
command_name check_postgres_wal_files
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db postgres --action=wal_files $ARG2$
}
define command {
command_name check_postgres_archive_ready
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -p $ARG1$ -u $ARG2$ -db postgres --action=archive_ready -w $ARG2$ -c $ARG3$
}
define command {
command_name check_postgres_hot_standby_delay
command_line $USER1$/check_postgres.pl --language=en --showtime=0 -H $HOSTADDRESS$ -H2 $ARG3$ -p $ARG1$ -p2 $ARG4$ -u $ARG2$ -u2 $ARG5$ -db postgres -db2 postgres --action=hot_standby_delay $ARG6$
}
Connexion via SSH¶
Pour l’utilisation de check_postgres
à travers une connexion SSH, les appels au script sont identiques. Par contre, toutes les lignes de commandes doivent être lancés par le plugin check_by_ssh
fourni par Nagios, selon le patron suivant :
define command {
command_name check_postgres_archive_ready
command_line $USER1$/check_by_ssh -t 60 -l $_HOSTSSH_USER$ -H $HOSTADDRESS$ -p $_HOSTSSH_PORT$ -C "<commande check_postgres.pl>"
}
Déclaration des services¶
Pour chaque commande, un service est déclaré. L’ensemble des services relatifs à la supervision des serveurs PostgreSQL est regroupé dans deux groupes d’hôtes, un groupe pour le serveur maître, le second pour le serveur standby.
Pour faciliter la configuration, un service père est utilisé, dérivé de generic-service, et contient les définitions suivantes :
define service {
name postgresql-service
use generic-service
register 0
max_check_attempts 4
check_interval 5
retry_interval 3
check_period 24x7
notification_interval 0
notification_period 24x7
contacts contacts
contact_groups contact_groups
}
Ensuite, chaque commande est définie de la façon suivante :
define service {
use postgresql-service
service_description PGSQL - Autovacuum freeze
hostgroup_name postgresql-servers
check_command check_postgres_autovac_freeze!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_FREEZE$
}
define service {
use postgresql-service
service_description PGSQL - Connections
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_backends!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$
}
define service {
use postgresql-service
service_description PGSQL - Connection check
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_connection!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$
}
define service {
use postgresql-service
service_description PGSQL - Last analyze
hostgroup_name postgresql-servers
check_command check_postgres_last_analyze!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_DBNAMES$!$_HOSTOPTIONS_LASTANALYZE$
}
define service {
use postgresql-service
service_description PGSQL - Last vacuum
hostgroup_name postgresql-servers
check_command check_postgres_last_vacuum!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_DBNAMES$!$_HOSTOPTIONS_LASTVACUUM$
}
define service {
use postgresql-service
service_description PGSQL - Locks
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_locks!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_DBNAMES$!$_HOSTOPTIONS_LOCKS$
}
define service {
use postgresql-service
service_description PGSQL - Query time
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_query_time!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_QUERYTIME
}
define service {
use postgresql-service
service_description PGSQL - Settings checksum
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_settings_checksum!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTCONFIG_CHECKSUM
}
define service {
use postgresql-service
service_description PGSQL - Transaction wraparound
hostgroup_name postgresql-servers
check_command check_postgres_txn_wraparound!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$
}
define service {
use postgresql-service
service_description PGSQL - WAL files
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_wal_files!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_WALFILES$
}
define service {
use postgresql-service
service_description PGSQL - Archive ready
hostgroup_name postgresql-servers
check_command check_postgres_archive_ready!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_ARCHIVEREADY$
}
define service {
use postgresql-service
service_description PGSQL - Hot standby delay
hostgroup_name postgresql-servers
check_command check_postgres_hot_standby_delay!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!$_HOSTOPTIONS_STANDBYHOST$!$_HOSTOPTIONS_STANDBYPORT$!$_HOSTOPTIONS_STANDBYUSER$!$_HOSTOPTIONS_STANDBY$
}
Déclaration des groupes d’hôtes¶
Les services définis précédemment sont liés à des groupes d’hôtes, postgresql-servers
et postgresql-servers-standby
, il faut les déclarer de la façon suivante :
define hostgroup {
hostgroup_name postgresql-servers
alias Serveurs PostgreSQL
}
define hostgroup {
hostgroup_name postgresql-servers-standby
alias Serveurs PostgreSQL Standby
}
Configuration des hôtes¶
Pour la configuration des hôtes, il faut les positionner dans le bon groupe selon leur rôle dans la réplication : postgresql-servers
pour le primaire, et postgresql-servers-standby
pour le secondaire.
Les services étant génériques, il faut déclarer l’ensemble des variables au niveau de l’hôte : la variable doit être préfixée par un underscore (ce qui permet d’éviter les conflits de nommage avec le reste de la configuration) sachant que Nagios intercale le mot HOST
après cet underscore dans l’utilisation pour les commandes et services, par exemple _OPTIONS_PGPORT
devient $_HOSTOPTIONS_PGPORT$
Parmi les sondes définies, les variables suivantes sont à déclarer au niveau des hôtes :
_OPTIONS_PGPORT 5432 ; ou un port alternatif
_OPTIONS_PGUSER nagios ; ou un autre utilisateur PostgreSQL pour la connexion
_OPTIONS_DBNAMES base1,base2 ; la liste des bases de données pour certains test
_SSH_USER nagios ; utilisateur pour l'accès SSH, le cas échéant
_SSH_PORT 22 ; port TCP du serveur SSH, le cas échéant
* txn_wraparound : aucune option supplémentaire n'est nécessaire
- Activité :
- Configuration :
- Réplication :
_OPTIONS_STANDBYHOST ip_esclave
_OPTIONS_STANDBYPORT port_esclave
_OPTIONS_STANDBYUSER user_esclave
_OPTIONS_STANDBY -w 700000 -c 1000000
Le bloat (fragmentation des tables) est à configurer séparemment car la sonde ne fait le calcul que sur une base donnée en paramètre. On définit donc un service par base :
define service {
use postgresql-service
service_description PGSQL - Tables and indexes bloat
hostgroup_name postgresql-servers,postgresql-servers-standby
check_command check_postgres_bloat!$_HOSTOPTIONS_PGPORT$!$_HOSTOPTIONS_PGUSER$!base!$_HOSTOPTIONS_BLOAT$
}
Conclusion¶
La configuration de Nagios peut être un travail fastidieux, principalement à cause de la nécessité d’ajuster les seuils selon le fonctionnement de l’application en production, qui n’est pas encore connu.