La supervision du pauvre

Nagios est un formidable outil permettant de gérer d'immenses parcs de machine, d'afficher des plans d'architecture, des rapports d'erreurs, etc. Maintenant lorsque l'on a dans son "parc" personnel deux pauvres serveurs qui se battent en duel, passer des heures à paramétrer et maintenir un tel système n'est pas forcement rentable. Maintenant refaire soi-même à la main toute cette mécanique ne l'est pas non plus, voici donc une voie du milieu.

L'idée de base

Comme nous l'avons déjà vu, Nagios est un système de supervision évolué, doté d'une interface WEB, d'une très dense bibliothèque de greffons, d'une base de donnée et de tout le tremblement. Cependant la mise en œuvre et le paramétrage du zinzin, sans être inaccessible peut demande un peu de temps et d'énergie. Et lorsque l'on n'a qu'une poignée de machine, on peut légitiment se demander s'il est pas possible de détourner ces greffons pour un usage un peu plus "simpliste".

Prenons l'exemple du greffon qui fait "ping" (c'est le greffon le plus dispendieux de l'établissement !) qui se trouve dans le dossier /usr/lib64/nagios/plugins (ou /usr/lib/nagios/plugins pour les distributions 32bits) sous le nom check_ping. Nous constatons déjà que c'est un exécutable. Cela ne coûte rien de le lancer, pour voir :

gaston$file /usr/lib64/nagios/plugins/check_ping
/usr/lib64/nagios/plugins/check_ping: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
gaston$/usr/lib64/nagios/plugins/check_ping
check_ping: Impossible de décomposer les arguments
Utilisation:check_ping -H <host_address> -w <wrta>,<wpl>% -c <crta>,<cpl>%
[-p packets] [-t timeout] [-4|-6]

Voilà qui est intéressant. Non seulement c'est un exécutable, mais c'est surtout une commande comme n'importe quelle autre commande GNU/Linux. Essayons donc avec des paramètres adéquats :

gaston$/usr/lib64/nagios/plugins/check_ping -w 3000.0,80% -c 5000.0,100% -p 1 -H 127.0.0.1
PING OK - Paquets perdus = 0%, RTA = 21.74 ms|rta=21.743999ms;3000.000000;5000.000000;0.000000 pl=0%;80;100;0
root#echo $?
0
root#/usr/lib64/nagios/plugins/check_ping -w 3000.0,80% -c 5000.0,100% -p 1 -H badhost
CRITIQUE - Hôte inaccessible (lug)
root#echo $?
2

Sur la sortie standard est envoyé divers informations sur le déroulement de l'exécution. La ligne comporte une petite section précédant le signe - qui indique le nom du test, PING, et le status OK, AVERTISSEMNT ou CRITIQUE. Après nous avons des indications sur ce qui c'est passé jusqu'au signe |, puis ce sont des mesures permettant d'évaluer les performances du test.

Mais au fond ce qui nous intéresse vraiment c'est le code d'erreur. 0 si tout va bien, et différent de 0 dans le cas contraire.

Sachant que tous les greffons se comportent exactement de la même manière, que dans la majorité des cas les appeler avec -h en paramètre nous en donne la syntaxe, et que le cas échéant nous avons le fichier commands.cfg pour s'aider, pourquoi ne pas écrire un petit programme tout bête dont le seule rôle sera d'encapsuler le lancement de ces plugins et d'écrire dans la sortie standard en cas d'erreur. Un petit script en Bash tout simple qui une fois collé dans un CRON nous préviendra naturellement par courriel dés que quelque chose se sera mal passé.

A tout fin utile je rappelle que le sujet est ici de faire des choses simples, fiable et efficaces. Évidemment un nagios habillé de pied en cap ferait parfaitement le job, mais avec beaucoup plus de sueur et de maintenance pour une architecture bien trop modeste pour de tels efforts.

Exploitation de SSH

Le script de supervision va tourner sur la machine allumée en permanence (mon Via C7). Les tests vont porter sur cette machine, mais aussi sur d'autres machines du réseau. Pour simplifier le débat, un peu comme pour GIT, ma couche de transport est un tunnel SSH et une validation entre les comptes root de chaque machines. Ceci vaut aussi pour la machine qui exécute le script (rien n'interdit en effet de s'auto-connecter à soi-même en SSH). Ainsi nous avons quelque chose de vraiment simple à mettre en oeuvre.

Pour préparer les machines à cet usage, il conviendra donc de permettre à la machine qui exécute le script une connexion SSH sans mot de passe vers toutes les machines que vous devez tester, y compris elle-même.

Le script

Nous allons donc réaliser notre supervision en simple Bash. Pour cela, armez vous de gedit et c'est parti...

Comme pour notre Sauvegarde du pauvre, le script sera articulé autours d'un minimum de fonction (une seule en réalité) et servira aussi de configuration.

La première chose à ajouter à notre check.sh est l'en-tête classique bash et la remise à vide d'un fichier dans lequel nous stockerons les erreurs rencontrées. Nous aurions pu écrire directement dans la sortie standard mais le problème avec Bash, c'est qu'un retour de fonction se fait aussi dans la sortie standard.

#! /bin/bash

# vidange des erreurs du précédent round
> /var/log/check.log
Début du script check.sh

La première fonction de notre système s'appelle is_alive. Elle va prendre en paramètre le nom d'une machine, faire un ping dessus et renvoyer 0 si la machine répond et 1 dans le cas contraire. Si la machine ne répond pas, ce sera considéré comme une erreur consignée dans les logs. Enfin le nom de la machine sera stocké dans une variable globale $host_name et être utilisé par la suite pour nos tests via SSH.

is_alive() {
export host_name=$1;

# on vérifie que le host est bien UP
ping -c 1 $host_name > /dev/null 2>&1
return $(state Alive $?)
}
la fonction state

Comme vous le voyez, le retour de la fonction is_alive est géré par la fonction state. Cette fonction prend en argument un libellé (ici Alive, un état de retour d'un autre fonction (ici celui de la fonction ping), et enfin un message (ici non utilisé). Le seul rôle de la fonction state est de vérifier si le 2nd paramètre est différent de 0, ce qui correspond à une erreur, et consigner en conséquence le message d'erreur.

state() {
label=$1; shift
state=$1; shift
message=$*

if [ $state -ne 0 ] ; then
echo "Échec du test '$label' sur $host_name: $message" >> /var/tmp/errors
fi

return $state  
}
la fonction state

Notez ici l'usage de la variable $host_name qui a été initialisée par is_alive avec la machine qui a reçu la tentative de ping.

Dernière fonction, et non des moindres, celle qui va effectivement lancer utilise un greffon Nagion à distance via SSH sur la machine $host_name. Cette fonction prendra en premier paramètre un libellé, en second la partie se trouvant après le _ d'un greffon nagios, et injectera le reste de ses arguments au dit greffon.

check() {
label=$1 ; shift
data=$(ssh $host_name "export PATH=\\$PATH:/usr/lib64/nagios/plugins:/usr/lib64/nagios/plugins/contrib:/usr/lib/nagios/plugins:/usr/lib/nagios/plugins/contrib; check_$* 2>/dev/null")
return $(state "$label" "$?" "$data")
}
la fonction check

Rien de compliqué dans cette fonction qui exploite pleinement le tunnel SSH pour redéfinir un chemin d'accès aux commandes permettant de retrouver les greffons sur la machine distante, et l'exécution du greffon avec la paramètres fournis.

Voilà, c'est terminé pour l'essentiel. Voyons maintenant comment mettre cela en musique.

is_alive machine_1 && {
check 'Charge'   load -w 5.0,4.0,3.0 -c 10.0,6.0,4.0
check 'Process'  procs -w 250 -c 400 -s RSZDT
check 'Zombies'  procs -w 5 -c 10 -s Z
}      
is_alive machine_2 && {
check 'Espace disque' disk -w 10% -c 5% -p /var -p /tmp -p -p /home -p /
check 'SMTP'          smtp -H smtp.mondomaine.fr
check 'Postgresql'    pgsql -d ma_base -l postgres
}      

cat /var/log/check.log
application des fonctions

Sympa non ? Nous utilisons ici une bien pratique syntaxe de Bash qui conditionne tout ce qui se trouve dans l'accolade à la réussite de la commande qui prècéde le &&. Une fois que tout est terminé, il ne reste qu'à vider le fichier /var/log/check.log dans la sortie standard. Ainsi, lorsque vous connecterez ce script à votre CRONTAB, le démon CRON voyant quelque chose d'écrit, se fera un plaisir de vous en prévenir par courriel.

Conclusion

Même si "supervision du pauvre" porte ici bien son nom, cela reste une approche pragmatique et très rentable car utilisant à plein tous les greffons de Nagios. On ne ré-invente pas la roue mais on lui permet d'être un peu plus carré en fonction de nos besoins. Le script peut ainsi être énormement adaptés d'un usage à l'autre. Dans mon cas, j'ai un peu dopé la fonction state de sorte à générer en plus de logs, une page HTML ultra basique (cf copie d'écran ci-contre) adaptée à la lecture sur mon smartphone. Avec un CRON qui se lance tous les 1/4 d'heure, je peux ainsi voir d'un coup d'oeil, et à distance, l'état de mes systèmes. Cela me permet aussi de voir lorsque des machines inutiles sont restées allumé pour rien.

Vus : 1931
Publié par Artisan Numérique : 100