Monitoring de mon homelab

Mon moyen pour garder un œil sur l'état de son homelab

Monitoring de mon homelab
Mon dashboard Grafana

Bien monitorer son serveur et les services qu'il sert permet de surveiller les performances et de pouvoir intervenir avant qu'un problème ne pointe le bout de son nez. Autant, il peut être simple de visualiser des logs (à condition de se connecter sur le serveur), autant se représenter la santé du serveur avec de simples metrics peut s'avérer très difficile.

Dans ce billet de blog, je vais présenter les solutions que j'ai sélectionnées pour mon serveur et l'utilisation que j'en fais.

Quelques prérequis

Ici, je vais parler de mon serveur tournant sous Ubuntu 20.04.4 LTS (Focal Fossa). Les outils sont utilisés sous forme de containers Docker et déployés à l'aide de Docker Compose.

Les metrics

Les metrics sont l'ensemble des mesures qui sont réalisées sur le serveur. De la consommation de RAM à la vitesse des ventilateurs en passant par la température d'un processeur, tout est mesurable sur un PC (en utilisant hwinfo par exemple). Dans ce paragraphe, on va s'intéresser aux moyens permettant de collecter ces données et de les mettre à disposition d'un outil d'affichage.

Node-exporter

Comme son nom l'indique, Node-exporter permet de collecter et d'exporter les metrics de notre environnement Linux vers une base de données de type Timeseries (Prometheus par exemple).

node-exporter:
  image: "prom/node-exporter"
  container_name: "node-exporter"
  depends_on:
    - "grafana"
  restart: "unless-stopped"
  ports:
    - "9100:9100"

Node-exporter n'a pas besoin de configuration particulière pour l'utilisation que j'en ai.

cAdvisor

L'outil suivant permet de surveiller les metrics de chaque container Docker qui tourne sur mon serveur. cAdvisor, pour Container Advisor, est un outil développé par Google, mais reste open-source. Il monitore les fonctions vitales de chaque container comme la consommation réseau, mémoire et CPU puis les exporte vers la base de donnée (Prometheus).

cadvisor:
  image: "gcr.io/cadvisor/cadvisor"
  container_name: "cadvisor"
  depends_on:
    - "grafana"
  restart: "unless-stopped"
  command:
    - "--disable_metrics=accelerator,diskIO,process,disk,hugetlb,resctrl,udp,advtcp,tcp"
    - "--housekeeping_interval=55s"
    - "--docker_only"
  volumes:
    - "/:/rootfs:ro"
    - "/var/run:/var/run:rw"
    - "/sys:/sys:ro"
    - "/var/lib/docker/:/var/lib/docker:ro"
  expose:
    - "8080"
🔎
Dans la configuration ci-dessus, certains metrics ont été désactivés pour des raisons de performance. cAdvisor est assez gourmand si on ne le surveille pas.

Prometheus

Prometheus permet de mettre à disposition de l'outil d'affichage les metrics collectées par Node-Exporter et cAdvisor. Il joue ici un simple rôle de base de données de metrics et fait donc l'interface entre la collection (cAdvisor et Node-exporter) et l'affichage.

prometheus:
  image: "prom/prometheus"
  container_name: "prometheus"
  restart: "unless-stopped"
  volumes:
    - "/home/louison/turbonas/monitoring/prometheus:/etc/prometheus/"
    - "prometheus-data:/prometheus"
  command:
    - "--config.file=/etc/prometheus/prometheus.yml"
  ports:
    - "9000:9090"

Prometheus a besoin de savoir qui va lui fournir des données. Pour cela on utilise le fichier prometheus.yaml

global:
  scrape_interval: 5s
  scrape_timeout: 5s 
scrape_configs:
  - job_name: prometheus
    static_configs: 
      - targets:
        - prometheus:9090
  - job_name: node-exporter
    static_configs: 
      - targets:
        - node-exporter:9100
  - job_name: cAdvisor
    static_configs:
      - targets:
        - cadvisor:8080

Prometheus pourrait suffire en lui-même puisque l'on dispose d'une page ou faire des requêtes sur les données, mais cette page est trop minimaliste à mon goût et on lui préférera un outil plus esthétique et puissant.

Capture d'écran d'une requête sur la page web de Prometheus

Les logs

Les logs sont les messages que nous laisse chaque système ou logiciel lorsqu'il se passe quelque chose ou qu'il ne se sent pas bien. Ils peuvent être très utiles pour savoir l'origine d'une panne et même parfois comment la résoudre. Ici, on va voir comment collecter et stocker nos logs.

Promtail

Promtail nous permet de collecter et d'envoyer les logs de ce qu'on souhaite dans Loki. Il est possible d'envoyer des logs système ou des logs venant d'une application qui serait en dehors de l'environnement Docker.

promtail:
  image: "grafana/promtail"
  container_name: "promtail"
  depends_on:
    - "grafana"
  restart: "unless-stopped"
  command:
    - "-config.file=/etc/promtail/promtail-config.yaml"
  volumes:
    - "/var/log:/var/log"
    - "/home/louison/turbonas/monitoring/promtail/promtail-config.yaml:/etc/promtail/promtail-config.yaml"
    - "/home/louison/turbonas/logs:/etc/logs"

Promtail a besoin qu'on lui indique les logs à récupérer dans le fichier promtail-config.yaml

# ports for Promtail configuration
server:
  http_listen_port: 9080
  grpc_listen_port: 0

# location of the file where to save how far Promtail read into files
positions:
  filename: /tmp/positions.yaml

# how to connect to the loki instance
clients:
  - url: http://loki:3100/loki/api/v1/push

# how Promtail can scrap logfiles
scrape_configs:

# local machine logs
- job_name: localhost
  static_configs:
  - targets: # on which servers should Promtail looks
      - localhost
    labels:
      job: varlogs 
      __path__: /var/log/*log # where to find logfiles

# local logs
- job_name: local
  static_configs:
  - targets: # on which servers should Promtail looks
      - localhost
    labels:
      job: locallogs
      __path__: /home/louison/turbonas/logs/*.log # where to find logfiles
🧠
Il est possible d'ajouter des jobs pour tout un tas de choses et notamment des fichiers LOG par exemple !

Le plugin loki-docker-driver

Ce plugin permet de récupérer les logs venant des containers Docker.

On commence par l'installer :

docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions

Puis, on change le driver par défaut dans /etc/docker/daemon.json:

{
    "log-driver": "loki",
    "log-opts": {
        "loki-url": "http://localhost:3100/loki/api/v1/push",
        "loki-batch-size": "400"
    }
}

Ce plugin nous sert ici à rediriger le flux de log Docker vers notre instance Loki. Mais du coup, c'est quoi Loki ?!

Loki

Loki c'est comme Prometheus mais pour les logs. Il permet de stocker et de mettre à disposition les logs envoyés par le plugin loki-docker-driver et Promtail.

loki:
  image: "grafana/loki"
  container_name: "loki"
  depends_on:
    - "grafana"
  restart: "unless-stopped"
  ports:
    - "3100:3100"
  command: 
  - "-config.file=/etc/loki/loki-config.yaml"
  - "--log.level=error"
  volumes:
    - "/home/louison/turbonas/monitoring/loki/loki-config.yaml:/etc/loki/loki-config.yaml"
    - "/home/louison/turbonas/monitoring/loki/tmp:/tmp/loki/"
    - "loki-data:/data/loki"

Loki a besoin d'informations pour fonctionner comme les ports sur lesquels se connecter et la configuration souhaitée. Ces informations sont à renseigner dans le fichier loki-config.yaml

auth_enabled: false

# ports for Promtail configuration
server:
  http_listen_port: 3100
  grpc_listen_port: 9096

common:
  path_prefix: /tmp/loki
  storage:
    filesystem:
      chunks_directory: /tmp/loki/chunks # where to store chunks
      rules_directory: /tmp/loki/rules # where to store rules
  replication_factor: 1
  ring:
    instance_addr: 127.0.0.1
    kvstore:
      store: inmemory

# schema of the database
schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

# alertmanager adress which to send alerts
ruler:
  alertmanager_url: http://localhost:9093

L'affichage

C'est maintenant que commence la partie marrante, l'affichage des données !

Grafana

Grafana est un outil permettant d'afficher des données venant d'un peu partout. Il permet la création de dashboards constitués de tuiles variées comme des graphiques, des courbes, des histogrammes, des logs, du texte, des cartes, etc.

grafana:
  image: "grafana/grafana"
  container_name: "grafana"
  ports:
    - "3000:3000"
  restart: "unless-stopped"
  volumes:
    - "/home/louison/turbonas/monitoring/grafana/provisioning/datasources:/etc/grafana/provisioning/datasources"
    - "/home/louison/turbonas/monitoring/grafana/grafana-data:/var/lib/grafana"

Grafana est l'outil de ce billet qui nécessite le plus de configuration. D'abord les datasources décrites dans le fichier grafana_ds.yaml (ou renseignable dans l'interface):

datasources:
- name: Prometheus
  access: proxy
  type: prometheus
  url: http://prometheus:9090
  isDefault: true
- name: Loki
  access: proxy
  type: loki
  url: http://loki:3100
  isDefault: true

Puis la configuration de l'application dans le fichier grafana.ini:

[server]
domain = grafana.lsarlinmagnus.fr
[users]
allow_sign_up = false
auto_assign_org = true
auto_assign_org_role = Admin
[auth.proxy]
enabled = true
header_name = Remote-User
header_property = username
auto_sign_up = true
headers = Groups:Remote-Group
enable_login_token = false
[date_formats]
full_date = DD-MM-YYYY HH:mm:ss

À présent que notre Grafana est prêt, on va pouvoir se lancer dans la confection du Dashboard. Pour cela, il suffit de se connecter à Gafana, créer un dashboard puis ajouter des panneaux afin d'afficher les données souhaitées.

Mon dashboard pour monitorer mon homelab

Une alternative minimale

Dozzle

Dozzle est une alternative simple et efficace permettant de visualiser les logs des containers et quelques metrics instantanés.

Capture d'écran de Dozzle
dozzle:
  image: amir20/dozzle
  container_name: dozzle
  restart: unless-stopped
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  ports:
    - 9999:8080

Conclusion

Architecture et flux de données

Le monitoring est un bon moyen de prévenir les pannes, de faire évoluer son serveur et d'avoir la meilleure expérience possible. Et puis franchement, c'est agréable à regarder quand ça bouge (tant que c'est pas rouge) !!!