Chapitre 41. Supervision distribuée

Introduction

Nagios peut être configuré pour supporter la supervision distribuée des services et ressources du réseau. Je vais essayer d'expliquer brièvement comment cela peut être fait…

Buts

Le but de l'environnement de supervision distribuéé que je vais décrire est de décharger l'excès de charge induit par les contrôle de services (sur la CPU, etc.) du serveur central sur un ou plusieurs serveurs distribués. La plupart des petites et moyennes entreprises n'auront pas réellement besoin de mettre en œuvre cet environnement. Cependant, quand vous voulez superviser des centaines, voire des milliers d'hôtes (et plusieurs fois cette valeur en termes de services) à l'aide de Nagios, cela commence à devenir important.

Diagramme de référence

Le diagramme ci-dessous devrait vous aider à vous faire une idée du fonctionnement de la supervision distribuée avec Nagios. Je ferai référence aux éléments du diagramme quand j'expliquerai les choses…

Distributed

Serveur central ou serveurs distribués

Quand on installe l'environnement de supervision distribuée avec Nagios, il y a des différences entre la configuration du serveur central et celle des serveurs distribués. Je vous montrerai comment configurer ces deux types de serveurs et j'expliquerai les effets des changements sur la supervision en général. A l'intention des débutants, décrivons d'abord l'utilité des différents serveurs…

Le rôle d'un serveur distribué est de contrôler tous les services définis pour une grappe [cluster] d'hôtes. J'utilise ce terme grappe de manière inappropriée : il désigne simplement un groupe d'hôtes de votre réseau. Selon la topographie de votre réseau, vous pouvez avoir plusieurs grappes en un seul lieu, ou chaque grappe peut être séparée par un WAN, un pare-feu, etc. Il faut surtout se souvenir d'une chose, c'est que pour chaque groupe d'hôtes (de quelque manière que vous le définissiez), il y a un serveur distribué sur lequel Nagios tourne et qui supervise les services des hôtes du cluster. Un serveur réparti est généralement une installation simplifiée de Nagios. Il n'est pas besoin d'installer l'interface web, d'envoyer des notifications, de faire tourner les scripts de gestionnaires d'événements ou de faire autre chose que l'exécution des contrôles de service si vous ne le souhaitez pas. De plus amples explications relatives à la configuration du serveur distribué suivront…

Le but du serveur central est d'écouter simplement les résultats des contrôles de service d'un ou de plusieurs serveurs distribués. Même si les services sont occasionnellement contrôlés activement par le serveur central, les contrôles actifs sont seulement exécutés dans des circonstances particulières ; disons donc pour l'instant que le serveur central n'accepte que les contrôles passifs. Comme le serveur central obtient des résultats des contrôles de services passifs d'un ou plusieurs serveurs répartis, il est utilisé comme point central pour la logique de supervision (ex: il envoie des notifications, exécute les scripts de gestionnaires d'événements, détermine l'état des hôtes, son interface web est installée, etc.).

Obtention des informations de contrôle de service à partir de serveurs distribués

Avant de sauter à pieds joints dans les détails de la configuration, il faut savoir comment envoyer les résultats des contrôles de service des serveurs distribués au serveur central. J'ai déjà expliqué comment soumettre des résultats de contrôles passifs à Nagios à partir de la machine même sur laquelle Nagios tourne (cf. documentation sur les contrôles passifs), mais je n'ai pas fourni d'information sur la manière d'envoyer des résultats de contrôles de service à partir d'autres hôtes.

Afin de faciliter l'envoi de résultats de contrôles passifs à un hôte distant, j'ai écrit le module complémentaire NSCA . Il contient deux parties. La première est un programme client (send_nsca) qui tourne sur un hôte distant et envoi les résultats de contrôles de service à un autre serveur. La seconde est le démon NSCA (nsca) qui fonctionne, soit comme un démon autonome, soit sous inetd, et écoute les connections des programmes du client. Après avoir reçu l'information de contrôle de service de la part d'un client, le démon enverra l'information de contrôle à Nagios (sur le serveur central) en insérant une commande PROCESS_SVC_CHECK_RESULT dans le fichier de commande externe, avec les résultats du contrôle. La prochaine fois que Nagios contrôlera les commandes externes, il trouvera l'information de contrôle de service passif qui avait été envoyée par le serveur distribué et la traitera. Facile, non ?

Configuration des serveurs distribués

Bon, comment Nagios est-il configuré sur un serveur distribué ? A la base, c'est juste une simple installation. Il n'est pas nécessaire d'installer l'interface web ou de faire envoyer des notifications par le serveur, comme c'est le cas pour le serveur central.

Changements principaux dans la configuration :

Afin que tout fonctionne ensemble de manière correcte, nous voulons que le serveur distribué renvoie les résultats de tous les contrôles de service à Nagios. Nous pourrions utiliser les gestionnaires d'événements pour envoyer les changements de l'état d'un service, mais cela ne fait pas l'affaire. Afin d'obliger le serveur distribué à envoyer tous les résultats des contrôles de service, il faut autoriser l'option de remontée de contrôle de service dans le fichier de configuration principal et permettre qu'une commande ocsp soit lancée après chaque contrôle de service. Nous utiliserons cette commande ocsp pour envoyer les résultats de tous les contrôles de service au serveur central, en utilisant le client send_nsca et le démon nsca (comme décrit ci-dessus) pour gérer la transmission.

Pour mener tout cela à bien, il faut définir la commande ocsp de cette façon :

ocsp_command=submit_check_result

La définition de la commande submit_check_result ressemble à ceci :

define command {
    command_name    submit_check_result
    command_line    /usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$'
}
        

Le script shell submit_check_result ressemble à cela (remplacez central_server par l'adresse IP du serveur central) :

#!/bin/sh

# Arguments:
#   $1 = host_name (Short name of host that the service is
#        associated with)
#   $2 = svc_description (Description of the service)
#   $3 = state_string (A string representing the status of
#        the given service - "OK", "WARNING", "CRITICAL"
#        or "UNKNOWN")
#   $4 = plugin_output (A text string that should be used
#        as the plugin output for the service checks)
#

# Convert the state string to the corresponding return code
return_code=-1

case "$3" in
    OK)
        return_code=0
        ;;
    WARNING)
        return_code=1
        ;;
    CRITICAL)
        return_code=2
        ;;
    UNKNOWN)
        return_code=-1
        ;;
esac

# pipe the service check info into the send_nsca program, which
# in turn transmits the data to the nsca daemon on the central
# monitoring server

/bin/printf "%s\t%s\t%s\t%s\n" "$1" "$2" "$return_code" "$4" | /usr/local/nagios/bin/send_nsca -H central_server -c /usr/local/nagios/etc/send_nsca.cfg
        

Le script ci-dessus suppose que vous avez le programme send_nsca et son fichier de configuration (send_nsca.cfg) placés respectivement dans les répertoires /usr/local/nagios/bin/ et /usr/local/nagios/etc/.

C'est tout ! Nous venons de configurer avec succès un hôte distant sur lequel tourne Nagios pour agir comme un serveur de supervision distribué. Voyons maintenant ce qui se passe exactement avec le serveur distribué et comment il envoie des résultats de contrôle de service à Nagios (les étapes soulignées ci-dessous correspondent aux numéros du schéma de référence ci-dessus) :

  1. Après que le serveur distribué a terminé l'exécution d'un contrôle de service, il exécute la commande définie par la variable ocsp_command . Dans notre exemple, c'est le script /usr/local/nagios/libexec/eventhandlers/submit_check_result. Remarquez que la définition de la commande submit_check_result a envoyé quatre éléments d'information au script : le nom de l'hôte auquel le service est associé, la description du service, le code de retour du contrôle de service, et la sortie du plugin de contrôle du service.

  2. Le script submit_check_result envoie dans un tube [pipe] l'information du contrôle de service (nom de l'hôte, description, code de retour et sortie) au programme client send_nsca.

  3. Le programme send_nsca transmet l'information de contrôle de service au démon nsca qui se trouve sur le serveur de supervision central.

  4. Le démon nsca du serveur central prend l'information de contrôle de service et l'écrit dans le fichier de commande externe pour qu'elle soit reprise ultérieurement par Nagios.

  5. Le processus Nagios du serveur central lit le fichier de commande externe et analyse l'information de contrôle de service provenant du serveur de supervision distribué.

Configuration du serveur central

Nous avons vu comment les serveurs de supervision distribués doivent être configurés, occupons nous maintenant du serveur central. Pour accomplir toutes ses missions, il est configuré de la même manière que vous configureriez un serveur seul. Il est installé de la manière suivante :

Il y a trois autres éléments importants que vous devez conserver à l'esprit en configurant le serveur central :

  • Tous les services qui sont supervisés par les serveurs distribués doivent comporter des définitions de service sur le serveur central. Nagios ignorera les résultats des contrôles de service passifs s'ils ne correspondent pas à un service qui a été défini.

  • Si vous n'utilisez le serveur central que pour traiter des services dont les résultats sont fournis par des hôtes distribués, vous pouvez simplement désactiver tous les contrôles de service de façon globale en mettant le paramètre execute_service_checks à 0. Si vous utilisez le serveur central pour superviser activement quelques services par lui-même (sans l'intervention des serveurs distribués), l'option enable_active_checks de chaque définition de service pour les services dont les résultats sont fournis par les hôtes distribués doit être positionnée à 0. Ceci empêchera Nagios de vérifier activement ces services.

Il est important que vous désactiviez soit tous les contrôles de service pour l'ensemble du logiciel, soit l'option enable_active_checks dans la définition de tout service surveillé par un serveur distribué. Cela assure que les contrôles de service actifs ne sont jamais exécutés en temps normal. Les services continueront à être ordonnancés à leur intervalle de contrôle normal (3 minutes, 5 minutes, etc…), mais ils ne seront jamais exécutés. Cette boucle de ré-ordonnancement continuera aussi longtemps que Nagios tourne. Je vais expliquer bientôt pourquoi ce type de fonctionnement…

Et voilà ! Facile, non ?

Problèmes avec les contrôles passifs

Pour toutes les utilisations intensives, nous pouvons dire que le serveur central s'appuie uniquement sur les contrôles passifs pour la supervision. Faire totalement confiance aux contrôles passifs pour superviser pose un problème majeur : Nagios doit se fier à quelque chose d'autre pour fournir les données supervisées. Que se passe-t-il si l'hôte distant qui envoie les résultats s'effondre ou devient injoignable ? Si Nagios ne contrôle pas activement les services de cet hôte, comment saura-t-il qu'il y a un problème ?

Heureusement, il y a une façon de gérer ces types de problèmes…

Le contrôle de validité des données

Nagios offre une fonctionnalité qui teste la validité des résultats d'un test (freshness checking). On peut trouver plus d'informations à ce sujet ici. Cette fonctionnalité apporte une solution aux situations ou les hôtes distants peuvent arrêter d'envoyer le résultat des tests passifs au serveur central. Elle (freshness) permet d'assurer que le test est soit fourni passivement par les serveurs distribués, soit exécuté activement par le serveur central si nécessaire. Si les résultats fournis par le test du service deviennent figés, Nagios peut être configuré pour forcer un contrôle actif depuis le serveur central.

Comment fait-on cela ? Sur le serveur central, il faut configurer ainsi les services qui sont surveillés par les serveurs distribués :

  • L'option check_freshness dans la définition des services doit être à 1. Ceci active le test de validité (freshness checking)

  • L'option freshness_threshold dans la définition des services doit être positionné à une valeur qui indique le niveau de validité ([NdT] : la traduction littérale est la fraîcheur, mais il ne me semble pas adapté) des données (telles que fournies par les serveurs distribués).

  • L'option check_command dans la définition des services doit indiquer les commandes valides qui seront employées pour tester activement les services depuis le serveur central.

Nagios teste régulièrement la validité des résultats pour lesquels cette option est activée. L'option freshness_threshold dans chaque service détermine le niveau de validité pour celui-ci. Par exemple, si sa valeur est 300 pour un de vos services, Nagios va considérer que les résultats du service sont figés s'ils ont plus de 5 minutes (300 secondes). Si vous ne spécifiez pas la valeur de freshness_threshold, Nagios calculera un seuil à partir de la valeur des options normal_check_interval ou de retry_check_interval (en fonction de l'état du service). Si les résultats sont figés, Nagios exécutera la commande spécifiée dans check_command dans la définition du service, vérifiant ainsi activement ce service.

N'oubliez pas que vous devez définir l'option check_command dans la définition des services, pour pouvoir tester activement l'état d'un service depuis le serveur central. Dans des conditions normales, cette commande check_command ne sera pas exécutée (parce que les test actifs auront été désactivés globalement au niveau du programme, ou pour des services spécifiques). A partir du moment ou le contrôle de validité des données est activé, Nagios exécutera cette commande, même si les tests actifs ont été désactivés globalement au niveau du programme ou pour des services spécifiques.

Si nous n'arrivez pas à définir des commandes pour tester activement un service depuis le serveur central (ou bien cela est un casse-tête douloureux), vous pouvez simplement définir toutes les options check_command d'après un simple script qui retourne un état critique. Voici un exemple : supposons que vous ayez défini une commande service-fige et utilisez cette commande dans l'option check_command de vos services. Elle pourrait ressembler à cela …..

define command {
    command_name    service-fige
    command_line    /usr/local/nagios/libexec/check_dummy 2 "CRITICAL: Service results are stale"
}
        

Quand Nagios détecte que les résultats sont figés et lance la commande service_fige, le plugin check_dummy est exécuté et le service passe dans un état critique. Ceci déclenchera l'envoi de notifications, donc vous saurez finalement qu'il y a un problème.

Contrôles des hôtes

Maintenant, vous savez comment obtenir des résultats de contrôles passifs depuis des serveurs distribués. Ceci signifie que le serveur central ne teste activement que ses propres services. Mais qu'en est-il des hôtes ? Vous en avez toujours besoin, non ?

Comme les contrôles d'hôtes n'ont qu'un impact faible sur la surveillance (ils ne sont faits que s'ils sont vraiment nécessaires), je vous recommanderais bien de faire ces contrôles de manière active depuis le serveur central. Ceci signifie que vous définirez le contrôle des hôtes sur le serveur central de la même manière que vous l'avez fait sur les serveurs distribués (également de la même manière que sur un serveur normal, non distribué).

Les résultats de contrôle passifs des hôtes sont disponible (lisez ceci), donc vous pourriez les utiliser dans votre architecture distribuée mais cette méthode comporte certains problèmes. Le principal étant que Nagios ne traduit pas les états problèmes (arrêtés DOWN ou injoignables UNREACHABLE) retournés par les vérifications passives des hôtes quand ils sont traités. Par conséquent, si vos serveurs de supervision ont une structure différentes en terme de parents ou enfants (et c'est ce qui se passe lorsque vos serveurs de supervisions ne sont pas exactement au même endroit), le serveur central va avoir une vision incorrecte des états des hôtes.

Si vous voulez vraiment envoyer des résultats passifs de contrôle d'hôte à un serveur de supervision central, vérifiez que :

La commande ochp utilisée pour le traitement des vérifications d'hôtes fonctionne de manière similaire à la commande ocsp utilisée pour le traitement des vérification des services (cf documentation ci-dessus). Pour être sûr que les vérifications passives d'hôtes sont valides et à jour, il est nécessaire d'activer la validité des vérification pour les hôtes de la même manière que pour les services.