L'observabilité dans Elasticsearch : adopter les standards Prometheus et OpenMetrics pour les indicateurs

Dans cet article de blog, nous aborderons les points suivants :

  • L'importance des standards ouverts
  • Le format d'exposition Prometheus
  • L'observabilité vue par Elastic
  • Trois façons d'exploiter les indicateurs Prometheus via Elasticsearch
  • Un exemple de collecte et de visualisation des indicateurs exposés via l'exportateur Redis de Prometheus

Les standards ouverts

Le site opensource.com propose un article instructif, intitulé  "What are Open Standards?" (Qu'est-ce que les standards ouverts ?). Vous y trouverez bon nombre d'informations passionnantes. Mais quand on a travaillé pendant des années dans une équipe opérationnelle, certains points s'avèrent particulièrement intéressants :

  1. La disponibilité : chacun peut lire et implémenter les standards ouverts.
  2. L'utilisateur final dispose d'un choix maximal.
  3. L'absence de discrimination (neutralité en matière de fournisseurs) : les standards ouverts et les organisations qui les administrent ne favorisent aucun prestataire par rapport à un autre.
  4. L'absence de secrets intentionnels : le standard ne doit dissimuler aucun détail nécessaire à l'interopérabilité de l'implémentation.

Voilà de bonnes raisons d'opter pour les standards ouverts. Mais voyons maintenant pourquoi OpenMetrics s'appuie sur le format d'exposition Prometheus. Lors de ses interventions aux conférences PromCon 2018 et KubeCon + CloudNativeCon North America 2018, Richard Hartmann expliquait pourquoi il était pertinent de créer un standard ouvert s'inspirant du format d'exposition Prometheus :

  • La majorité des formats de données sont propriétaires, difficiles à implémenter, ou les deux.
  • Prometheus est de fait devenu un standard en matière de monitoring cloud-native.
  • La simplicité des données au format d'exposition s'est traduite par une explosion des points de terminaison d'indicateurs compatibles.
  • Le format d'exposition Prometheus s'appuie sur un grand nombre d'expériences opérationnelles, mais seules quelques personnes ont pris part à sa conception.
  • Certains autres projets et fournisseurs sont tentés d'adopter les standards d'un produit "concurrent".

Le format d'exposition Prometheus

Pour en savoir plus sur le format d'exposition, n'hésitez pas à consulter le référentiel Github Prometheus. Mais pour l'heure, prenons un exemple. Disons que je dispose d'un exportateur, l' exportateur Redis d'Oliver006, et que celui-ci publie des indicateurs sur le port 9121 au niveau du point de terminaison /metrics. Ci-dessous, je n'affiche que les informations relatives à l'indicateur Redis "instantaneous ops per second" (opérations instantanées par seconde). Nous y trouvons trois lignes de lecture :

  1. Le texte d'aide (Help)
  2. Le type d'indicateur (en l'occurrence, il s'agit d'une jauge)
  3. Le serveur Redis mesuré (port localhost 6379) et sa lecture actuelle (9 opérations par seconde)

roscigno-prometheus-exposition-format.png

L'observabilité vue par Elastic

Je vous encourage vivement à découvrir l'observabilité vue par Elastic.En attendant, je ne résiste pas au plaisir de partager ici mon passage préféré dans cet article :

Lorsqu'on conçoit et qu'on fabrique un système "observable", l'objectif est de s'assurer que lorsqu'il est mis en production, les opérateurs soient capables de détecter les comportements indésirables (indisponibilité du service, erreurs, ou lenteur des réponses, par exemple) et qu'ils disposent d'informations exploitables pour déterminer la cause du problème avec efficacité (logs d'événements détaillés, informations granulaires sur l'utilisation des ressources, ou encore traces d'applications).

Je partage totalement cet avis et pense que pour exécuter, réparer et gérer les services que nous fournissons, nous avons besoin de l'ensemble des logs, des indicateurs et des informations de trace. En raison de son adoption généralisée et de sa communauté active, Prometheus constitue un élément essentiel de l'observabilité. Le standard OpenMetrics ne fera que le valoriser davantage : qu'ils soient réels ou imaginaires, il abolira les obstacles à l'adoption d'un format d'indicateurs conçu par et pour les opérations, qui s'est naturellement imposé dans le secteur.

La plupart de mes interlocuteurs connaissent très bien la Suite Elastic, aussi connue sous le nom d'ELK, qu'ils utilisent pour le logging. Mais la Suite Elastic a plus d'un tour dans son sac : elle est aussi parfaitement adaptée aux indicateurs d'une manière générale, et aux indicateurs de performance applicative. Pour en savoir plus, je vous invite à consulter ces articles consacrés aux indicateurs, ainsi qu'à APM et au traçage distribué.

L'intégration poussée de la Suite Elastic et du mode d'exportation d'indicateurs propre à Prometheus présente un intérêt certain. Voici les principales raisons qui nous amènent à le penser :

  • Association des indicateurs avec les logs et APM dans Elasticsearch pour les mettre en corrélation dans Kibana. Ce témoignage de l'entreprise NS1 vous en dit plus sur l'association des logs et des indicateurs dans la Suite Elastic.
  • Utilisation d'Elasticsearch comme stockage à long terme pour les indicateurs collectés par le serveur Prometheus, qui ne permet pas nativement le clustering à l'heure actuelle.
  • Vision d'ensemble de tous vos indicateurs, où que se trouvent vos instances Prometheus.Mais quelle est notre approche de ces intégrations ? C'est ce que nous allons voir en détail dans la suite de l'article.

Exemple d'exportateur

Pour cet environnement de démo, j'utilise Google Kubernetes Engine (GKE). J'exécute donc mon application (Metricbeat) et l'exportateur Prometheus dans Kubernetes. Voici un petit aperçu du manifeste d'Oliver006, où l'on voit comment déployer un exportateur Redis en tant que side-car avec l'image Redis. Comme vous pouvez le constater, l'exportateur publie sur le port 9121, qui est le numéro de port attribué par défaut à l'exportateur Redis de Prometheus.

...
  - name: redis-exporter
    image: oliver006/redis_exporter:latest
    resources:
      requests:
        cpu: 100m
        memory: 100Mi
    ports:
    - containerPort: 9121
...

Intégralité du code source disponible sur GitHub

Scraper les indicateurs via le module Prometheus de Metricbeat

Metricbeat est l'agent de transfert léger Elastic conçu pour les indicateurs. Lemodule Prometheus fourni avec Metricbeat vous permet de collecter les indicateurs de trois façons :

  1. Vous pouvez vous connecter au serveur Prometheus sur le port 9090 et extraire les indicateurs déjà collectés grâce à l'API Prometheus Federation (qui permet d'obtenir les indicateurs que collecte Prometheus).
  2. Vous pouvez vous connecter au serveur Prometheus sur le port 9090 via le point de terminaison /metrics (self-monitoring Prometheus).
  3. Vous pouvez vous connecter aux exportateurs Prometheus individuellement et analyser le format d'exposition.

Comment savoir quelle approche à adopter ? Cela dépend de votre niveau de maîtrise du serveur Prometheus. Si vous disposez déjà d'un serveur Prometheus configuré pour scraper les indicateurs, et que vous voulez directement interroger ces données à des fins d'intégration, vous pouvez commencer par les méthodes (1) et (2).

  • En revanche, si vous ne disposez pas du serveur Prometheus ou que vous préférez scraper vos exportateurs en parallèle via différents outils, vous pouvez opter pour la méthode (3).

Remarque : Certaines des fonctionnalités Metricbeat ci-dessus sont disponibles en version bêta dans Metricbeat 7.0. Nous vous recommandons de télécharger la version bêta 7.0 ou de copier les liens du conteneur depuis L'API Prometheus Federation https://www.docker.elastic.co/ , puis d'exécuter la version bêta dans un environnement qui n'est pas en production.

D'une manière générale, on utilise une fédération pour permettre la montée en charge, regrouper des ensembles de données, ou copier les données disponibles à un autre emplacement (pour la reprise après sinistre). Le serveur Prometheus propose un point de terminaison /federation. Elastic se connecte à ce point de terminaison pour copier les indicateurs collectés par Prometheus, pour toutes les raisons évoquées ci-dessus.

...
  - module: prometheus
    period: 10s
    hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"]
    metrics_path: '/federate'
    query:
      'match[]': '{__name__!=""}'
...

Intégralité du code source disponible sur GitHub

Dans l'exemple ci-dessus, la requête est définie sur "tout ce qui a un nom non vide". Si vous ne voulez pas tout copier, la documentation Prometheus vous explique comment définir une condition de correspondance plus restrictive. L'exemple se connecte aussi au serveur Pometheus toutes les dix secondes (mon serveur de démo ne collecte des indicateurs que depuis quelques pods et kube-state-metrics), mais vous pouvez modifier cet intervalle.

La fonctionnalité de self-monitoring Prometheus

Tout comme les exportateurs, Prometheus intègre un point de terminaison /metrics. Cela vous permet de collecter des indicateurs au sujet du serveur Prometheus. La configuration est la suivante :

...
  - module: prometheus
    period: 10s
    hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"]
    metrics_path: /metrics
...

Intégralité du code source disponible sur GitHub

Scraping de l'exportateur Prometheus

Cet aperçu de YAML provient d'un manifeste décrivant le déploiement d'un DaemonSet Metricbeat. Il demande à Metricbeat d'assurer la détection automatique avec kubernetes.labels.app == redis et de lire les indicateurs depuis le port 9121 de ce pod. Souvenez-vous que le containerPort défini pour l'exportateur Redis est 9121.

...
- condition.equals:
    kubernetes.annotations.prometheus.io/scrape: "true"
  config:
    - module: prometheus
      period: 10s
      # Redis pods
      hosts: ["${data.host}:9121"]
      metrics_path: /metrics
...

Une fois Metricbeat déployé, n'importe quel pod qui satisfait à la condition kubernetes.labels.app == redis se voit appliquer le module Prometheus, et les indicateurs sont collectés depuis le side-car de l'exportateur, sur le port 9121.

Mais que serait K8s sans les métadonnées ? Nous allons donc exploiter les métadonnées et la fonctionnalité Autodiscover de Beats. Examinons ce code de remplacement de l'aperçu de YAML ci-dessus :

...
- condition.equals:
    kubernetes.annotations.prometheus.io/scrape: "true"
  config:
    - module: prometheus
      period: 10s
      hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]
      metrics_path: /metrics
...

Intégralité du code source disponible sur GitHub

Cette fois, au lieu de rechercher des exportateurs pour des pods Redis, nous allons en rechercher pour n'importe quel pod dont l'annotation kubernetes.annotations.prometheus.io/scrape est définie sur "true". La fonctionnalité de détection automatique de Prometheus est aussi configurée ainsi. En général, la fonctionnalité Autodiscover de Metricbeat est liée à une annotation contenue dans l'espace de noms elastic.co. Mais comme cet article est consacré à la lecture depuis des exportateurs Prometheus, faisons honneurs aux annotations K8s standards associées à Prometheus. Examinons la liste d'hôtes présentée plus haut :

hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]

Vous aurez remarqué que nous ne codons plus le port 9121 en dur, puisqu'il s'agit du port de l'exportateur Redis. L'annotation prometheus.io/port est définie sur le numéro de port de l'exportateur. Pour un aperçu plus complet, voici une portion de code du fichier guestbook.yaml où ces annotations étaient définies :

...
kind: Deployment
metadata:
  name: redis-master
spec:
  replicas: 1
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
      labels:
        app: redis
...

Intégralité du code source disponible sur GitHub

Quand je vous disait que K8s ne serait pas K8s sans les métadonnées...

Quand visualisation rime avec information

Transférer des données vers la Suite Elastic, c'est bien. Pouvoir interagir avec ces données, c'est mieux. Dans la vidéo ci-dessous, nous allons découvrir comment créer des visualisations utiles grâce aux indicateurs Redis scrapés par Prometheus (puis importés dans la Suite Elastic), mais aussi grâce aux événements Kubernetes collectés depuis kube-state-metrics directement avec Metricbeat.

Pour aller plus loin et obtenir des instructions détaillées après avoir regardé la vidéo, n'hésitez pas à consulter ce référentiel d'exemple.

Cap sur l'observabilité

Au paragraphe précédent, nous avons créé une visualisation Kibana pour un indicateur Redis clé (opérations instantanées par seconde), exposé par l'exportateur Redis d'Oliver006. La prochaine étape sera de collecter des logs, puis de créer un tableau de bord, afin d'associer logs et indicateurs dans nos applications.

Pour en savoir plus sur la collecte de logs dans un environnement Kubernetes, je vous suggère de suivre les instructions disponibles dans le référentiel GitHub elastic/examples. En quelques minutes à peine, Filebeat, Metricbeat et Packetbeat pourront commencer à collecter les données et à les publier dans Elasticsearch. Les différents agents Beats intègrent des exemples de tableau de bord, mais vous pouvez bien sûr créer vos propres visualisations pour les données Prometheus, et associer les différentes visualisations pour créer vos propres tableaux de bord, adaptés à vos méthodes de travail. Et si vous rencontrez un problème ou que vous avez envie de parler d'observabilité, les forums de discussion sont là pour ça.