Shinken : l’art de l’inspiration

Posted in Nagios by Nap on November 14, 2009

Le partage des idées

Dans tout ce qui est libre on partage le code bien sûr, mais encore plus important on partage les idées. Deux modifications que j’ai apportées ces derniers temps aux Workers (utilisés par les pollers/reactionners) reflètent cela.

Le problème des workers est double : avoir LE bon nombre de Worker et que chaque worker soit le plus efficace possible. Le tout bien sûr pour réduire leur charge au maximum.

Avoir le bon nombre

Le nombre de Worker n’est pas si simple à déterminer. On peut placer un nombre arbitraire (10, 30, 100 ou même 250) mais il ne sera jamais optimal, sauf à faire de nombreuses tentatives. De plus, mesurer leur utilisation n’est pas chose aisée.

Sur un petit environnement, avoir 4 workers sera plus que suffisant. Sur les très gros, 30 n’est pas du luxe. En effet, si on prends un check simple qui fait toujours la même chose, il est relativement simple de savoir combien il en faut. Mais avec des checks qui mettent un temps aléatoire pour s’éxécuter, ça devient tout de suite plus dur.

Après une petite réflexion, leur nombre optimal est venu:

temps_moyen_checks*checks à traiter

Bon le nombres de checks à traiter est plus que facile à obtenir. Le temps moyen des checks un petit peu moins. Je suis parti d’un temps moyen depuis le lancement du daemon mais le problème est que le nombre de checks à la seconde n’est pas tout le temps le même, la nuit ça peut être plus calme par exemple. J’ai utilisé un calculun calcul similaire au load average Unix (une moyenne mobile exponentielle). Ceci permet de ne pas avoir de lisser un peu le nombres de workers demandés le tout en ayant une réactivité intéressante car j’ai pris un load à une minute.

Ceci n’aurait pas été possible si les auteurs d’Unix d’auraient pas utilisés ce type de moyenne et que Linux m’ait montré le code (tout simple en plus..). Au passage j’ai cré une Class spéciale pour ce type de calcul afin de pouvoir le réutiliser dans d’autres parties du code.

Pour l’instant c’est la partie montante du nombre de worker qui est utilisé. Il faut que je m’occupe de la partie descendante (où comment flinguer intelligemment les workers).

Attendre le temps qu’il faut

Revenons un peu sur les temps des checks. Ils sont aléatoires. Souvenez vous : j’ai changé le code du lancement des checks sous Unix par la variante Windows (avec un joli gain de perfs à la clé et une dépendance de moins). MAIS cette technique repose sur une boucle sur poll (pas de select malheureusement :( ) avec un sleep au milieu. OK, il suffit d’attendre le temps du checks… Ah flûte, on ne sait pas a priori combien de temps il va attendre. Attendre trop et c’est de la latence et un worker qui ne fai rien (donc plus de workers nécessaires). Attendre trop pu, c’est une latence minimale, mais un poll lancé trop souvent et donc de la charge inutile…

Bref, il faut attendre le BON temps, ou a défaut le bon ordre de grandeur. Là on peut s’inspirer du TCP.

Oulala, quel est le rapport entre le TCP et une boucle sur le poll? Et bien le slow start de TCP bien sûr! TCP est fait pour tout type de connexions, rapides, lentes, moyennes. Il doit optimiser le débit. Pour cela il augmente dès le début de la connexion le débit envoyé à chaque envoi. Fois 2 à chaque envois. Dès que ça ne passe plus, il a trouvé l’ordre de grandeur, et passe par une augmentation linéaire.

On va utiliser un système similaire. Nous voulons l’ordre de grandeur (une fois qu’on a trouvé, c’est fini). On va donc partir d’une boucle toute simple :

wait_time = 0.0001
while process.poll() is None:
time.sleep(wait_time)

Et la changer en :

wait_time = 0.0001
while process.poll() is None:
wait_time = min(wait_time*2, 0.1)
time.sleep(wait_time)

En une ligne on a une recherche de l’ordre de grandeur. Simple non? Ici j’ai borné à 0.1s. 10 appels systèmes par secondes sont tout à fait acceptable, 10000 beaucoup moins. On change donc un nombre d’appel en O(n) en O(log2(n)).

Il est marrant de voir à quel point les algo les plus remarquables sont toujours d’une simplicité étonnante…

Moyenne mobile exponentielle

Shinken : un nouveau logo

Posted in Nagios by Nap on November 14, 2009 2 Comments

Sur la page de Shinken dans (l’excellent) wiki de nagios-fr (http://wiki.nagios-fr.org/nagios/shinken/start) j’avais placé un petit texte sur un appel à un nouveau logo :

L’auteur n’est pas contre une autre mascotte plus originale (moins manchot) le temps qu’elle respecte l’esprit du logiciel

En effet, le logo que j’avais assemblé au début du projet était le suivant :

shinkenOk il est marrant, mais il a un gros soucis d’image : c’est un manchot. C’est àdire que c’est Très connoté Linux. J’aime Linux, je l’utilise tous les jours, et je suis en train de poster depuis a kubuntu chérie, MAIS pour un programme, le choix d’un logo manchot est à double tranchant : ça fait Linux OK, mais ça ne fait QUE Linux. Or Shinken est multiplateformes. Il faut un logo plus neutre, mais toujours avec la symbolique du Shinken qui coupe.

Romuald FRONTEAU de l’équipe de nagios-fr a donc répondu à mon appel et m’a apporté un nouveau logo que j’aime tout particulièrement :

logo_shinkenSobre, élégant, efficace. Que demander de plus?

Je vais garder mon manchot pour le blog et mettre le nouveau sur les sites du projet Shinken.

Shinken : le choix de la licence AGPL

Posted in Nagios by Nap on November 14, 2009

Au début de l’écriture de Shinken s’est vite posé le choix de la licence. Ou plutôt le choix de la licence libre pour être plus exact. La BSD ou tout autre licence qui permet de prendre le code, de le placer dans du code propriétaire sans rien retourner à la communauté n’est pas à mon goût. Certains l’acceptent bien, moi non. Le choix de la GPL est vite arrivé comme un standard.

Ensuite le problème des services distants se pose avec la GPL, d’où le choix final de l’AGPL qui impose à un fournisseur de service de fournir le code à ses clients s’il utilise le code en AGPL.

Je viens de lire http://www.framablog.org/index.php/post/2009/11/13/pourquoi-j-utilise-la-licence-gpl (traduction de http://zedshaw.com/blog/2009-07-13.html) et ça me conforte dans ce choix.

Shinken : un serveur? Inutile, préférez un eeepc…

Posted in Nagios by Nap on November 10, 2009 2 Comments

Hier je me suis amusé à voir jusqu’où pouvait aller Shinken en terme de perfs sur un eeepc 701 (le tout premier pas super puissant). Et bien il s’en tire plus qu’honorablement : 10000Checks/5min. C’est largement suffisant pour bon nombre d’installations. Bref, n’achetez plus de serveur pour votre supervision, prenez plutôt des eeepc, c’est beaucoup moins cher…

Voici les specs du monstre :

eeepcEt ce que donne shinken (ici l’ordonnanceur) :

shinken-eeepcJe préfère m’abstenir de faire un bench avec Nagios sur cette machine :mrgreen:

Et bientôt une grande nouvelle concernant le logo de Shinken ;-)

Shinken : 100Kchecks? Ah désolé, il fallait lire 200K

Posted in Nagios by Nap on November 9, 2009

Et oui désolé, mais le 100K checks/5min n’est plus de mise, désolé. C’était un compte rond, facile à retenir, mais non, il n’est plus.

Il faut parler de 200K désormais (dans les même conditions donc Xeon 4coeurs) :mrgreen:

La limitation n’est plus du fait du poller désormais, mais bien du scheduler. Et tout ça c’est à cause de Windows. En effet, je me suis demandé ce que donnait l’exec que j’utilise sous Windows sur Linux, donc sans passer par pexpect. Et bien les perfs sont autrement meilleures sans. Donc bye bye la lib, retour à la mano (10lignes, ça va…). Ceci m’a permis au passage de limiter le nombre de Workers en cours et donc de limiter fortement le load average de la machine, ce qui ne me déplais pas, c’est bien plus contrôlable.

Avec une telle conf, la machine arrive à avoir 25% de CPU en idle, le scheduler lui est très sollicité (principalement par les échanges Pyro/cPycle). Je me demande à combien on peut monter en mettant un poller et deux schedulers…

Pour la preuve au fait:

mysql> select count(*),avg(latency) from service;
+———-+—————–+
| count(*) | avg(latency)    |
+———-+—————–+
|   200005 | 13.173913548248 |
+———-+—————–+
1 row in set (0.30 sec)

PS: pas de capture de ninja ça coup-ci, la page part en timeout… trop de services à gérer…

Shinken : à oui au fait, c’est multiplate-forme

Posted in Nagios by Nap on November 5, 2009

Shinken est écrit en Python et ses deux dépendances principales sont Pyro et Pygraph qui sont disponibles sur toutes les plate-formes où est Python (c’est à dire beaucoup). J’ai fait un test, et après quelques petits aménagements très légers (10 lignes…) dans la partie lancement des checks et autres, j’ai réussi à lancer Shinken sous Windows :)

Une petite preuve çi-dessous:

shinken-on-windowsEn fait j’ai dû bypasser la partie lecture du pipe nommé nagios.cmd pour que ca marche, les pipes nommées sous Windows n’étant pas gérés directement (ni simplement…). Mais tout le reste fonctionne comme sur un Linux :)

Certains vont se demander à quoi ça sert. Alors:

  • ca coûte rien de le porter pour Windows, alors faut pas se priver
  • Shinken gère les très grands environnements avec le découpage de conf and co (là où Nagios péchait par manque de perf et l’architecture distribuée hautement disponible), mais il ne faut pas oublier que Nagios est aussi exclu des PME à cause de la nécessité d’avoir un Linux (la solution cygwin n’est pas acceptable ni recommandée…). Shinken permet de ne plus avoir ce problème et offre à Nagios un nouveau terrain de jeu, et non des moindres.

Reste à voir si Ninja est prévu pour Windows, et après on peut penser à un pack Shinken/Ninja/Pyhon/Xampp.

Questions performances le lancement de process sous Windows coûte cher. Ici la machine est très chargée, mais bon elle avait 1500 checks/5min et surtout c’était une VM (faut pas trop lui en demander). Sous Windows ça sera les petits environnements, donc 1500 checks c’est déjà pas si mal :)

Dernière info : l’installation de python et des dépendances de shinken sous un Windows est une véritable partie de plaisir, un grand bravo aux auteurs de Python et leur processus d’installation sous Windows, car ça marche très bien, c’est un vrai next/next/next :)

Aller vraiment la dernière : là c’est un XP, mais ça roule de la même manière sur un Seven :mrgreen:

Shinken : les realms sont là

Posted in Nagios by Nap on November 3, 2009

Ca y est, j’ai implémenté les Realms et tout ce que ça implique sur le dispatching des configurations et la gestion des spares. Une configuration l’utilisant va devenir par exemple :

define realm {
   realm_name       All
   realm_members    Europe,US,Asia
   default          1    ;Est le realm par défaut. Doit être le seul dans ce cas...
}
define realm{
   realm_name       Europe
   realm_members    Paris   ;Le realm Paris est contenu dans Europe
}
define reactionner{
       name	reactionner-All
       address	localhost
       port	7769
       spare	0
       realm    All
       }

define poller{
       name     poller-All
       address  localhost
       port     7771
       spare    0
       realm    All
       manage_sub_realms  1
}

define broker{
       name	broker-All
       address	localhost
       port	7772
       spare	0
       realm    All
       }

Ici c’est un cas très simple, sans spare (et avec des realms un peu vide…) mais qui montre un peu la conf que cela va donner.

Il ne me manque plus qu’à gérer le cas où l’administrateur n’en a défini aucun (ce qui sera pour les petites et moyennes configurations). Dans ce cas je vais en créer un à la volée et mettre tout le monde dedans tout simplement :)

Shinken : Pool -> Realm

Posted in Nagios by Nap on November 1, 2009

Bonjour,

Petit changement cosmétique pour les pools. Ils ne s’apellent plus comme ça, je préfère utilisé realms à la place. Il y aura beaucoup moins de confusion avec les pools. Si certains ne savent pas ce que signifie ce terme, il y a wikipedia  http://en.wikipedia.org/wiki/Realm.

Bon c’est parti pour du query remplace maintenant…

Shinken : la notion de pool, ou comment pousser encore plus loin l’architecture

Posted in Nagios by Nap on October 29, 2009 2 Comments

L’illumination du jour

Bonjour,

Hier j’ai eu tout le temps de pousser l’architecture de Shinken plus loin que je ne l’avais fait jusqu’alors. En effet, elle permet dans sa forme actuelle d’avoir un point unique d’administration de plusieurs ordonnanceurs, pollers, reactionners et brokers. Les hôtes sont dispatchés sur les ordonnanceurs, les services suivent, les satellites (poller/reactionner/broker) tapent sur tous les ordonnanceurs. C’est implémenté, et le pire, c’est que ça fonctionne. Tout le monde est content.

Tout le monde? Non. Un petit village d’irréductibles gaul… oups, je m’égare…

Tout le monde? Non. Imaginons un peu qu’un administrateur ait une infrastructure distribuée sur plusieurs continents (un quelconque rapport avec l’infra de l’auteur est fort plausible…). Avec l’archi de Shinken actuellement, si l’administrateur a mis deux ordonnanceur : un a Bordeaux et un à Shangaï (toujours par le plus grand des hasard hein…) et de même un poller sur Bordeaux, et un sur Shangaï, les pollers tapent sur les deux ordonnanceurs, et pour ceux qui n’ont pas le grand bonheur d’avoir un site à shangaï, autant vous dire que les lignes internet sont plutôt… bon disons que c’est aléatoire pour rester poli. De plus, un hôte va se voir affecté sur un ordonnanceur ou un autre sans pouvoir influer dessus.

Bref, Shinken, dans son état actuel, est pratique pour avoir de la haute dispo, répartition de charge et performance mais pour un site unique. Et là vous me voyez venir à des kilomètres : la gestion des sites.

Un pool, des pools

Alors on va utiliser un nom plus général qu’un site (après tout ça peut être une séparation plus organisationnelle que géographique) : un pool. (A ne pas confondre avec les pollers donc).

Un pool est un groupe de ressources indissociables auquel vont pouvoir être rattachés des hôtes ou des groupes d’hôtes. Une telle association sera unique, un hôte ne pourra se trouver que dans un pool donné et il faudra que ses parents soient dans le même pool (sinon le découpage de conf et le dispatchign ne sera pas content). Si ces derniers n’ont pas de pool désignés, il hériterons de celui-là.

Un pool est donc un groupe de schedulers, pollers, [reactionners], [brokers] (les deux derniers sont optionnels). Dans un pool, les pool vont se connecter à tous les schedulers du pool.

Un pool peut contenir un autre pool. Ceci ne change rien pour les ordonnanceurs/pollers, ceux-ci ne s’adressant qu’aux ordonnanceurs du même pool. Les hôte d’un pool ne seront dispatchés que sur les schedulers du pool, pas de ses fils. Là où une hiérarchie de pool devient utile concerne les reactionners/brokers : ils sont associés à un pool, mais si ce dernier contient d’autres pools (qui eux même en contiennent d’autres etc etc) et bien les reactionners/broker vont chercher les infos sur tous les ordonnanceurs de la hiérarchie de pool.

En fait, cette notion de satallites qui peuvent atteindre les sous-pools devrait être paramétrable, genre une option acces_inner_pool avec comme valeur par défaut les pollers a 0, et les reactioners/broker 1. Si après l’administrateur veux le changer pour décloisonner/cloisonner, libre à lui.

Il faut bien retenir une chose : un seul Arbiter (et son spare) et une seule conf, quelque soit le nombre de pools que vous avez. Ah une autre chose : pour l’instant rien n’est implémenté! Mais bon ça ne devrait pas être trop méchant je pense.

Au secours, je comprends rien!

Pas clair? Oui je m’en doute un peu, avec mes pools, sous-pool, pollers et schedulers.

En résumé, vous mettez un hôte ou un groupe d’hôte dans un pool. Celui-ci est un ensemble de ressources pour superviser vos hôtes et les services qui y sont raccrochés. Vous pouvez enlever ou rajouter des ressources au pool sans avoir à changer la conf des 30K hôtes que vous avez patiemment configuré car vous avec rajouté un ordonnanceur ou un poller de plus dans le lot.

Bref, le pool est une facilité pour gérer ses ressources. Si vous n’avez qu’un petit site gérable par un ordonnanceur/poller/reactionner/broker, pas la peine de vous embêter avec un pool, par défaut shinken en créera un pour vous à la volée et vous n’en entendrez même pas parler :)

Dessine moi un diagramme

Des diagrammes, c’est encore mieux que toutes ces explications :)

Imaginons que l’on a deux environnements distribués un peu partout dans le monde. Dans un cas, on souhaite un cloisonnement total des continents. Dans un autre, on accepte que les réactionners et brokers soient communs à tous les ordonnanceurs du monde (oui, rien que ça :) ).

Les diagrammes

Voici le cas isolé :

shinken-architecture-isolated-pools

Et le cas plus communs avec les réactionner/broker de communs :

shinken-architecture-global-poolComme vous pouvez le voir, les éléments sont raccrochés à un seul pool. suivant l’héritage qu’on leur a donné, ils utilisent les ordonnanceurs des sous-pool ou non.

Et dans la conf, ça donne quoi?

Voici ce que ça devrait donner pour le second cas :

define pool {
pool_name    All
pools         Europe, US, Asia
}
define pool{
pool_name    Europe
pools                Paris
}

(je ne sais pas encore si c’est bien utile de forcer la définition des autres pools même s’ils n’ont qu’un nom…).

define scheduler{
scheduler_name       sched Paris
pool                                 Paris
}
define reactionner{
reactionner_name   reactionner-maitre
pool                        All
}

Et dans les hôtes :

define host{
host_name         serveur-paris
pool                       Paris
[...]
}

Pour ces derniers ce paramètre sera géré par l’héritage comme toutes les propriétés des hôtes.

Ce qui est susceptible de changer

Il me reste quelques petits points à voir : doit-on faire le lien entre les schedulers/pollers/reactionners/broker et les pools au niveaux du define des pools, ou bien comme ci-dessus au niveau des éléments? Les deux? Mais quoi faire en cas d’incompatibilité des deux types de configuration? Je prends tout commentaires :)

Shinken : dispatch des commandes externes

Posted in Nagios by Nap on October 24, 2009

Des commandes importantes

Nous avons déjà vu le dispatch des configurations vers les schedulers et les satellites, regardons désormais comment se passe l’envoi de commandes externes par le client. Dans la philosophie Shinken, celui-ci n’a besoin d’envoyer ses ordres que d’un seul endroit, à côté de l’Arbiter.

Il faut séparer les commandes en deux catégories :

  • les commandes globales à tous les ordonnanceurs;
  • les commandes spécifiques à un élément (host/service/contact).

En fait une partie des deuxièmes commandes est en fait globale : les contacts sont partout et les commandes les concernant sont envoyées partout.

Comment shinken les dispatch

En fait ce n’est pas sorcier. Pour chaque type de commande Shinken sait s’il elles sont globales ou non. Pour les globales, il ne se pose pas de question, il envoie à tout le monde et voila.

Pour les spécifiques, il faut qu’il trouve quel est l’ordonnanceur en question. Il cherche pour cela dans les N configurations l’élément impacté (hôte ou service). Une fois trouvé, il sait à qui envoyer l’ordre et il le fait.

Une fois les ordres reçus, les ordonnanceurs n’ont plus qu’à les appliquer.

? Vous voulez un diagramme? Bon ok, voici un exemple avec une commande spécifique et une globale.

shinken-external-commands

« Previous PageNext Page »