Parallélisation des contrôles de service


Introduction

Une des fonctionnalités de Nagios est la possibilité d'effectuer des contrôles de service en parallèle. Cette documentation essaiera d'expliquer en détail ce que cela signifie et quel est son impact sur les services que vous avez définis.

Comment fonctionne la parallélisation

Avant que je n'explique comment fonctionne la parallélisation du contrôle des services, vous devez d'abord comprendre comment Nagios effectue l'ordonnancement des événements. Tous les événements internes de Nagios (i.e rotation des fichiers journaux, contrôle des commandes externes, contrôle des services, etc.) sont placés dans une file d'attente. Chaque membre de la file d'attente doit être exécuté à un moment donné. Nagios fait de son mieux pour que tous les événements aient bien lieu au bon moment, bien que certains puissent être retardés si Nagios fait autre chose.

Les contrôles de services sont un type d'éléments qui sont placés dans la file d'attente de Nagios. Lorsqu'un contrôle de service doit être effectué, Nagios démarre un autre processus (avec un appel à la fonction fork()) et effectue le contrôle de service (i.e un quelconque plugin). Cependant, Nagios n'attend pas que le contrôle de service s'achève. A la place, il retourne mettre en route les autres services qui se trouvent dans la file d'attente...

Que se passe-t-il lorsque le contrôle de service s'achève ? Hé bien, le processus lancé par Nagios pour effectuer ce contrôle envoie un message à Nagios avec les résultats du contrôle. C'est alors au tour de Nagios de contrôler et d'analyser les résultats.

Afin que Nagios supervise effectivement, il doit analyser les résultats des contrôles de services qui se sont achevés. Ceci est effectué via un processus de "récolte" des contrôles de services qui se sont achevés. Le "récolteur de service" est un autre type d'évènement qui est placé dans la file d'attente de nagios. La fréquence de ces événements de "récolte" est déterminée par l'option service_reaper_frequency du fichier de configuration pincipal. Lorsqu'un événement de "récolte" est exécuté, il contrôlera tous les messages qui contiennent le résultat des contrôles de service qui se sont achevés. Ces résultats sont alors manipulés par le noyau logique du contrôle des services. A partir de ce moment, Nagios détermine si les hôtes doivent ou non être contrôlés, si des notifications doivent être envoyées, etc. Lorsque les résultats des contrôles de service ont été analysés, Nagios reprogramme le prochain contrôle de service et le replace dans la file d'attente pour une exécution ultérieure. Ce qui termine le cycle contrôle/supervision !

Pour ceux d'entre vous qui veulent vraiment savoir, mais qui n'ont pas regardé le code, Nagios utilise des files de messages pour traiter des communications entre Nagios et le processus qui effectue le contrôle de service...

Attrapes-nigauds possibles...

Vous devez savoir qu'il y a quelques désavantages potentiels à paralléliser le contrôle des services. Comme plus d'un service peut tourner simultanément, ils peuvent interférer les uns avec les autres. Vous devrez évaluer le type de contrôles de services qui tournent et prendre les mesures appropriées pour prévenir les conséquences indésirables. C'est particulièrement important si vous avez plus d'un contrôle de service qui a accès à du matériel (comme un modem). Egalement, si au moins deux contrôles de services se connectent au démon sur un hôte distant pour vérifier une information, assurez-vous que le démon peut être sollicité via plusieurs connexions.

Heureusement, vous pouvez effectuer certaines manipulations qui vous protègent des "collisions" de services...

  1. Le moyen le plus simple pour éviter les collisions est d'utiliser la variable service_interleave_factor. Entrelacer des services aidera à réduire la charge imposée par les contrôles de services sur les hôtes distants. Réglez la variable pour utiliser le facteur de calcul d'entrelacement "débrouillard" [smart], puis réglez la manuellement si vous estimez que c'est nécessaire.
  2. Ensuite, vous pouvez régler l'argument max_check_attempts de chaque définition de service à une valeur supérieure à un. Si le contrôle de service entre en collision avec un autre contrôle en cours, Nagios réessaiera le contrôle de service max_check_attempts fois avant d'envoyer une notification du problème à quelqu'un.
  3. Vous pouvez aussi essayer d'implémenter une logique du type "retrait et réessai" [back-off and retry] dans le code de contrôle de service, bien que vous puissiez trouver cela trop difficile ou trop consommateur de temps.
  4. Si rien de cela ne fonctionne, vous pouvez empêcher la parallélisation en réglant l'option max_concurrent_checks à 1. Cela permettra le contrôle d'un seul service à la fois, ce n'est donc pas une solution particulièrement spectaculaire. S'il y a suffisamment de demandes en ce sens, j'ajouterai une option aux définitions de services qui vous permettra de préciser si le contrôle de service doit être ou non parallélisé. S'il n'y a pas assez de demandes, je ne le ferai pas.

Un autre élément à noter est l'effet de la parallélisation des contrôles de service sur les ressources de la machine hébergeant Nagios. Effectuer un certain nombre de contrôles de services en parallèle peut grever les ressources mémoire et CPU. La méthode inter_check_delay_method essaiera de minimiser la charge imposée sur votre machine en répartissant les contrôles dans le temps (si vous utilisez la méthode "débrouillard" [smart]), mais ce n'est pas une solution totalement sûre. Afin d'avoir un regard sur le nombre de contrôles de services qui peuvent fonctionner en même temps, utilisez la variable max_concurrent_checks. Vous devrez affiner cette valeur, construite sur le nombre total de services que vous contrôlez, les ressources système disponibles (cadence du processeur, mémoire, etc.) et les autres processus qui tournent sur votre machine. Pour avoir davantage d'informations sur la façon de régler la variable max_concurrent_checks pour qu'elle corresponde à vos exigences, lisez la documentation relative à l'ordonnancement des contrôles.

Ce qui n'est pas parallélisé

Il faut se souvenir que, seule, l'éxecution des contrôles de services a été parallélisée. Il y a une bonne raison à cela : les autres choses ne peuvent pas l'être d'une manière très sûre ou très saine. En particulier les gestionnaires d'événements, les notifications de contact, la vérification des contrôles de services et les contrôles d'hôtes ne sont pas parallélisés. Voici pourquoi...

Les gestionnaires d'événements ne sont pas parallélisés du fait de leur conception même. Une grande part de leur puisssance provient de leur capacité à résoudre les problèmes de manière préventive. Un exemple en est le redémarrage du serveur web quand le service HTTP de la machine locale est détecté 'down'. Pour éviter que plusieurs gestionnaires d'événements n'essayent de résoudre des problèmes de manière parallèle (sans qu'ils ne sachent ce que les autres font), j'ai décidé de ne pas les paralléliser.

Les notifications de contact ne sont pas parallélisées à cause des méthodes de notification que vous pouvez utiliser. Si, par exemple, une notification de contact utilise un modem pour composer le numéro de votre alphapage et lui envoyer un message, elle a besoin de l'accés exclusif au modem pendant que la notification s'effectue. Si au moins deux notifications étaient exécutées en parallèle, une seule serait effectuée car les autres n'auraient pas accès au modem. Il y a des moyens de contourner cela comme employer une méthode du style "retrait et réessai" dans le script de notification, mais j'ai décidé de ne pas me fier aux utilisateurs qui avaient implémenté ce type de fonction dans leurs scripts. Une note rapide : si vous avez des contrôles de services qui utilisent un modem, assurez-vous que les scripts de notification qui effectuent la numérotation peuvent réessayer d'accéder au modem après un échec. C'est nécessaire, car un contrôle de service peut tourner en même temps qu'une notification !

L'analyse des résultats des contrôles de services n'a pas été parallélisée. Et cela pour éviter les situations où de multiples notifications relatives à des problèmes d'hôtes ou de rétablissement de service peuvent être envoyées si un hôte s'effondre, devient inaccessible, redevient opérationnel.