technique:adminsys:monitoring:metrologie:service_metrics

Collecte des métriques de services

Lorsque les métriques des services sont exposées via un exporter Prometheus, cela signifie simplement que, sur un chemin du domaine (généralement /metrics), les métriques sont accessibles en HTTP. Pour des raisons de sécurité, nous préférons que ces métriques ne soient pas exposées publiquement, et que seul notre scraper vmagent puisse y avoir accès.
Comme l’exporter est exposé via HTTP, et donc derrière Traefik, on peut simplement activer de l’authentification Basic pour permettre uniquement à vmagent de récupérer les métriques.

Du côté de Traefik, on va simplement se baser sur le middleware Basic Auth. Il permet d’activer une authentification Basic sur un router Traefik spécifique.
Prenons l’exemple d’un service Web classique, ici CodiMD. Les labels appliqués sur le conteneur pour exposer le service sont les suivants :

snippet.yaml
traefik.enable: true
traefik.http.routers.codimd-app.entrypoints: websecure
traefik.http.routers.codimd-app.rule: Host(`md.picasoft.net`)
traefik.http.routers.codimd-app.service: codimd-app
traefik.http.services.codimd-app.loadbalancer.server.port: 3000

Le premier label permet d’activer Traefik sur le conteneur. Le second permet de créer un router nommé codimd-app qui sera connecté à l’entrypoint websecure (c’est à dire en HTTPS).
Le troisième label créé une règle indiquant que toutes les requêtes vers md.picasoft.net sont captées par ce router, et le quatrième label indique que les requêtes doivent être envoyées sur un service nommé codimd-app. Enfin le dernier label créé le service codimd-app en indiquant que cela correspond au port 3000 dans le conteneur.

Dans notre cas, un exporter Prometheus écoute sous le chemin /metrics/codimd du service, et un autre sous /metrics/router. On veut donc que tout le trafic vers ce service pour le chemin commençant par /metrics soit soumis à une authentification Basic de Traefik. Pour cela on créé un second routeur. On a ainsi :

snippet.yaml
traefik.enable: true
traefik.http.routers.codimd-app.entrypoints: websecure
traefik.http.routers.codimd-app.rule: Host(`md.picasoft.net`)
traefik.http.routers.codimd-app.service: codimd-app
traefik.http.routers.codimd-metrics.entrypoints: websecure
traefik.http.routers.codimd-metrics.rule: "Host(`md.picasoft.net`) && PathPrefix(`/metrics`)"
traefik.http.routers.codimd-metrics.service: codimd-app
traefik.http.routers.codimd-metrics.middlewares: "codimd-metrics-auth@docker"
traefik.http.middlewares.codimd-metrics-auth.basicauth.users: "test:$$apr1$$waO5zvqJ$$jrty/RULcxryemeBmH3RU0"
traefik.http.services.codimd-app.loadbalancer.server.port: 3000

On retrouve les labels précédents, mais aussi des nouveaux. On créé en effet un second router nommé codimd-metrics, toujours sur l’entrypoint websecure et qui pointe sur le service codimd-app. Cependant ce router a une règle adaptée : Host(md.picasoft.net) && PathPrefix(/metrics). Il capte donc tout le trafic vers ce domaine ET ayant un chemin qui commence par /metrics. Cela va nous permettre d’appliquer le middleware Basic Auth uniquement pour ce chemin.
Pour cela on utilise le label traefik.http.routers.codimd-metrics.middlewares: “codimd-metrics-auth@docker” qui indique qu’il faut utiliser un middleware Traefik nommé codimd-metrics-auth et qui est configuré à l’aide de labels Docker (la partie @docker). C’est le rôle du label suivant, traefik.http.middlewares.codimd-metrics-auth.basicauth.users: “test:$$apr1$$waO5zvqJ$$jrty/RULcxryemeBmH3RU0” qui créé le fameux middleware nommé codimd-metrics-auth, basé sur basicauth, et qui spécifie la chaîne d’authentification Basic Auth.

Pour éviter de versionner la chaîne d’identification, on préfère plutôt utiliser une variable dans le label : traefik.http.middlewares.codimd-metrics-auth.basicauth.users: “${METRICS_AUTH}” et placer la valeur dans un fichier .env.

Pour générer la chaîne d’authenticiation Basic Auth qui est donnée au label Traefik, on commence par définir un nom d’utilisateur (ici codimd) et par générer un mot de passe (par exemple avec pwgen -sB 64). On place ces identifiants dans le pass (dans le dossier Tech/Prometheus-Exporters-Auth).
On utilise ensuite la commande suivante pour générer la chaîne d’authentification qu’il faut renseigner dans le label.

$ echo $(htpasswd -nb USER PASSWORD)
USER:$apr1$4WpORg/6$.bUMzTnrDPivUXfu7.vvP0

Du côté de vmagent il faut préciser les identifiants en question dans le fichier de configuration Prometheus. Pour chaque configuration de service, l’objet basic_auth permet de spécifier que l’exporter nécessite une uathentification Basic. Par exemple pour notre cas (des champs ont été retirés pour se concentrer sur ce qui nous intéresse) :

snippet.yaml
  - job_name: codimd
    metrics_path: "/metrics/codimd"
    scheme: "https"
    basic_auth:
      username: codimd
      password: monpassword

L’inconvénient est que nos identifiants vont se retrouver dans le fichier de configuration, qui est versionné. Pour cela on va donc utiliser un mécanisme de vmagent qui permet de remplacer des valeurs dans le fichier de configuration à l’aide de variables d’environnement. On utilisera donc la configuration suivante :

snippet.yaml
  - job_name: codimd
    metrics_path: "/metrics/codimd"
    scheme: "https"
    basic_auth:
      username: "%{CODIMD_METRICS_USER}"
      password: "%{CODIMD_METRICS_PASSWORD}"

Il ne reste plus que à fournir les 2 variables d’environnement en question à vmagent. Pour cela on utilise le même mécanisme de fichiers de secrets que l’on utilise dans notre repository dockerfiles. On charge ensuite le fichier de variables dans le conteneur vmagent.

  • technique/adminsys/monitoring/metrologie/service_metrics.txt
  • de kyane