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.
Configuration Traefik
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
.
Génération authentification Basic
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
Configuration vmagent
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.