A l’heure actuelle, les infrastructures IT sont de plus en plus complexes et dynamiques. Avec les infrastructures dans le Cloud et les applications basées sur les conteneurs, votre infrastructure change rapidement et doit être à jour dans votre système de supervision.
La meilleure façon d’être à jour est d’utiliser l’automatisation avec un outil de gestion de configuration (configuration management). Dans cet article, nous allons nous appuyer sur l’outil Salt.
Buts
Quand un salt-minion s’enregistre à un salt-master, le serveur avec le salt-minion sera automatiquement ajouté dans la configuration de Centreon avec les bons modèles d’hôtes. Ensuite la configuration du collecteur sera rechargée.
Voici l’architecture de la plateforme à superviser :
Pré-requis
Pour ce tutoriel, vous avez besoin de bonnes connaissances des modèles hôtes et des groupes hôtes dans Centreon Web.
Les logiciels requis :
- SaltStack
- Centreon Web => 2.8.x
- python-sdk-centreonapi => 0.0.1
Préparez votre Centreon Web
Vous devez avoir configuré des modèles d’hôtes et des groupes d’hôtes.
Pour ce tutoriel, je vais utiliser les modèles d’hôtes et groupes d’hôtes suivants :
Modèles d’hôtes venant des Plugin Packs
- Linux SNMP (operatingsystems-linux-snmp) : la base pour superviser un serveur Linux en utilisant SNMP
- Apache Server (applications-webservers-apache-serverstatus) : superviser un serveur Apache
- MySQL DB (applications-databases-mysql) : superviser un serveur MySQL
Groupes d’hôtes
- linux-servers : Liste des serveurs linux
- frontend : Liste des serveurs HTTP
- backend : Liste des serveurs de base de données
Configuration du salt-master
Ajout des informations liées à Centreon Web dans la configuration de salt-master
Je suggère d’utiliser un fichier supplémentaire pour cette configuration comme /etc/salt/master.d/centreon.conf.
Les options de configuration :
Nom de la clé | Description |
---|---|
url | L’url pour accéder à Centreon Web. |
username | Un utilisateur qui peut utiliser les APIs REST. |
password | Le mot de passe de l’utilisateur. |
poller | Le collecteur où les nouveaux hôtes seront supervisés. |
hosttemplates | La liste des modèles d’hôtes pour les nouveaux hôtes. Cette liste pourra être complétée par la configuration du minion. |
hostgroups | La liste des groupes d’hôtes à attacher aux nouveaux hôtes. Cette liste pourra être complétée par la configuration du minion. |
Exemple :
centreon:
url: http://centreon.domain.tld/centreon
username: username
password: password
poller: Central
hosttemplates:
- operatingsystems-linux-snmp
hostgroups:
- linux-servers
Ecrire le salt-runner
Le salt-runner sera exécuté sur le salt-master. Il appellera l’API REST de Centreon Web au moment de l’enregistrement d’un nouveau salt-minion. Ce script est écrit en Python. Vous pouvez aller voir la documentation salt pour plus d’informations.
J’utilise le chemin /srv/runners pour mes scripts de runner. Ce chemin est configuré dans le fichier /etc/salt/master, ajouté a la fin du fichier :
runner_dirs: ['/srv/runners']
Ensuite, je crée le fichier /srv/runners/centreon.py qui contient le code suivant :
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import json
import logging
import salt.client
# Import from python-sdk-centreonapi
from centreonapi.webservice import Webservice
from centreonapi.webservice.configuration.host import Host
from centreonapi.webservice.configuration.poller import Poller
# Initialize the default logger to write in salt-master log file
logger = logging.getLogger(__name__)
# Create a class to interact with object
class Centreon(object):
def __init__(self):
# Get configuration
self.config = Centreon.getConfig()
# Initialize the webservice connector
Webservice.getInstance(
self.config['url'],
self.config['username'],
self.config['password']
)
# Initialize Centreon objects
self.host = Host()
self.poller = Poller()
# Initialize local salt client
self.salt_client = salt.client.LocalClient()
# Cache for salt grains
self.grans_cache = None
# Get the configuration from salt-master configuration file
@staticmethod
def getConfig():
centreon_config = __opts__['centreon'] if 'centreon' in __opts__ else None
if centreon_config is None:
raise KeyError('Not configuration found')
# Test required configuration parameters
url = centreon_config.get('url', None)
username = centreon_config.get('username', None)
password = centreon_config.get('password', None)
poller = centreon_config.get('poller', None)
if url is None or username is None or password is None or poller is None:
KeyError('Missing parameters')
hosttemplates = centreon_config.get('hosttemplates', [])
hostgroups = centreon_config.get('hostgroups', [])
if len(hostgroups) == 0 or len(hosttemplates) == 0:
KeyError('Missing parameters')
return {
'url': url,
'username': username,
'password': password,
'poller': poller,
'hosttemplates': hosttemplates,
'hostgroups': hostgroups
}
# Test if the host exists in Centreon Web configuration
def exists(self, minion_name):
try:
hosts = self.host.list()
except Exception as exc:
logger.error(exc)
raise exc
for info in hosts['result']:
if info['name'] == minion_name:
return True
return False
# Get the host ip address (use the first time when the host have multiple ip address)
def get_minion_ip(self, minion_name):
ip = self.salt_client.cmd(minion_name, 'network.ip_addrs')
if minion_name not in ip or len(ip[minion_name]) == 0:
raise KeyError('The minion has not ip !!! ...')
return ip[minion_name][0]
# Cache the grains centreon of the host to add
def get_grains_centreon(self, minion_name):
grains = self.salt_client.cmd(minion_name, 'grains.item', ['centreon'])
if minion_name not in grains:
self.grains_cache = {}
self.grains_cache = grains[minion_name]['centreon']
logger.error(json.dumps(self.grains_cache))
# Generate the list of hostgroups for the host to add
def get_hostgroups(self, minion_name):
if self.grains_cache is None:
self.get_grains_centreon(minion_name)
if 'hostgroups' in self.grains_cache:
hostgroups = list(set(self.config['hostgroups'] + self.grains_cache['hostgroups']))
else:
hostgroups = self.config['hostgroups']
return '|'.join(hostgroups)
# Generate the list of hosttemplates for the host to add
def get_hosttemplates(self, minion_name):
if self.grains_cache is None:
self.get_grains_centreon(minion_name)
if 'hosttemplates' in self.grains_cache:
hosttemplates = list(set(self.config['hosttemplates'] + self.grains_cache['hosttemplates']))
else:
hosttemplates = self.config['hosttemplates']
return '|'.join(hosttemplates)
# Function to register the runner on salt-master : test if salt-master configuration is valid
def __virtual__():
try:
Centreon.getConfig()
except Exception as exc:
logger.error(exc)
return False
return True
# The runner action to add host to Centreon Web
def register_instance(minion_name):
try:
# Create the Centreon object
centreon = Centreon()
except Exception as exc:
logger.error(exc)
raise exc
# Test if the host exists in Centreon Web and add it if does not exist
if not centreon.exists(minion_name):
logger.info("Add host %s" % (minion_name))
# Add the host
host.add(
minion_name,
minion_name,
centreon.get_minion_ip(minion_name),
centreon.get_hosttemplates(minion_name),
centreon.config['poller'],
centreon.get_hostgroups(minion_name)
)
# Apply the host templates for create associate services
host.applytpl(minion_name)
# Apply Centreon configuration and reload the engine
poller.applycfg(config['poller'])
Configuration du salt-reactor
Le salt-reactor est le mécanisme qui exécute une action quand l’événement est lancé par Salt. Vous pouvez aller voir la documentation salt pour plus d’informations.
Je configure l’action d’ajout d’un hôte quand le salt-master reçoit l’événement qu’un salt-minion est démarré.
Dans le fichier /etc/salt/master, j’ajoute à la fin la configuration pour l’événement.
reactor:
- 'salt/minion/*/start':
- /etc/salt/master.d/reactor_monitoring.sls
salt/minion/*/start est l’événement qu’un salt-minion démarre et envoie les informations de démarrage au salt-master.
Le fichier /etc/salt/master.d/reactor_monitoring.sls contient la configuration pour appeler le runner.
minion_to_monitoring:
runner.centreon.register_instance:
- minion_name: {{ data['id'] }}
runner.centreon.register_instance définit le runner pour Centreon et exécute l’action register_instance.
data[‘id’] est le nom du minion.
Après la configuration du salt-master, je redémarre le service salt-master.
service salt-master restart
Configuration du salt-minion
Cette configuration doit être faite avant le démarrage du salt-minion, sinon l’hôte sera ajouté sans les informations supplémentaires.
J’ajoute quelques configurations pour Centreon avec les grains pour avoir une meilleure configuration de mon hôte. Je sauvegarde ces informations dans le fichier /etc/salt/minion.d/grains.conf.
La liste des informations de configuration :
Nom de la clé | Description |
---|---|
hosttemplates | Les modèles d’hôtes supplémentaires pour le nouvel hôte. |
hostgroups | Les groupes d’hôtes supplémentaires pour le nouvel hôte. |
Exemple pour un hôte de type serveur web :
grains:
centreon:
hostgroups:
- frontend
hosttemplates:
- applications-webservers-apache-serverstatus
Exemple pour un hôte de type serveur de base de données MySQL :
grains:
centreon:
hostgroups:
- backend
hosttemplates:
- applications-databases-mysql
Après cette configuration, je démarre le service du minion.
service salt-minion start
Et c’est tout.
N’hésitez pas à commenter et ajouter vos améliorations.