Déploiement d’une stack ELK en mode Swarm

Bonjour à tous, dans cet article nous allons vous présenter comment déployer la solution open source ELK en mode Swarm.

Vous verrez les questions que nous nous sommes posées afin d’en déterminer l’infrastructure, le dimensionnement, mais aussi comment déployer la Stack et la rendre hautement disponible.

Qu’est-ce que ELK ?

Aujourd’hui appelé Elastic Stack, « ELK » est l’acronyme de trois projets open source : Elasticsearch, Logstash et Kibana.

Elasticsearch

Elasticsearch est un moteur de recherche et d’analyse RESTful distribué, conçu pour répondre à une multitude de cas d’utilisation.

Qu’il s’agisse de données structurées ou non structurées, de données géographiques ou d’indicateurs, avec Elasticsearch, il est possible de lancer différents types de recherches, ou encore les associer entre elles.

Logstash

Logstash est un pipeline open source côté serveur, destiné au traitement des données.

Sa mission ? Ingérer simultanément des données provenant d’une multitude de sources, puis les transformer et les envoyer vers un système de stockage.

Le pipeline de traitement des événements Logstash comprend trois étapes :

entrées -> filtres -> sorties

Les entrées génèrent des événements, les filtres les modifient et les sorties les expédient ailleurs. Les entrées et les sorties prennent en charge des codecs qui permettent de coder ou de décoder les données à l’entrée ou à la sortie du pipeline sans avoir à utiliser un filtre séparé.

Kibana

Kibana permet de visualiser les données Elasticsearch et de naviguer dans la Suite Elastic.

Qu’est-ce que Swarm ?

Swarm est un groupe de machines qui exécutent Docker et qui font partie d’un cluster. Vous continuez à exécuter les commandes Docker auxquelles vous êtes habitué, mais elles sont maintenant exécutées depuis un nœud manager.

Les managers Swarm peuvent utiliser plusieurs stratégies pour exécuter les containers, telles que le « nœud le plus vide » – qui utilise les machines les moins utilisées, ou « global », qui garantit que chaque nœud obtient exactement une instance du container spécifié.

Vous demandez à l’orchestrateur Swarm d’utiliser ces stratégies dans le fichier compose, tout comme celui que vous avez déjà utilisé auparavant.

Cas d’entreprise

Voici un cas d’entreprise afin d’appuyer les propos qui vont suivre :

Vous êtes consultant en informatique et une entreprise A fait appel à vos compétences afin de remplacer le puits de logs existant.


L’entreprise A n’utilise qu’une machine afin de récolter le Syslog de son routeur.


Le tout est sauvegardé dans un fichier, avec une rotation par jour. La taille de chaque fichier est en moyenne de 3 Go.


L’objectif est de remplacer ce puits de logs en un SIEM

Volumétrie

Afin d’avoir davantage de marge de manœuvre, le volume journalier stocké sur le disque a été fixé à 5Go.

La rétention des données selon la directive 2006/24/CE exige la conservation des données pendant une période allant de six mois à deux ans, en particulier en vue de pouvoir :

  • tracer et identifier la source d’une communication
  • tracer et identifier la destination d’une communication
  • identifier la date, l’heure et la durée d’une communication
  • discerner le type de communication
  • identifier la machine utilisée pour communiquer
  • identifier la location des équipements de communication mobile

La volumétrie annuelle est donc de : 5Go * 365 = 1 825Go de données.

Dimensionnement

Maintenant que la volumétrie est évaluée, il faut assurer une continuité de service. C’est la raison pour laquelle l’ensemble des services ainsi que le matériel seront redondés.

Dans un premier temps, il faut s’assurer de la pérennité des données. La réplication de ces dernières est nécessaire car étant sensibles, l’entreprise ne peut se permettre d’en perdre. C’est pourquoi elles seront dupliquées 2 fois. Le stockage doit être au minimum de : 3 * 1 825 = 5 475Go, soit 5.34To.

Indexes et shards

Par défaut, un index est composé de 5 shards primary et d’1 réplica. Il est courant de voir des shards de taille comprise entre 20Go et 40Go. En reprenant le calcul volumétrique précédent, l’index net-security-syslog-* fera 1.8To de données au bout d’un an.

Avec au maximum 40Go de données par shards, il faudra donc : 1 825Go / 40Go ~= 47 shards. Pour être un peu plus à l’aise, les indexes seront dimensionnés avec des shards de 35Go environ, soit 52 shards sur 1 an pour l’index net-security-syslog-*.

Afin de ne pas avoir un seul index porteur de toutes les données, ce dernier sera divisé en plusieurs sous-indexes, datés par semaine, soit : net-security-syslog-%{+YYYY.ww}, eux-mêmes composés de 5 shards primaires et de 2 réplicas.

Pour terminer, l’infrastructure sera multipliée afin d’assurer une haute disponibilité, une répartition de la charge sur les différents nœuds, mais aussi une meilleure répartition des données afin d’avoir encore la totalité des données si jamais une ou plusieurs machines étaient défaillantes.

Prérequis

Pour ce cas d’entreprise, il faut :

  • 5 machines Ubuntu 18.04.2
  • 1.5 To de stockage / node
  • 16 Go de RAM / node
  • 4 CPUs Intel(R) Core(TM) i5-4460 3.20GHz / node

Installer Docker 18.09.2

Pour commencer, effectuez l’installation de Docker en suivant les instructions sur le site officiel jusqu’à l’installation de Docker CE,Docker CLI et containerd.

Puis déconnectez / reconnectez-vous en tant que user.

Initialisation et configuration de votre cluster Swarm

Pour initialiser Swarm, effectuez les commandes suivantes :

Sur chaque hôte du cluster, lancez la commande fournie précédemment par le résultat de l’initialisation du cluster :

Ces derniers seront ajoutés en tant que worker par défaut, à la différence de la machine qui initie la création du cluster qui est manager.

Ajouter des nœuds manager pour la tolérance aux pannes du cluster Swarm

Tout comme le cluster Elasticsearch, Swarm a besoin de plusieurs nœuds de type manager afin d’assurer : l’état du cluster, les services de planification, etc.

De plus, il est nécessaire d’avoir une tolérance aux pannes, comme le cluster Elasticsearch. Il est important de conserver un nombre impair de nœuds manager. Cela garantit que le quorum reste disponible pour traiter les demandes si le réseau est partitionné en deux ensembles.

https://docs.docker.com/engine/swarm/admin_guide/

Pour promouvoir des nœuds du cluster Swarm en manager, passez la commande suivante :

Dans ce cas :

Maintenant que les nœuds sont déployés, il serait intéressant de pouvoir les identifier afin d’apposer des contraintes lors des déploiements.

Par exemple, les containers ELK de type master pourraient être déployés sur des nœuds spécifiques, les containers de type data sur d’autres, etc.

Dans ce cas, les contraintes de déploiements suivantes :

  • Déployer les containers Elasticsearch de type master sur des nœuds spécifiques

Pour ce faire, il faut ajouter un label sur les nœuds Swarm concernés depuis un nœud manager de la façon suivante :

Pour lister les nœuds avec les labels :

Afin d’avoir une vue du cluster Swarm, les containers qui y sont déployés, il est intéressant d’utiliser le service Visualizer.

Depuis un nœud manager :

Une fois déployé, il est possible d’accéder à Visualizer depuis l’IP du nœud sur le port 8080.

https://docs.docker.com/engine/swarm/ingress/

Vue du cluster Swarm avec Visualizer

Déploiement de la Stack ELK

Prérequis système

Maintenant que Swarm est prêt, il faut remplir certains prérequis système avant de pouvoir déployer la Stack ELK.

En effet, il est nécessaire de désactiver la mémoire SWAP, augmenter le nombre maximal de descripteurs de fichiers ouverts, augmenter le nombre de mmap ou encore augmenter le nombre de connexions qu’Elasticsearch peut demander.

Pour ce faire, éditez le fichier /etc/sysctl.conf et ajoutez les lignes suivantes :

De plus, le démon Docker est souvent démarré avec une limite trop basse pour la mémoire verrouillable. Les containers héritent de cette limite, ce qui pose un problème pour Elasticsearch lorsqu’il tente de verrouiller plus de mémoire que celle autorisée.

Pour regarder les limites du démon Docker :

Alors que dans ce cas il serait préférable de voir unlimited. Pour ce faire :

Vérification :

Vous trouverez toutes les informations nécessaires en suivant ce lien

Explication

La Stack est composée de plusieurs services, définis dans un fichier docker-compose.yml. Il est courant d’utiliser ce format de fichier dans le cadre d’un déploiement de containers, mais de nouvelles fonctionnalités sont ajoutées pour l’orchestrateur Swarm.

Voici le docker-compose final du déploiement :

Afin d’assurer une haute disponibilité des services, il est judicieux de redonder l’ensemble des services.

Des contraintes d’emplacement sont spécifiés pour certains services, ainsi que des modes de déploiement différents, comme le mode global ou le mode replicated.

En mode global, Docker Swarm va s’assurer que chaque nœud du cluster possède une instance du service, alors qu’en mode replicated, Swarm déploiera autant d’instances de ce service que précisé.

Traefik

Traefik est un reverse proxy HTTP et un équilibreur de charge moderne qui facilite le déploiement de micro services. Il sera utilisé en tête des services afin qu’il redirige les requêtes HTTP des frontends vers les backends associés.

Le mode de déploiement est en mode replicated, au nombre de 3.

Ici l’image Docker provient d’un registry privé Gitlab car c’est une image personnalisée. Un certificat SSL ainsi que le fichier de configuration sont ajoutés à cette dernière, qui sera construite et déployée automatiquement grâce à Gitlab CI/CD.

Le fichier traefik.toml est le suivant :

Afin de limiter les accès à certains services tels que Visualizer ou Kibana, il faut dans un premier temps utiliser l’Authentification Basic que propose Traefik. Il suffit de générer un couple user:password de la façon suivante :

Pour plus d’informations concernant les différentes possibilités qu’offre Traefik, rendez-vous ici.

Kibana

Le déploiement du service Kibana est en mode replicated, avec un nombre d’instances égal à 2. Le nœud sur lequel sera déployé Kibana a peu d’importance, l’idée est simplement de s’assurer que ce service soit toujours disponible.

Afin d’avoir la main sur les ressources du cluster et du nœud, les ressources telles que la RAM sont limitées mais aussi réservées.

Enfin, l’ajout de la variable d’environnement JAVA ELASTICSEARCH_HOSTS: http://elastic-coordination:9200 permet aux requêtes envoyées à Kibana de passer par un type de nœud Elasticsearch spécifique, les nœuds de type coordinating qui seront présentées par la suite.

Attention, il faut que le nom DNS du nœud coordinating soit identique au nom du service qui se trouve dans le docker-compose.yml

En utilisant le nom du service et non l’IP d’un nœud du cluster au sein de Swarm, la haute disponibilité du service de routing et de load balancer d’Elasticsearch est assurée, ce grâce au mode de routing mesh de Swarm.

Logstash

Logstash est le service déployé afin de traiter le flux Syslog du routeur de l’entreprise, en deux parties :

  • la partie input, qui spécifie le port d’écoute, le type d’input, et le protocole, ici UDP
  • la partie output, qui redirige le flux vers les services Elasticsearch de type coordinating ainsi que l’index associé. Là l’index est de type année-numerodesemaine, comme vu précédemment.

Elasticsearch

Le cluster Elasticsearch doit avoir plusieurs nœuds maîtres afin d’éviter les problèmes de cerveau divisé, ou split-brain.

Le problème de split-brain se produit lorsque deux parties du cluster ne peuvent pas communiquer et pensent que l’autre partie est hors-service. Ce problème risquerait de faire perdre des données parce que le maître du cluster décide quand de nouveaux indices peuvent être créés, comment les shards sont déplacés, etc.

S’il y a 2 maîtres, l’intégrité des données devient périlleuse parce qu’il y aura 2 nœuds qui pensent être master du cluster, mais chacun de leur côté

Pour éviter la situation du split-brain, il faut utiliser le paramètre suivant :

Ce paramètre indique à Elasticsearch de ne pas élire un maître s’il n’y a pas assez de nœuds maîtres disponibles. Ce n’est qu’à ce moment-là qu’il y aura des élections

Le quorum est calculé de la façon suivante : (nombre de nœuds éligibles au master / 2) + 1.

Dans ce cas, le cluster est composé de 3 nœuds maîtres dédiés et 5 nœuds de données, le quorum est de 2, puisqu’il est nécessaire de seulement compter les nœuds qui sont maîtres éligibles.

https://docs.docker.com/engine/swarm/admin_guide/

Elasticsearch est configuré pour utiliser la découverte multicast prête à l’emploi. La multidiffusion fonctionne en envoyant des pings UDP sur votre réseau local pour découvrir les nœuds. Les autres nœuds Elasticsearch recevront ces pings et répondront. Un cluster est formé peu de temps après.

Le paramètre à appliquer est :

Pour terminer, chaque container doit avoir sa propre fonction au sein du cluster ELK.

Il existe plusieurs type de nœud comme les nœuds master, data, coordinating ou encore ingest. Pour spécifier le type de nœud au container, il faut passer les variables suivantes, en ne mettant la valeur true qu’à un paramètre sur les 3.

Un nœud de type coordinating n’est aucun des trois types précédents, il faut donc tout passer à false.

Pour plus d’informations sur les différents types de nœuds, c’est par .

Déploiement

Maintenant que tous les containers sont paramétrés, il ne reste plus qu’à déployer la Stack à l’aide de la commande suivante :

Comme dit précédemment, la création d’images est automatisée grâce à Gitlab CI/CD et leur stockage est effectué au sein d’un registry privé. C’est la raison pour laquelle il faut utiliserdocker login ainsi que le paramètre –with-registry-auth.

Pour vérifier que la Stack existe :

Afin de vérifier que les différents services s’exécutent et que le nombre de réplicas souhaité est respecté :

Comme vu plus haut, il est possible de voir l’ensemble des containers déployés au sein du cluster. Rendez-vous sur https://visualizer-elk.net-security.fr.

Saisissez admin:admin et vous voilà authentifié, avec l’accès à la vue de Visualizer.

Vue du cluster Swarm avec Visualizer

Parfait ! Maintenant, rendez-vous sur
https://kibana-elk.net-security.fr, saisissez admin:admin. Voici les vues que vous devriez avoir :

Page de lancement de Kibana
Page d’accueil de Kibana

Suite au déploiement de la Stack, il est nécessaire de mettre en place le nombre de réplicas pour les indexes avant de rediriger le flux Syslog vers Logstash.

La modification du nombre de réplicas d’un index ne peut se faire qu’avant la création de ce dernier.

Pour ce faire, il faut créer un template et pousser le fichier de configuration suivant sur n’importe quel nœud du cluster Elasticsearch (au sein d’un container) :

Afin de le déployer, voici la commande à lancer :

Pour terminer, il ne reste plus qu’à rediriger le flux de l’ancien puits de logs vers le SIEM ELK, sur n’importe quel nœud du cluster vers le port 5000.

Haute disponibilité avec keepalived

Le cluster dispose de services hautement disponibles, repartis sur 5 nœuds.

Si deux nœuds de type data sont corrompus, l’intégrité reste assurée. Si deux nœuds de type master sont défaillants, l’ensemble du cluster est encore fonctionnel. Il en est de même avec Logstash et Kibana.

Mais qu’arriverait-il si jamais le nœud qui reçoit la sortie Syslog du routeur de l’entreprise est défaillant ? Il y a ici un SPOF (Single Point Of Failure) qui met à plat la Stack hautement disponible.

Keepalived est une solution (libre et gratuite) « tout en un » de haute disponibilité, de virtualisation de services applicatifs et de répartition de charge. Elle s’appuie entièrement sur des fonctionnalités du noyau Linux et des protocoles standardisés tout en consolidant ces technologies dans une même solution. Keepalived est un outil extrêmement léger, très facile à appréhender, à configurer et à déployer.

Pour continuer sur la lancée de dockerisation, Keepalived sera déployé dans un container, sur chaque hôte du cluster, mais pas au sein de la Stack d’ELK.

Le container est à déployer de la façon suivante :

Attention, bien penser à positionner une priorité différente pour chaque nœud du cluster.

Pour vérifier que l’adresse IP virtuelle VRRP fonctionne sur le bon hôte, voici la commande à lancer sur les hôtes du cluster :

Une fois la vérification faite, il faut modifier l’IP cible du flux Syslog de routeur pour maintenant la faire pointer sur la VIP.

Le cluster est désormais hautement disponible 🙂

Les points à améliorer

La Stack maintenant déployée, il reste certains points à améliorer et à mettre en place, comme :

  • Déployer une Stack de monitoring (Prometheus, Grafana etc.)
  • Gérer la CPU des containers comme la RAM
  • Mettre en place le stockage à chaud et à froid
  • Gérer la rotation des logs (1 an)
  • Configurer les Persistent Queues de Logstash

Je vous parlerai de ces points dans un prochain article.

D’ici là, j’espère que cet article vous aura plu, si vous avez des questions ou des remarques sur ce que j’ai pu écrire n’hésitez pas à réagir avec moi par mail ou en commentaire !

Merci pour votre lecture et à bientôt !

APavone

4 Replies to “Déploiement d’une stack ELK en mode Swarm”

    1. Bonjour,
      il est vrai que de loin ça à l’air d’être une usine à gaz. L’article est particulièrement long, et la mise en place paraît fastidieuse.
      Cependant, que ce soit sous Docker ou non, ELK ou un autre SIEM, je pense que si nous voulons une solution résiliente et performante il y a des études à mener et du coup une mise en place à faire.
      Je pense même que grâce à Docker Swarm c’est beaucoup plus simple à maintenir, surtout au niveau des migrations. Un coup de docker service update et « c’est fini » (voir parallelism).
      Edit: Il ne faut pas oublier que cette solution est open source et gratuite, et que seul le support est payant, ce qui n’est pas négligeable (25 000 euros / an pour 5 nœuds de type data)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.