Shinken : Les grandes lignes
( 06 Oct 2009 )Il y a quelques temps j'ai présenté dans les grandes lignes mon proof of concept Shinken, le Nagios en Python. Et bien il a plutôt bien avancé depuis. En voici un état des lieux et une idée de là où il va.
Architecture générale
Shinken est pensé pour les environnements distribués. Il est bien sûr possible de faire tourner tous ses composants sur une seule et même machines. Les composants justement, parlons en.
Architecture de Nagios
Nagios est (quasiment) monolithique. Il lit la conf, la traite, ordonnance les checks, les lance ainsi que les actions qui en résultent (les notifications et les event handlers). Il exporte également des informations vers un daemon externe pour mise en base de données.
Lorsque l'on a un petit environnement, tout marche bien, c'est pratique et presque rapide. Le problème se pose avec les grands environnements : Nagios est capable de gérer facilement jusqu'à 10000checks/5minutes sur un serveur moyen de gamme. Avec du tuning on peu arriver à 30000, mais gère plus, même en rajoutant pleins de CPU sur le serveur. La mise en place des environnements distribués n'est pas triviale (la preuve, elle demande un chapitre à part entière dans mon livre :) ). La tâche est encore plus hardue pour les environnements distribué ET hautement disponibles. Cette dernière exigence est très complexe à gérer si on ne veux pas perdre trop en performances, voir pas faisable du tout pour les très gros environnements sauf à mettre une armée de serveurs.
C'est là que vient Shinken : mettre en place un environnement distribué hautement disponible facilement. Le côté facile doit venir aussi de la gestion de conf. Nagios a une gestion de la configuration impressionnante, mais qui nécessite un gros travail manuel lorsqu'il est question d'environnements distribués.
De même pour donner des ordres à Nagios, il faut passer par le pipe nommé nagios.cmd situé sur le même serveur. Pour un serveur ça va, mais pour une dizaine, se souvenir sur quel serveur Nagios se trouve l'hôte que vous voulez rescheduler devient un peu plus complèxe...
Pour résumer la situation, l'architecture de Nagios est la suivante :
Architecture de Shinken
Shinken propose une solution à ces problèmes : le découplage des rôles de Nagios. Ces rôles sont éparpillés sur différents processus. Voici le schémas global, le rôle de chaque élément sera précisé plus bas:
- Arbiter : lit la configuration, la découpe en N partie et l'envoi vers les autres processus. Il lit l'unique fichier nagios.cmd de l'architecture, et transmet les ordres à qui il faut. Il est également le garant de la haute disponibilité et la répartition de charge.
- Schedulers (nom de processus Shinken) : il lit la conf que lui envoi Arbiter. Il peux y avoir N schedulers, chacun avec ses propres éléments (hôtes/services). Il est en charge d'ordonnancer les checks, de les proposer aux autres éléments, récupère le retour des checks, et propose des notifications/event handlers si besoin qui seront lancé par des éléments externes.
- Pollers : Il peux y en avoir autant qu'on veut. Ils récupèrent les checks auprès des schedulers, les lance et renvoi le retour aux scheduler en question. Il n'y a pas intelligence ici. Ils récupèrent des checks, les lancent, renvoient le résultat. Point barre.
- Actionner : De préférence il n'y en a qu'un (et un spare). Il est en charge de lancer les notifications et les event handlers. Il fonctionne de la même manière que les pollers, mais il est à part car on préfère en avoir un et un seul qui fait les notifications (pour les problèmes d'acès aux serveur SMTP ou les flux RSS par exemple).
- Broker : Unique avec un spare, Les schedulers exportent des informations dans des 'broks', des morceaux d'informations. Ils sont récupérés par le Broker qui en fait ce qu'il veut après, suivant les plugins qu'il a. Chaque plugin traite l'information comme il le veut. Les plugins actuellement développés sont l'export du fichier service-perfdata et l'export dans la base merlin. La base ndo ne devrait pas tarder, mais ca sera plus long que pour celle de merlin, car elle est vraiment mal fichue!
- Bah c'est tout. C'est déjà pas mal non? :)
Les éléments de charge sont éclatés d'où le load balancing. L'arbiter est le garant de la haute dispo, il réparti les conf aux vivants, et envoi les conf des éléments morts aux spare si un membre actif vient à mourrir (bah ca peut arriver hein, personne n'est parfait). L'administrateur n'a pas à se soucier de quel scheduler va gérer son élément (hôte), l'arbiter va découper la conf pour lui de manière automatique, et en faire des paquets les plus équilibrés possible en terme de charge. Shinken tiens son nom de là d'ailleurs :)
La configuration
Qui dit nouveaux éléments dit nouvelle configuration. L'arbiter mis à part, chaque élément a un élément de configuration qui lui est dédié. Elle est de la forme (par exemple ici pour les scheduler):
define scheduler{
name scheduler-main
address 192.168.0.1
port 7768
spare 0
}
define poller{
name poller-main
schedulers scheduler-main, scheduler-spare
address 192.168.0.1
port 7771
}
Ceci doit être donné à l'arbiter dans le fichier nagios.cfg, comme n'importe quel autre configuration d'éléments dans Nagios. Ceci va permettre à l'Arbiter d'envoyer les configuration et de gérer les liens avec les schedulers, pollers and co. Je n'ai pas encore prévu de configuration locale au poller and co. Mais à part le port d'ouverture, il n'y aura pas gand chose à configurer.
Je prévois de faire en sorte de créer automatiquement un élément en local s'il n'est pas défini dans la configuration, genre dans le cas de l'import d'une configuration existante sans avoir à la modifier.
Les performances
J'en vois déja arriver avec leur grands sabots : "c'est en python donc c'est tellement lent qu'on ne va pas pouvoir tester sur de vrais environnements". Ca aurait été sacrément inutile si c'était le cas. Je n'aime pas trop perdre mon temps. Allons directement à la mesure dans de vraies conditions : serveur Xeon bi-coeurs 3ghz. J'ai utilisé une configuration générée tout comme dans le chapitre 9 de mon livre (quoi,vous ne l'avez pas encore lu?). La latence nous permet de savoir si le programme a assez de ressources ou non.
- Nagios dans sa configuration standard a stagnée a 9500 checks/5min, avec du tunning poussé, 25000. Je n'ai pas encore fait les tests avec export en base de données avec ndo2db;
- Shinken arrive à 50000 avant que j'ai eu à faire du tunning de code...Et l'export en base de données fait en prime, le tout sur la même machine bien sûr.
Il n'y a pas de secret ici : La charge de Nagios vient du lancement de nouveaux process Nagios qui doivent lancer les plugins et le fait de "reaper" les résultats dans des fichiers plats. Shinken utilise un pool de process (les pollers ont un pool de workers) donc pas de surcharge ici, et les pollers envoient directement les résultats des checks en mémoire (technique d'objets distribués de type Corba, mais en autrement plus simple à utiliser). Pas de fichiers à parser, beaucoup moins de charge. "Et voila".
Par contre ce n'est pas parfait : le lancement de l'Arbiter est légèrement plus lent que Nagios pour la lecture de la configuration, mais rien de rédhibitoire. Je vois revenir les gros sabots pour la consommation mémoire : Oui, ceci consomme plus de RAM que Nagios. Nagios est vraiment bien optimisé sur ce point, Shinken est "seulement" 3 fois plus consommateur, genre 250Mo pour les 50000 checks. C'est tout à fait acceptable à mon goût.
Bref, c'est testable même avec des grands environnements. Et ca veut dire que l'on peut encore améliorer Nagios. Bon reste à faire la partie Worker en C. Je l'aurais bien prise chez Apache, mais question de licence, ça le fait pas je pense. Puis le code est .. complexe pour juste une gestion de worker, mais bon c'est le C hein...
Ce qui est déjà fait
Les fonctionnalités principales de Nagios sont déjà dans Shinken:
- ordonnancement de Nagios (HARD, SOFT, etc)
- gestion des périodes de temps Nagios (sauf les exclusions)
- checks passif
- gestion des dépendances
- macros
- vérification de la fraicheur des états
- export des données de performances
- export des données dans une base MySQL de type Merlin
- la gestion du flapping
- le cache de checks pour les dépendances
- services volatiles (pour les logs)
- gestion du fichier de rétention
Pas si mal hein?
Ce qu'il reste à faire
Avant de le présenter "officiellement" aux auteurs de Nagios, je tiens à ce que la gestion des spares soient complète. De même que l'export vers la base ndo. Après je le présente, avec dans l'espoir de voir les bonnes idées s'il y en a (comme le pool de process) intégrée dans Nagios si c'est possible. (Bon tout est possible, mais en C ça devient beaucoup plus long à faire... beaucoup plus long à faire même...et pourtant j'aime le C, faut pas croire).
Ah oui, il faut que je fasse une VM de type VirtualBox avec Shiken et Ninja pour l'interface. En fait plusieurs VM seraient mieux pour l'aspect distribué.