Kubernetes Nodes Logs avec Promtail

Sommaire

Promtail est un agent applicatif permettant de transmettre des logs vers une instance Loki, outil de gestion de logs de la société Grafana Labs. L'outil fonctionne très bien en environnement Kubernetes, récupérant l'ensemble des logs des conteneurs, avec des notions d'auto-discovery et gestion de labels.

Il est très simple à installer en tant que daemonset dans un cluster, pour y récupérer les logs des conteneurs. Mais parfois on a besoin de récupérer également les logs des nodes du cluster, sur lesquels tournent ces conteneurs.

Ci-après une explication rapide pour la mise en place d'un tel setup.

Promtail logs with Loki & Grafana

Installation simple

Note: Cet article utilise Promtail v2.5.0, la configuration présentée peut différer selon la version que vous utiliserez.

Par défaut, l'installation de Promtail se fait avec un chart Helm, qui fonctionne "out-of-the-box". On considère que Loki et Grafana sont déjà déployés dans le cluster.

1$ helm repo add grafana https://grafana.github.io/helm-charts
2$ helm repo update
3$ helm --install --namespace observability --create-namespace promtail grafana/promtail

On peut voir maintenant que les agents Promtail tournent sur les nodes, et que les logs arrivent dans Loki. Grafana permet l'exploration des logs, tout est bon.

1$ kubectl get pods -l app.kubernetes.io/name=promtail
2NAME READY STATUS RESTARTS AGE
3promtail-47jwn 1/1 Running 0 13m
4promtail-mwkcb 1/1 Running 0 14m

Promtail basic logs

Paramétrage

Pour l'instant, on a un setup simple, mais fonctionnel.

Cependant, pour les besoins exprimés cela ne suffit pas, car on doit transmettre les logs du répertoire /var/log/ des nodes vers Loki, ici plus spécifiquement le fichier /var/log/syslog. Pourquoi ne pas utiliser ces daemonsets pour cela ? On va configurer Promtail en ce sens.

Montage du dossier hôte

Tout d'abord, on doit monter le dossier de l'hôte /var/log sur le pod. On montera le dossier dans /var/log/host pour éviter tout problème d'écrasement / nommage.

On spécifie cela dans les paramètres du chart Helm, dans un fichier custom-values.yaml :

 1# Mount folder /var/log from node
 2extraVolumes:
 3  - name: node-logs
 4    hostPath:
 5      path: /var/log
 6
 7extraVolumeMounts:
 8  - name: node-logs
 9    mountPath: /var/log/host
10    readOnly: true

On upgrade le chart helm, et le dossier /var/log/host est bien là, parfait !

1$ helm upgrade --install --namespace observability promtail grafana/promtail -f custom-values.yaml
2$ kubectl exec -it promtail-mwkcb --mount | grep /var/log/host
3/dev/sda1 on /var/log/host type ext4 (ro,relatime,data=ordered)

Avant d'aller plus loin, voyons si l'on peut lire les fichiers à l'intérieur :

1$ kubectl exec -it promtail-mwkcb --tail /var/log/host/syslog
2tail: cannot open ‘/var/log/host/syslog’ for reading: Permission denied
3command terminated with exit code 1

Mmmm, il y a quelque chose d'incorrect ici, voyons les permissions des fichiers :

1$ kubectl exec -it promtail-mwkcb — ls -l /var/log/host/syslog
2-rw-r---- 1 102 adm 72327736 Jun 29 20:01 /var/log/host/syslog

Le fichier appartient à l'utilisateur avec l'ID 102 et groupe "adm". Avec getent on a un peu plus d'infos sur ce groupe :

1$ kubectl exec -it promtail-mwkcb -- getent group adm
2adm:x:4:

Donc, si l'on veut que promtail puisse lire ce fichier, il faut ajouter des contextes de sécurité avec l'option fsGroup, que l'on définit dans les custom values du chart Helm :

1# Set fsGroup to allow syslog file reading
2podSecurityContext:
3  fsGroup: 4

On upgrade le chart Helm, et on vérifie l'accès au fichier :

1$ helm upgrade promtail grafana/promtail -f custom-values.yaml
2$ kubectl exec -it promtail-2dbh9 -- tail /var/log/host/syslog
3Jun 29 20:16:28 worker-pool-node-d5353e kubelet[1596]: I0629 20:16:28.374480 1596 clientconn.go:897] blockingPicker: the picked transport is not ready, loop back to repick
4Jun 29 20:16:28 worker-pool-node-d5353e docker[1888]: I0629 20:16:28.375267 1 utils.go:81] GRPC call: /csi.v1.Node/NodeGetVolumeStats

Cela semble mieux ! Maintenant on peut lire les fichiers du node depuis notre pod Promtail.

Configuration Promtail

On va ensuit configurer Promtail pour lire (scrape) ce nouveau fichier, avec un simple "File Target Discovery" (voir ici). On y rajoute quelques labels pour les retrouver facilement dans Loki plus tard. Toujours dans les custom values :

 1# Scrape config to read syslog file from node
 2config:
 3  snippets:
 4    extraScrapeConfigs: |
 5      # Add an additional scrape config for syslog
 6      - job_name: node-syslog
 7        static_configs:
 8        - targets:
 9          - localhost
10          labels:
11            job: node/syslog
12            __path__: /var/log/host/syslog      

On upgrade une fois de plus le chart, et on peut maintenant voir les logs syslog du node, en plus des logs des conteneurs, être transmis dans Loki, nickel !

Nodes logs with Promtail

Ajout de labels dynamiques

Les logs sont là, mais avoir des labels supplémentaires ne serait pas de refus, comme le nom du node.

On va alors utiliser l'option -config.expand-env qui récupère les variables d'environnement, et on va les rajouter dans la configuration de Promtail :

 1# Allow environment variables usage
 2extraArgs:
 3  - -config.expand-env=true
 4
 5# Scrape config to read syslog file from node
 6config:
 7  snippets:
 8    extraScrapeConfigs: |
 9      # Add an additional scrape config for syslog
10      - job_name: node-syslog
11        static_configs:
12        - targets:
13          - localhost
14          labels:
15            job: node/syslog
16            __path__: /var/log/host/syslog
17            node_name: '${HOSTNAME}'      

On upgrade une dernière fois le chart, on vérifie les logs dans Grafana... Et voilà ! On a bien les logs des nodes, avec les labels qui vont bien !

Labelled nodes logs with Promtail

Récapitulatif

Pour résumer, afin d'avoir les logs des nodes dans Loki en utilisant Promtail, il "suffit" de :

  1. Monter le dossier /var/log du node dans le pod Promtail
  2. Utiliser le bon fsGroup pour pouvoir lire les fichiers
  3. Ajouter une configuration de scraping static_configs
  4. Utiliser les variabels d'environnement pour ajouter des labels

On retrouvera le fichier custom-values.yaml pour déployer le chart Helm dans mon dépôt GitLab.

On peut maintenant fouiner dans les logs, vérifier ce qu'il ne va pas sur les nodes, et plus encore... Bonne recherche !