Introduction
L'an dernier, nous avons abordé différentes solutions de supervision (Nagios et Zabbix principalement), et nous avons mis en place une solution simple de supervision d'une petite infrastructure Web lors du TP.
Cette année, nous allons aller un peu plus loin, lors d'un TP nettement plus complet, qui nous permettra d'aborder différentes méthodes de collecte de métriques systèmes, réseau, mais aussi applicatives et "Business", tout en créant différents /dashboards/ adaptés à chaque type de métriques et surtout, adaptés aux besoins de l'utilisateur final.
En effet, un administrateur systèmes et réseaux, un développeur, ou un gestionnaire n'ont pas les mêmes besoins de visibilité sur l'ensemble du système d'information.
Dans le cadre d'un utilisateur "Business", par exemple, peu lui importe de savoir le temps CPU utilisé sur la 26è VM frontale de l'applicatif. Par contre, il sera sûrement intéressé par le nombre d'utilisateurs enregistrés de la plateforme, le nombre de clics sur tel article, le nombre de transactions, leur valeur moyenne, le temps de réponse de la plateforme, ou l'impact business d'une panne, etc...
Autant d'informations que nous pouvons collecter soit directement en base de données, soit via de l'analyse de logs, soit via des appels "internes" à l'API de notre applicatif, etc, et que bien évidemment nous pouvons stocker dans le temps afin d'obtenir un bon visuel de l'évolution des "affaires".
Comme vous effectuez en même temps votre TP de maintenance op', on va monitorer ces machines avec différents outils
Indicateurs systèmes et réseaux
On va ici retrouver nos classiques métriques CPU, RAM, I/Os disques, espace disque, réseau, l'état de la réplication de nos données (DRBD ou autre), l'état de nos machines physiques, virtuelles, de notre équipement réseau (SNMP anyone? ), bref tous les indicateurs "proches" du matériel utilisé. Comme on l'a abordé l'année précédente, je ne vais pas m'attarder outre-mesure sur ces concepts
Indicateurs applicatifs
État des services
- Mes services s'exécutent-ils?
- répondent-ils correctement aux requêtes que je leur fais passer?
- répondent-ils rapidement sur une requête?
Métriques des services
- Nombre de requêtes par seconde (load-balancer, serveurs web, bases de données, caches...)
- Temps d'exécution moyen par requête
- Taux d'invalidation dans le cas des caches
- /Key efficiency/ (bdds), locks, etc
- Métriques générées via les logs (good ol' syslog, ELK, Graylog, Splunk, etc): hits/s, taux d'erreurs, etc
Indicateurs "Business"
Métriques métier
Exemple: call center
- Nombre d'appels/unité de temps
- Taux de résolution des tickets
- Temps de résolution moyen des tickets
- Le tout par tech' pour envoyer à la RH :] - euh, pardon, faire de belles stats
- Taux de satisfaction clients (petit email après interv -> sondage -> bdd -> datas remontées dans la supervision)
Exemple: Plateforme Web
- nombre de visiteurs uniques, de pages vues
- taux de création d'utilisateurs, nombre d'utilisateurs
- URLs les plus visitées
- taux de clics (pub & co
)
- Géolocalisation des utilisateurs (miam)
- ratio bots/organiques
Mise en place d'une solution d'analyse des logs
Graylog
Prérequis
Une VM avec 2Go ou plus de RAM, 10Go de disque, docker et docker-compose installés.
Stack Graylog
Aussi bon que soit ELK, il est quand même plutôt gourmand en ressources. On va donc utiliser une alternative plus légère afin que le TP puisse se dérouler sans faire exploser vos machines perso: Graylog. Et, oui, c'est de l'open-source pondu par... Oracle
Graylog s'appuie sur MongoDB et ElasticSearch, dès lors on va aussi vouloir installer leurs images docker respectives. La recette est un poil plus compliquée que celle de portainer (notez qu'avec portainer, plus besoin des paramètres /network/ et /volumes/, c'est lui qui s'occupe de tout )
(ici le hash du mot de passe est celui du super mot de passe bien balaise: "admin" :p)
Docker Compose: déployer rapidement Graylog
Votre VM doit impérativement disposer des instructions AVX2 (par exemple, dans la configuration matérielle de votre VM proxmox, choisissez le type de CPU x86-64-v2-AES au minimum). Dans le cas contraire, MongoDB (et donc, toute la stack qui en dépend) ne pourra pas se lancer.
Une fois cette vérification effectuée, il nous suffit d'utiliser cette stack docker compose:
services:
mongodb:
image: "mongo:7.0"
restart: "on-failure"
networks:
- graylog
volumes:
- "mongodb_data:/data/db"
- "mongodb_config:/data/configdb"
# For DataNode setup, graylog starts with a preflight UI, this is a change from just using OpenSearch/Elasticsearch.
# Please take a look at the README at the top of this repo or the regular docs for more info.
# Graylog Data Node: https://hub.docker.com/r/graylog/graylog-datanode
# Make sure this is set on the host before starting:
# echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
# sudo sysctl -p
datanode:
image: "${DATANODE_IMAGE:-graylog/graylog-datanode:7.0}"
hostname: "datanode"
environment:
GRAYLOG_DATANODE_NODE_ID_FILE: "/var/lib/graylog-datanode/node-id"
# GRAYLOG_DATANODE_PASSWORD_SECRET and GRAYLOG_PASSWORD_SECRET MUST be the same value
GRAYLOG_DATANODE_PASSWORD_SECRET: "somepasswordpeppersupersecret"
GRAYLOG_DATANODE_MONGODB_URI: "mongodb://mongodb:27017/graylog"
ulimits:
memlock:
hard: -1
soft: -1
nofile:
soft: 65536
hard: 65536
ports:
- "127.0.0.1:8999:8999/tcp" # DataNode API
- "127.0.0.1:9200:9200/tcp"
- "127.0.0.1:9300:9300/tcp"
networks:
- graylog
volumes:
- "graylog-datanode:/var/lib/graylog-datanode"
restart: "on-failure"
# Graylog: https://hub.docker.com/r/graylog/graylog-enterprise
graylog:
hostname: "server"
image: graylog/graylog:7.0
depends_on:
mongodb:
condition: "service_started"
datanode:
condition: "service_started"
entrypoint: "/usr/bin/tini -- /docker-entrypoint.sh"
environment:
GRAYLOG_NODE_ID_FILE: "/usr/share/graylog/data/data/node-id"
# GRAYLOG_DATANODE_PASSWORD_SECRET and GRAYLOG_PASSWORD_SECRET MUST be the same value
GRAYLOG_PASSWORD_SECRET: "somepasswordpeppersupersecret"
GRAYLOG_ROOT_PASSWORD_SHA2: "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
GRAYLOG_HTTP_EXTERNAL_URI: "http://192.168.1.191:9000/"
GRAYLOG_MONGODB_URI: "mongodb://mongodb:27017/graylog"
ports:
- "5044:5044/tcp" # Beats
- "1514:1514/udp" # Syslog
- "1514:1514/tcp" # Syslog
- "5140:5140/udp" # Syslog
- "5140:5140/tcp" # Syslog
- "5555:5555/tcp" # RAW TCP
- "5555:5555/udp" # RAW UDP
- "9000:9000/tcp" # Server API
- "12201:12201/tcp" # GELF TCP
- "12201:12201/udp" # GELF UDP
#- "127.0.0.1:10000:10000/tcp" # Custom TCP port
#- "127.0.0.1:10000:10000/udp" # Custom UDP port
- "13301:13301/tcp" # Forwarder data
- "13302:13302/tcp" # Forwarder config
networks:
- graylog
volumes:
- "graylog_data:/usr/share/graylog/data/data"
restart: "on-failure"
networks:
graylog:
driver: "bridge"
volumes:
mongodb_data:
mongodb_config:
graylog-datanode:
graylog_data:
Bien sûr, il faut maintenant alimenter Graylog. Pour celà, on peut utiliser /rsyslog/, HAProxy permet aussi de directement envoyer ses logs à un syslog distant (log IP:port local0 par exemple dans la configuration globale d'HAProxy), de même, on peut aussi utiliser une /Input/ Graylog de type Raw Text (TCP) et y envoyer les résultats de nos scripts (cronnés par exemple) d'extraction de statistiques de base de données, et ainsi de suite, par exemple en pipant le résultat d'une requête SQL dans netcat, qui lui même envoie le résultat en TCP à l'input Graylog voulue.
Il faut ensuite configurer (System/Inputs) une Input de type RawPlaintext/UDP, en mode global, sur le port 1514, écoutant sur 0.0.0.0
Sur notre haproxy, on va modifier sa configuration pour lui faire envoyer ses logs à Graylog:
global
log /dev/log local0
log /dev/log local1 notice
log 192.168.1.191:1514 local0
Où 192.168.1.191 est l'IP de notre VM Graylog.
Pour finir, au niveau de notre input Graylog, on va cliquer sur 'Manage Extractors' pour pouvoir configurer notre premier extracteur de logs. Le but est d'extraire, via un Grok Pattern ou une Regex, les informations voulues des lignes de log envoyées par Haproxy à Graylog. Dans notre exemple, l'adresse IP pour laquelle nous utiliserons le Grok Pattern % puis ensuite, via une expression régulière, un autre extracteur pour extraire le code de retour HTTP (200, 404, 503...), et enfin, créer un dashboard nous permettant d'afficher les données extraites (grokées) via de beaux graphes