K3S et la supervision avec VictoriaMetrics, kube-state-metrics, node-exporter et Grafana

Pour faire suite à l’installation d’une instance Kubernetes avec K3S , il est maintenant l’heure de préparer l’observabilité dans l’ensemble du cluster. Dans cet article, j’utiliserai Kubernetes v1.33, VictoriaMetrics v1.124, et Helm 3+.

VictoriaMetrics servira de puits de métriques, Grafana sera utilisé pour afficher ces métriques dans des tableaux de bord, node-exporter pour obtenir les métriques de la machine sous-jacente et kube-state-metrics récoltera les métriques des objets du cluster dans Kubernetes.

Installation de kube-state-metrics#

L’installation de kube-state-metrics nécessite une attention particulière pour garantir des données cohérentes et fiables. Il est crucial de respecter la matrice de compatibilité entre kube-state-metrics et la version du cluster Kubernetes, disponible dans la documentation du dépôt GitHub. Dans cet exemple, la version 2.16 de kube-state-metrics sera utilisée.

Via Helm, nous allons ajouter le dépôt, mettre à jour la liste des dépôts, récupérer la version à installer et déployer l’outil.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm search repo prometheus-community/kube-state-metrics -l | head -n 6

NAME                                    CHART VERSION APP VERSION DESCRIPTION
prometheus-community/kube-state-metrics 6.1.4         2.16.0      Install kube-state-metrics to generate and expo...
prometheus-community/kube-state-metrics 6.1.3         2.16.0      Install kube-state-metrics to generate and expo...
prometheus-community/kube-state-metrics 6.1.2         2.16.0      Install kube-state-metrics to generate and expo...
prometheus-community/kube-state-metrics 6.1.1         2.16.0      Install kube-state-metrics to generate and expo...
prometheus-community/kube-state-metrics 6.1.0         2.16.0      Install kube-state-metrics to generate and expo...

Je vais prendre la dernière version disponible au 08/2025, soit la version 6.1.4. Il n’est pas nécessaire de modifier les valeurs de cette charte Helm. Le déploiement s’effectuera dans le namespace kube-system, réservé aux outils d’infrastructure comme kube-state-metrics. Déployez l’outil avec la commande suivante :

helm install kube-state-metrics prometheus-community/kube-state-metrics \
  --namespace supervision \
  --create-namespace \
  --version 6.1.4 \
  --set rbac.create=true \
  --set serviceAccount.create=true

et le tour est joué.

Quelques métriques de la machine physique ou virtuelle#

Qu’importe où est installée votre instance Kubernetes, il est bon de récupérer les métriques de la machine sous-jacente. Installons et exploitons node-exporter. Il existe d’autres outils comme Netdata , mais presque tous les tableaux de bords sont configurés pour utiliser les métriques de node-exporter plutôt que Netdata.

Déployons node-exporter, avec Helm, une nouvelle fois. Les valeurs par défauts de la chart sont correctes (création d’un serviceAccount, pas d’utilisateur root, montage des partitions en lecture seule, UID et GID spécial, récupération des hostNetwork: true et hostPID: true déjà activés). Si besoin, vous pouvez faire un $ helm show values prometheus-community/prometheus-node-exporter > node-exporter_values.yaml pour récupérer les valeurs et les modifier à votre guise.

La commande de déploiement est la suivante : $ helm upgrade --install node-exporter prometheus-community/prometheus-node-exporter -n supervision. L’outil est léger, il ne consommera pas beaucoup de ressources dans votre cluster et vous permettra d’avoir de nombreuses métriques intéressantes. Un nouveau pod sera créé dans le namespace supervision. Vous aurez ainsi des métriques pour le processeur (sockets et cœur), mémoire vive, disque dur et tant d’autres.

VictoriaMetrics#

Comme toute application déployée avec Helm, vous devez ajouter le dépôt, mettre à jour la liste des dépôts puis lancer l’installation. De plus, pour afficher les six dernières versions disponibles, utilisez head en plus de helm.

helm repo add vm https://victoriametrics.github.io/helm-charts/
helm repo update
helm search repo vm/victoria-metrics-single -l | head -n 6

Désormais, il est possible de récupérer les valeurs pour les modifier selon votre environnement. C’est par ailleurs nécessaire pour que le déploiement soit au plus juste selon votre contexte. Extrayez-les avec la commande helm show values oci://ghcr.io/victoriametrics/helm-charts/victoria-metrics-single –-version 0.24.3 > vmetrics_values.yaml. Ici, je récupère les valeurs de la chart en version 0.24.3, correspondant à VictoriaMetrics 1.124.0.

Ce que j’apprécie avec VictoriaMetrics et helm, c’est sa simplicité de mise en place et de configuration dans une instance comme k3s. Il y a quelques valeurs à modifier, notamment plusieurs lignes :

  • Vers la ligne 185, saisissez votre storageClassName: "", pour ma part, storageClassName: "longhorn".
  • À la ligne 198, ajustez la taille de stockage. Par défaut, elle est de 16 Go, mais modifiez-la selon la durée de rétention souhaitée. Étant donné que je ne veux pas conserver les métriques indéfiniment, que l’espace est limité et que peu de services nécessitent une supervision, je réduis la taille à 12 Gi.
  • Des limitations peuvent être appliquées à partir de la ligne 209. Soyez prudent lors de la saisie des valeurs, car si elles sont trop basses, l’application ne fonctionnera pas et des « OOMKilled » apparaîtront dans les logs de VictoriaMetrics. Pour le moment, je ne connais pas le besoin en CPU ni en RAM, alors je ne vais pas les fixer pour le moment.
  • Vers la ligne 250, l’ingress est par défaut désactivé. Je laisse volontairement le paramètre à false, puisque le service sera accessible par la gateway-api gérée par Cilium.
  • Dans le bloc “server: scrape:”, changez false par true, pour que VictoriaMetrics génère sa configuration depuis le bloc scrape_config juste en dessous.
  • À partir de la ligne 440, la configuration scrape_config est définie et déjà préconfigurée pour Kubernetes. Les quelques services internes qui fonctionnent dans le cluster seront déjà scrappés.

Toutes les options sont disponibles à cette adresse - VictoriaMetrics documentation .

Mon bloc de scrape_config avec kube-state-metrics et node-exporter ressemble à ça :

scrape:
  # -- If true scrapes targets, creates config map or use specified one with scrape targets
  enabled: true
  config:
    global:
      scrape_interval: 30s

    # Scrape targets
    scrape_configs:
      - job_name: "kube-state-metrics"
        static_configs:
          - targets: ["kube-state-metrics.supervision.svc.cluster.local:8080"]
        scheme: http

      - job_name: "node-exporter"
        static_configs:
          - targets:
              [
                "node-exporter-prometheus-node-exporter.supervision.svc.cluster.local:9100",
              ]
        scheme: http

Déployons maintenant VictoriaMetrics avec les valeurs personnalisées, à l’aide la commande helm upgrade --install vms oci://ghcr.io/victoriametrics/helm-charts/victoria-metrics-single -f vmetrics_values.yaml --version 0.24.3 -n supervision. La version 0.24.3 de la chart Helm sera employée. Un nouveau namespace de supervision sera créé s’il n’existe pas déjà, et les options de configuration du fichier vmetrics_values.yaml seront utilisées pour personnaliser les informations.

Le résultat attendu doit être le suivant :

helm upgrade --install vms oci://ghcr.io/victoriametrics/helm-charts/victoria-metrics-single -f vmetrics_values.yaml --version 0.24.3 -n supervision
Pulled: ghcr.io/victoriametrics/helm-charts/victoria-metrics-single:0.24.3
Digest: sha256:271e7ba04d8dae886080cd6d0900251cc5e590fc3b5b4e34cd58ae5c35d7f230
Release "vms" has been upgraded. Happy Helming!
NAME: vms
LAST DEPLOYED: Fri Aug 22 18:50:13 2025
NAMESPACE: supervision
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
The VictoriaMetrics write api can be accessed via port 8428 on the following DNS name from within your cluster:
    vms-victoria-metrics-single-server.supervision.svc.cluster.local.

Metrics Ingestion:
  Get the Victoria Metrics service URL by running these commands in the same shell:
    export POD_NAME=$(kubectl get pods --namespace supervision -l "app=" -o jsonpath="{.items[0].metadata.name}")
    kubectl --namespace supervision port-forward $POD_NAME 8428

  Write URL inside the kubernetes cluster:
    http://vms-victoria-metrics-single-server.supervision.svc.cluster.local.:8428/<protocol-specific-write-endpoint>

  All supported write endpoints can be found at https://docs.victoriametrics.com/single-server-victoriametrics/#how-to-import-time-series-data

  E.g: for Prometheus:
    http://vms-victoria-metrics-single-server.supervision.svc.cluster.local.:8428/api/v1/write

Read Data:
  The following URL can be used as the datasource URL in Grafana:
    http://vms-victoria-metrics-single-server.supervision.svc.cluster.local.:8428

kubectl get pods -n supervision
NAME                                   READY   STATUS    RESTARTS   AGE
vms-victoria-metrics-single-server-0   1/1     Running   0          7m53s

kubectl -n supervision describe pod vms-victoria-metrics-single-server-0
Name:             vms-victoria-metrics-single-server-0
Namespace:        supervision
Priority:         0
Service Account:  vms-victoria-metrics-single-server
Node:             vps-1/<ip_server>
Start Time:       Fri, 22 Aug 2025 18:48:38 +0000
Labels:           app=server
                  app.kubernetes.io/instance=vms
                  app.kubernetes.io/managed-by=Helm
                  app.kubernetes.io/name=victoria-metrics-single
                  app.kubernetes.io/version=v1.124.0
                  apps.kubernetes.io/pod-index=0
                  controller-revision-hash=vms-victoria-metrics-single-server-85c6cc85bd
                  helm.sh/chart=victoria-metrics-single-0.24.3
                  statefulset.kubernetes.io/pod-name=vms-victoria-metrics-single-server-0
Annotations:      <none>
Status:           Running
IP:               10.42.0.232
IPs:
  IP:           10.42.0.232
Controlled By:  StatefulSet/vms-victoria-metrics-single-server
Containers:
  vmsingle:
    Container ID:  containerd://69817a94bd007cf7678eb1ed663d81dadc02d49cafe3cd1aa264fc941cb28a74
    Image:         victoriametrics/victoria-metrics:v1.124.0
    Image ID:      docker.io/victoriametrics/victoria-metrics@sha256:2d7fc1f0f19160a06b0d72daff6c96ddd58de1a4560d1d827aa79633b5382524
    Port:          8428/TCP
    Host Port:     0/TCP
    Args:
      --envflag.enable
      --envflag.prefix=VM_
      --httpListenAddr=:8428
      --loggerFormat=json
      --retentionPeriod=1
      --storageDataPath=/storage
    State:          Running
      Started:      Fri, 22 Aug 2025 18:48:52 +0000
    Ready:          True
    Restart Count:  0
    Liveness:       tcp-socket :http delay=30s timeout=5s period=30s #success=1 #failure=10
    Readiness:      http-get http://:http/health delay=5s timeout=5s period=15s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /storage from server-volume (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-lsxq8 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       True
  ContainersReady             True
  PodScheduled                True
Volumes:
  server-volume:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  server-volume-vms-victoria-metrics-single-server-0
    ReadOnly:   false
  kube-api-access-lsxq8:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason                  Age                    From                     Message
  ----     ------                  ----                   ----                     -------
  Normal   Scheduled               8m38s                  default-scheduler        Successfully assigned supervision/vms-victoria-metrics-single-server-0 to vps-1
  Normal   SuccessfulAttachVolume  8m28s                  attachdetach-controller  AttachVolume.Attach succeeded for volume "pvc-ee5b9e3e-5c8f-414b-b6ba-c0e8a74298de"
  Normal   Pulling                 8m26s                  kubelet                  Pulling image "victoriametrics/victoria-metrics:v1.124.0"
  Normal   Pulled                  8m24s                  kubelet                  Successfully pulled image "victoriametrics/victoria-metrics:v1.124.0" in 2.654s (2.654s including waiting). Image size: 17167494 bytes.
  Normal   Created                 8m24s                  kubelet                  Created container: vmsingle
  Normal   Started                 8m24s                  kubelet                  Started container vmsingle

Quelques commandes supplémentaires :

  • mettre à jour VictoriaMetrics : récupérez les valeurs de la nouvelle version, puis déployez-la : helm show values oci://ghcr.io/victoriametrics/helm-charts/victoria-metrics-single –-version <nouvelle_version> > vmetrics_values.yaml && vim vmetrics_values.yaml && helm upgrade --install vms oci://ghcr.io/victoriametrics/helm-charts/victoria-metrics-single –-version <nouvelle_version> -f vmetrics_values.yaml --create-namespace -n supervision
  • supprimer tout le déploiement : helm uninstall vms -n supervision
  • trouver le nom du service VictoriaMetrics (pour le mettre dans la datasource grafana) : kubectl get svc -n supervision |grep victoria- |awk '{print $1}'
  • accéder à l’interface de victoriametrics : kubectl -n supervision port-forward svc/vms-victoria-metrics-single-server 8428:8428 ; en accédant à l’interface web (http://localhost:8428 ), plusieurs liens vous permettront de voir les cibles, la configuration, ou encore naviguer dans les métriques.

Lors du déploiement de VictoriaMetrics, des notes apparaissent pour vous aider à configurer VM dans Grafana, ou accéder aux métriques de manière brute.

Read Data:
  The following URL can be used as the datasource URL in Grafana:
    http://vms-victoria-metrics-single-server.supervision.svc.cluster.local:8428

Utilisez l’adresse mentionnée ci-dessus pour permettre à Grafana d’accéder à VictoriaMetrics et d’afficher les métriques dans des tableaux de bord attrayants.

Désormais, passons à Grafana.

Déploiement et configuration de Grafana#

Tout comme les autres applications, ajoutez le dépôt Helm pour Grafana, mettez les dépôts à jour et regardez quelles sont les versions disponibles :

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm search repo grafana/grafana -l | head -n 6
NAME                             CHART VERSION APP VERSION        DESCRIPTION
grafana/grafana                  9.3.4         12.1.0             The leading tool for querying and visualizing t...
grafana/grafana                  9.3.3         12.1.0             The leading tool for querying and visualizing t...
grafana/grafana                  9.3.2         12.1.0             The leading tool for querying and visualizing t...
grafana/grafana                  9.3.1         12.1.0             The leading tool for querying and visualizing t...
grafana/grafana                  9.3.0         12.1.0             The leading tool for querying and visualizing t...

Extrayez-les avec la commande helm show values grafana/grafana > grafana_values.yaml. Ici, je récupère les valeurs de la dernière chart disponible (version 9.3.4 au 08/2025), correspondant à Grafana 12.1.0.

Dans le fichier de valeur, j’ai modifié le nom de la storageClass (ligne 419) et le nom du compte administrateur (ligne 491). Un peu plus bas, ligne 664, vous pouvez ajouter la datasource VictoriaMetrics directement comme source préconfigurée, ce qui est plutôt pratique. Avec la précédente installation, voici à quoi ça ressemble :

datasources:
  datasources.yaml:
    apiVersion: 1
    datasources:
      - name: VictoriaMetrics
        type: prometheus
        url: http://vmsingle-victoria-metrics-single-server.default.svc.cluster.local:8428
        access: proxy
        updateIntervalSeconds: 30
        isDefault: true
        editable: true

Il y a un autre bloc intéressant un peu plus bas, qui permet d’ajouter des tableaux de bords dès l’installation de Grafana. La configuration que je vous propose nécessite un accès à l’internet depuis Kubernetes et nécessite un stockage persistent. Dans ce cas, j’utilise les tableaux pour VictoriaMetrics, Node Exporter, et Kubernetes. Les ID sont les suivants :

  • node-exporter : id 1860, révision 41.
  • victoriametrics : id 10229, révision 22
  • kubernetes “global” : id 15757, révision 43
  • kubernetes “api” : id 15761, révision 19

En yaml, voici ce que ça donne (en dessous de datasources) :

dashboardProviders:
  dashboardproviders.yaml:
    apiVersion: 1
    providers:
      - name: "base"
        orgId: 1
        folder: ""
        type: file
        disableDeletion: true
        editable: true
        options:
          path: /var/lib/grafana/dashboards/base
      - name: "kubernetes"
        orgId: 1
        folder: "kubernetes"
        type: file
        disableDeletion: true
        editable: true
        options:
          path: /var/lib/grafana/dashboards/kubernetes

dashboards:
  base:
    victoriametrics:
      gnetId: 10229
      revision: 22
      datasource: victoriametrics
    node-exporter:
      gnetId: 1860
      revision: 41
      datasource: victoriametrics

  kubernetes:
    k8s-views-global:
      gnetId: 15757
      revision: 43
      datasource: victoriametrics
    k8s-system-api:
      gnetId: 15761
      revision: 19
      datasource: victoriametrics

J’ai laissé le reste des options par défaut, pour le moment. Maintenant, lancez l’installation, en spécifiant le namespace et le fichier de valeurs personnalisées :

helm install grafana grafana/grafana -f grafana_values.yaml -n supervision
NAME: grafana
LAST DEPLOYED: Fri Aug 22 20:37:46 2025
NAMESPACE: supervision
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:

   kubectl get secret --namespace supervision grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

2. The Grafana server can be accessed via port 80 on the following DNS name from within your cluster:

   grafana.supervision.svc.cluster.local

   Get the Grafana URL to visit by running these commands in the same shell:
     export POD_NAME=$(kubectl get pods --namespace supervision -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}")
     kubectl --namespace supervision port-forward $POD_NAME 3000

3. Login with the password from step 1 and the username: admin

Tout est explicite dans les notes. Récupérez le mot de passe en saisissant la commande kubectl get secret --namespace supervision grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo.

À cet instant, si vous n’avez ni ingress ni gateway-api de configuré (mon cas actuel), vous pouvez accéder à l’interface de Grafana en faisant un port-forwarding. Voici les étapes et les commandes :

  • récupérer le nom du pod Grafana dans le namespace supervision
  • lancer le port-forwarding du port 3000 de Grafana vers un port libre de sa machine (dans l’exemple, 50001).
kubectl get pods -n supervision|grep grafana
grafana-695894f4b4-8tt29               1/1     Running   0          9h

kubectl -n supervision port-forward pod/grafana-695894f4b4-8tt29 50001:3000
Forwarding from 127.0.0.1:50001 -> 3000
Forwarding from [::1]:50001 -> 3000

Maintenant, ouvrez votre navigateur vers la page “http://localhost:50001 ” et voici de ce que vous devriez obtenir si vous avez suivi intégralement ce post :

Pour la prochaine fois, il y a encore quelques manipulations à voir, notamment l’accès depuis l’extérieur avec gateway-api, la sauvegarde des données, la personnalisation plus poussée, l’ajout de l’OIDC…

Sources#

Metrics for Kubernetes Object Stateskube-state-metrics, an add-on agent to generate and expose cluster-level metrics.Kuberneteskube-state-metrics 6.1.4 · prometheus/prometheus-communityInstall kube-state-metrics to generate and expose cluster-level metricsSource VictoriaMetrics / Grafana

Helm Charts: VictoriaMetrics SingleDocumentation for VictoriaMetrics, VictoriaLogs, Operator, Managed VictoriaMetrics and vmanomalyVictoriaMetricsGuides: Kubernetes monitoring via VictoriaMetrics SingleDocumentation for VictoriaMetrics, VictoriaLogs, Operator, Managed VictoriaMetrics and vmanomalyVictoriaMetricsGitHub - dotdc/grafana-dashboards-kubernetes: A set of modern Grafana dashboards for Kubernetes.A set of modern Grafana dashboards for Kubernetes. - dotdc/grafana-dashboards-kubernetesGitHubdotdc

Julien HOMMET
11 minutes
2266 mots
tuto