E-NO
Kubernetes 7 min de lecture

Architecture de journalisation Kubernetes expliquée avec des exemples pratiques

calendar_today Publié : 2026-08-26
update Dernière mise à jour : 2026-08-26
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Architecture de journalisation Kubernetes expliquée avec des exemples pratiques ».

Introduction

La journalisation Kubernetes est une capacité opérationnelle fondamentale qui permet aux développeurs et aux ingénieurs DevOps de comprendre le comportement des applications, de diagnostiquer les pannes et de surveiller la santé du cluster. Cependant, de nombreuses équipes sont confrontées à des journaux fragmentés, à une absence d'architecture claire et à un débogage improvisé. Cet article fournit un guide pratique, axé sur des exemples, de l'architecture de journalisation Kubernetes. Vous apprendrez comment les journaux circulent des conteneurs vers un backend centralisé, comment configurer les agents de journalisation courants et comment résoudre les problèmes typiques à l'aide de commandes concrètes et de sorties attendues.

Nous nous concentrons sur des scénarios réels : un cluster à nœud unique simple pour l'apprentissage, un cluster de production multi-nœuds, et les étapes pour évoluer d'une journalisation de base vers une configuration centralisée robuste. À la fin, vous serez en mesure de concevoir, mettre en œuvre et vérifier une solution de journalisation répondant aux besoins opérationnels.

Inventaire des versions et de l'environnement

Avant de plonger dans la journalisation, vous devez connaître votre environnement. Cette section fournit des commandes pour inventorier les versions, les nœuds et les composants de journalisation existants. Un inventaire précis évite les configurations incompatibles et vous aide à identifier ce qui est déjà en place.

Informations sur Kubernetes et les nœuds

Commencez par confirmer la version de Kubernetes et les détails des nœuds. Cela est essentiel car les versions des agents de journalisation ont souvent des contraintes de compatibilité avec l'API Kubernetes et le runtime de conteneur.

kubectl version --short
# Sortie attendue similaire à :
# Client Version: v1.25.3
# Server Version: v1.25.3

kubectl get nodes -o wide
# Exemple de sortie :
# NAME     STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
# node1    Ready    control-plane   10d   v1.25.3   192.168.1.10   <none>        Ubuntu 22.04.1 LTS   5.15.0-56-generic   containerd://1.6.8

Composants de journalisation existants

Vérifiez si des agents de journalisation sont déjà déployés. Les agents courants incluent Fluent Bit, Fluentd, Filebeat ou Vector. Recherchez des DaemonSets (un par nœud) ou des Deployments.

kubectl get daemonsets --all-namespaces | grep -E 'fluent|filebeat|log|vector'
kubectl get deployments --all-namespaces | grep -E 'fluent|filebeat|log|vector'
# Si rien ne retourne, aucun agent commun n'est déployé.

# Vérifiez également les ressources personnalisées liées à la journalisation
kubectl get crd | grep -E 'fluent|log|elastic'

Emplacement des journaux du runtime de conteneur

Comprendre où les journaux des conteneurs sont stockés sur le nœud est crucial pour la configuration de l'agent. Pour containerd (le défaut dans de nombreux clusters), les journaux se trouvent généralement sous /var/log/containers (liens symboliques) et /var/log/pods. Pour Docker, ils se trouvent sous /var/lib/docker/containers.

# Sur un nœud, listez les fichiers journaux d'exemple
ls -l /var/log/containers/ | head -5
# Exemple : total 0
# lrwxrwxrwx 1 root root 107 Jan  5 10:00 app-nginx-6d4b7c9f5-abcde_default_nginx-abc123.log -> /var/log/pods/default_app-nginx-6d4b7c9f5-abcde/nginx/0.log

Vérification pratique

Exécutez un pod de test qui produit des journaux et vérifiez qu'ils sont écrits à l'emplacement attendu.

kubectl run logtest --image=busybox --restart=Never -- sh -c 'while true; do echo "Hello from logtest at $(date)"; sleep 5; done'
kubectl logs -f logtest
# Vous devriez voir une sortie répétée.

# Sur le nœud, trouvez le fichier journal pour ce pod
ls /var/log/pods/default_logtest/ | grep logtest
# Exemple : logtest.log
cat /var/log/pods/default_logtest/logtest/0.log
# Affiche la même sortie que kubectl logs.

Nettoyez le pod de test :

kubectl delete pod logtest

Question rapide 1 sur 2

Quel est le format standardisé utilisé par le kubelet pour rendre les journaux de conteneurs disponibles via `kubectl logs` ?

Le passage de référence indique que l'intégration avec le kubelet est standardisée via le _format de journalisation CRI_.

Chemin de configuration sécurisé

La configuration des agents de journalisation peut avoir un impact sur toutes les applications d'un nœud si elle est mal effectuée. Cette section décrit un chemin sûr et incrémental : d'un test sur un seul nœud à un déploiement complet, avec vérification à chaque étape.

Choix d'un agent de journalisation

Fluent Bit est un choix populaire et léger pour Kubernetes. Il est efficace et s'intègre bien avec de nombreux backends. Nous utiliserons ici Fluent Bit comme exemple, mais les principes s'appliquent à d'autres agents.

Étape 1 : Déployer Fluent Bit en tant que DaemonSet dans un namespace de test

Commencez avec une configuration minimale qui lit les journaux des conteneurs et les sort vers stdout (pour vérification). Créez un fichier fluent-bit-test.yaml :

apiVersion: v1
kind: Namespace
metadata:
  name: logging-test
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: logging-test
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush        1
        Daemon       off
        Log_Level    info
    [INPUT]
        Name         tail
        Path         /var/log/containers/*.log
        Parser       docker
        Tag          kube.*
    [OUTPUT]
        Name         stdout
        Match        *
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: logging-test
spec:
  selector:
    matchLabels:
      app: fluent-bit
  template:
    metadata:
      labels:
        app: fluent-bit
    spec:
      containers:
      - name: fluent-bit
        image: fluent/fluent-bit:2.1.10
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: config
          mountPath: /fluent-bit/etc/
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: config
        configMap:
          name: fluent-bit-config

Appliquez et vérifiez :

kubectl apply -f fluent-bit-test.yaml
kubectl get pods -n logging-test -o wide
# Attendez-vous à un pod fluent-bit par nœud, statut Running.

# Vérifiez les journaux pour voir s'il collecte
kubectl logs -n logging-test daemonset/fluent-bit --tail=20
# Vous devriez voir des entrées de journal d'autres pods s'ils existent, ou au moins les journaux de démarrage de l'agent lui-même.

Étape 2 : Ajouter un filtre de métadonnées Kubernetes

Les journaux bruts des conteneurs manquent de noms de pods, de namespaces et d'étiquettes. Ajoutez un filtre Kubernetes pour enrichir les journaux. Mettez à jour la ConfigMap fluent-bit.conf pour inclure :

[FILTER]
    Name                kubernetes
    Match               kube.*
    Kube_URL            https://kubernetes.default.svc:443
    Kube_CA_File        /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    Kube_Token_File     /var/run/secrets/kubernetes.io/serviceaccount/token
    Kube_Tag_Prefix     kube.var.log.containers.
    Merge_Log           On
    Merge_Log_Key       log_processed

Ce filtre nécessite que le pod ait accès à l'API Kubernetes. Le compte de service par défaut dans le namespace peut avoir besoin de permissions RBAC. Pour les tests, vous pouvez créer un ClusterRole et un ClusterRoleBinding pour autoriser la lecture des pods. Créez rbac.yaml :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluent-bit-read
rules:
- apiGroups: [""]
  resources: ["pods", "namespaces"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fluent-bit-read
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: fluent-bit-read
subjects:
- kind: ServiceAccount
  name: default
  namespace: logging-test

Appliquez et redémarrez Fluent Bit :

kubectl apply -f rbac.yaml
kubectl rollout restart daemonset/fluent-bit -n logging-test
kubectl logs -n logging-test daemonset/fluent-bit --tail=10
# Recherchez des lignes contenant "kubernetes": {"pod_name": ...}

Étape 3 : Envoyer les journaux vers un backend centralisé (exemple Elasticsearch)

Remplacez la sortie stdout par Elasticsearch. Assurez-vous d'avoir une instance Elasticsearch accessible depuis le cluster. Pour les tests, vous pouvez déployer un Elasticsearch à nœud unique dans le même namespace ou utiliser un endpoint externe. Mettez à jour la section de sortie dans fluent-bit.conf :

[OUTPUT]
    Name            es
    Match           *
    Host            elasticsearch.logging-test.svc
    Port            9200
    Index           kubernetes-logs
    Type            _doc
    Logstash_Format On
    Logstash_Prefix kubernetes-logs
    Retry_Limit     False

Appliquez la mise à jour de la configuration et redémarrez :

kubectl apply -f fluent-bit-test.yaml
kubectl rollout restart daemonset/fluent-bit -n logging-test
kubectl logs -n logging-test daemonset/fluent-bit --tail=10
# Vous ne devriez voir aucune erreur et peut-être des messages sur la connexion à Elasticsearch.

Vérifiez que les données arrivent dans Elasticsearch :

# Si vous avez un accès curl à Elasticsearch
curl -X GET 'http://elasticsearch.logging-test.svc:9200/_cat/indices/kubernetes-logs*?v'
# Sortie attendue comme :
# health status index                             uuid                   pri rep docs.count docs.deleted store.size pri.store.size
# green  open   kubernetes-logs-2024.01.05        aBcDeFgHiJkLmNoPqRs   1   0        100            0      200kb          200kb

Étape 4 : Passer au namespace de production et mettre à l'échelle

Une fois que la configuration de test fonctionne, répliquez-la dans un namespace de production avec des limites de ressources appropriées, des sélecteurs de nœuds et des contextes de sécurité. Envisagez d'utiliser le chart Helm officiel pour une gestion plus facile.

helm repo add fluent https://fluent.github.io/helm-charts
helm install fluent-bit fluent/fluent-bit --namespace logging --create-namespace

Vérifiez toujours après chaque modification :

kubectl get pods -n logging -o wide
kubectl logs -n logging daemonset/fluent-bit --tail=20

Vérification et diagnostics

Une fois la journalisation configurée, vous devez vérifier qu'elle fonctionne correctement et diagnostiquer les problèmes lorsque les journaux sont manquants ou mal formés. Cette section fournit des commandes de diagnostic et leur interprétation.

Vérifier la collecte de journaux pour un pod spécifique

Créez un pod de test avec un motif de journal connu :

kubectl run log-check --image=busybox --restart=Never -- sh -c 'for i in $(seq 1 10); do echo "UNIQUE_MARKER_$i"; sleep 1; done'

Attendez la fin, puis vérifiez si les journaux apparaissent dans la sortie de Fluent Bit. Si vous utilisez la sortie stdout, vérifiez les journaux de Fluent Bit :

kubectl logs -n logging-test daemonset/fluent-bit --since=5m | grep UNIQUE_MARKER
# Vous devriez voir les 10 lignes.

Si vous utilisez Elasticsearch, interrogez pour le marqueur :

curl -X GET 'http://elasticsearch.logging-test.svc:9200/kubernetes-logs*/_search?q=log:UNIQUE_MARKER_1&pretty'

Scénarios de défaillance courants et diagnostics

  1. Aucun journal d'aucun pod
  • Vérifiez si les pods Fluent Bit sont en cours d'exécution : kubectl get pods -n logging
  • Vérifiez les journaux de Fluent Bit : kubectl logs -n logging daemonset/fluent-bit --tail=50
  • Recherchez des erreurs comme "permission denied" sur les fichiers journaux. Assurez-vous que le DaemonSet a des volumes hostPath montés correctement et que le conteneur s'exécute en tant que root (ou a les permissions appropriées).
  1. Journaux manquants pour des pods spécifiques
  • Le plugin d'entrée tail peut ne pas avoir commencé à lire le fichier s'il existait auparavant. Assurez-vous que Fluent Bit a un accès en lecture et que le motif de chemin correspond. Vérifiez le Path dans la configuration d'entrée. Généralement, le chemin est /var/log/containers/*.log.
  • Vérifiez que le fichier journal du pod existe sur le nœud : ls -l /var/log/containers/ | grep <pod-name>
  1. Les journaux sont tronqués ou illisibles
  • Le parseur peut être mal configuré. Si vous utilisez le parseur Docker, assurez-vous qu'il correspond au runtime de conteneur. Pour containerd, vous pourriez avoir besoin d'un parseur différent ou d'aucun parseur.
  • Augmentez Buffer_Size et Mem_Buf_Limit dans le plugin d'entrée pour gérer de grandes lignes de journal.
  1. Fluent Bit ne peut pas se connecter au backend
  • Vérifiez les politiques réseau et le DNS des services. Depuis le cluster, testez la connectivité : kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never -- curl -v http://elasticsearch.logging-test.svc:9200
  • Assurez-vous que le service backend est dans le même namespace ou accessible via FQDN.

Surveillance des métriques de Fluent Bit

Fluent Bit expose des métriques internes qui peuvent aider à diagnostiquer les problèmes de performance. Activez l'endpoint de métriques dans la configuration :

[SERVICE]
    HTTP_Server  On
    HTTP_Listen  0.0.0.0
    HTTP_Port    2020

Ensuite, exposez le port dans le DaemonSet et interrogez les métriques :

kubectl port-forward -n logging daemonset/fluent-bit 2020:2020
curl http://localhost:2020/api/v1/metrics/prometheus
# Recherchez des métriques comme fluentbit_input_records_total, fluentbit_output_errors_total

Question rapide 2 sur 2

Selon l'article, quelle est une approche courante pour la journalisation au niveau du cluster ?

Le passage énumère plusieurs approches, et la première mentionnée consiste à utiliser un agent de journalisation au niveau du nœud qui s'exécute sur chaque nœud.

Modes de défaillance et récupération

Même avec un pipeline de journalisation bien configuré, des pannes surviennent. Cette section décrit les modes de défaillance courants, leurs symptômes et les étapes de récupération.

Mode de défaillance 1 : Pression disque due à des journaux volumineux

Symptôme : L'utilisation du disque du nœud augmente rapidement, provoquant éventuellement des évictions de pods.

Diagnostic :

df -h /var/log
# Vérifiez l'utilisation du disque sur le nœud où les journaux sont stockés.
du -sh /var/log/containers/* | sort -rh | head -10
# Identifiez quel pod génère le plus de journaux.

Récupération :

  • Implémentez la rotation des journaux au niveau du runtime de conteneur (généralement configuré via les paramètres kubelet comme --container-log-max-size et --container-log-max-files). Par exemple, définissez dans la config kubelet : containerLogMaxSize: "10Mi", containerLogMaxFiles: 5.
  • Ajoutez des limites de ressources à l'agent de journalisation pour éviter qu'il ne consomme trop de CPU/mémoire.
  • Implémentez une limitation de débit dans Fluent Bit en utilisant le filtre Throttle.

Mode de défaillance 2 : CrashLoopBackOff de l'agent de journalisation

Symptôme : kubectl get pods -n logging montre des pods Fluent Bit en CrashLoopBackOff.

Diagnostic :

kubectl describe pod -n logging -l app=fluent-bit
# Regardez les événements pour les messages d'erreur (par exemple, OOMKilled, erreur de config).
kubectl logs -n logging <fluent-bit-pod> --previous
# Vérifiez les journaux du conteneur précédent pour la raison du crash.

Causes courantes et récupération :

  • Mauvaise configuration : Corrigez la syntaxe du fichier de config ou les paramètres invalides. Validez la config avec fluent-bit -c /path/to/conf --dry-run localement.
  • Mémoire insuffisante : Augmentez la limite de mémoire dans la spec du DaemonSet ou réduisez la mise en mémoire tampon.
  • Problèmes de permissions : Assurez-vous que le conteneur s'exécute avec un contexte de sécurité approprié pour lire les journaux de l'hôte. Par exemple, définissez runAsUser: 0 si nécessaire, mais préférez utiliser un utilisateur dédié avec un accès de groupe aux répertoires de journaux.

Mode de défaillance 3 : Backend indisponible (perte de données)

Symptôme : Les journaux n'apparaissent pas dans le backend, et les journaux de Fluent Bit montrent des erreurs de connexion répétées ou des tentatives épuisées.

Diagnostic :

kubectl logs -n logging daemonset/fluent-bit --tail=50 | grep -i 'error\|retry\|failed'
# Recherchez des messages comme "[error] [output:es:es.0] connection refused"

Récupération :

  • Remettez le service backend en ligne (par exemple, Elasticsearch).
  • Assurez-vous que Fluent Bit a la logique de nouvelle tentative activée et une limite de nouvelles tentatives suffisante. Dans le plugin de sortie, définissez Retry_Limit sur une valeur élevée ou False pour des tentatives infinies (avec prudence, car cela peut accumuler un tampon disque).
  • Envisagez d'utiliser un tampon disque pour conserver les journaux pendant les pannes du backend. Dans Fluent Bit, configurez storage.path et utilisez storage.type filesystem dans la sortie.

Mode de défaillance 4 : Perte de journaux due à la suppression d'un pod

Symptôme : Lorsqu'un pod est supprimé, ses journaux sont retirés du nœud (avec la configuration par défaut). Si l'agent de journalisation ne les a pas encore traités, les journaux sont perdus.

Prévention :

  • Assurez-vous que l'agent de journalisation traite les journaux rapidement et dispose d'un tampon suffisamment grand. Surveillez la métrique fluentbit_output_retries_failed_total.
  • Utilisez un stockage persistant pour les journaux sur le nœud, mais cela est rare. Il est préférable de diffuser les journaux dès qu'ils sont produits.
  • Pour les applications critiques, envisagez une journalisation au niveau de l'application vers un puits distant directement pour éviter la dépendance aux fichiers journaux du nœud.

Liste de contrôle des opérations

Cette liste de contrôle résume les opérations quotidiennes et périodiques essentielles pour maintenir une configuration de journalisation Kubernetes saine.

Vérifications quotidiennes

  • [ ] Vérifier que les pods de l'agent de journalisation sont en cours d'exécution : kubectl get pods -n logging -o wide (attendu : tous Ready 1/1).
  • [ ] Vérifier les journaux d'erreur de l'agent : kubectl logs -n logging daemonset/fluent-bit --tail=20 | grep -i error (attendu : aucune erreur).
  • [ ] Confirmer que les journaux circulent vers le backend le cas échéant : interroger le backend pour les documents récents (par exemple, Elasticsearch : curl -s 'http://elasticsearch:9200/kubernetes-logs-*/_count?pretty' | grep count).

Vérifications hebdomadaires

  • [ ] Inspecter l'utilisation du disque sur les nœuds : df -h /var/log sur tous les nœuds ; s'assurer que l'utilisation est inférieure à 70 %.
  • [ ] Examiner l'utilisation des ressources de l'agent de journalisation : kubectl top pods -n logging (nécessite metrics server).
  • [ ] Vérifier la dérive de configuration : comparer la ConfigMap en cours d'exécution avec l'état souhaité versionné.

Vérifications mensuelles

  • [ ] Appliquer les mises à jour de sécurité de l'image de l'agent de journalisation : vérifier les nouvelles versions et mettre à jour le chart Helm ou la balise d'image.
  • [ ] Tester la rotation et la rétention des journaux : simuler un pod à volume de journalisation élevé et s'assurer que la rotation fonctionne et que les anciens journaux sont supprimés.
  • [ ] Examiner les permissions RBAC des comptes de service de journalisation ; s'assurer du moindre privilège.

Runbook de réponse aux incidents

  1. La journalisation s'est complètement arrêtée
  • Vérifier les pods de l'agent : kubectl get pods -n logging
  • Si CrashLoopBackOff, inspecter les journaux et les événements ; se référer au Mode de défaillance 2.
  • Si aucun pod, vérifier le DaemonSet/Deployment : kubectl get daemonset -n logging
  • S'assurer que les sélecteurs de nœuds ou les tolérances n'excluent pas tous les nœuds.
  1. Problèmes de backend (Elasticsearch en panne)
  • Vérifier les pods Elasticsearch : kubectl get pods -n elastic
  • Vérifier le stockage : kubectl get pvc -n elastic
  • Redémarrer si nécessaire, puis vérifier que Fluent Bit se reconnecte.
  1. Latence élevée de recherche de journaux
  • Vérifier l'utilisation des ressources du backend : kubectl top pods -n elastic
  • Mettre à l'échelle les nœuds de données Elasticsearch ou augmenter le tas.
  • Optimiser les paramètres d'index (par exemple, le nombre de fragments).

Conclusion

Une journalisation Kubernetes efficace nécessite de comprendre l'architecture, une configuration minutieuse et une surveillance proactive. Nous avons couvert l'ensemble du cycle de vie : de l'inventaire de l'environnement à la configuration sécurisée, à la vérification, à la récupération après défaillance et aux opérations continues. En suivant les exemples pratiques et les commandes fournies, vous pouvez construire un pipeline de journalisation résilient qui vous aide à résoudre plus rapidement les problèmes d'application et à maintenir la santé du cluster.

Rappelez-vous que la journalisation n'est pas un système à configurer et à oublier. Examinez régulièrement votre configuration, surveillez la santé de tous les composants et ajustez à mesure que votre cluster évolue. Commencez par la liste de contrôle fournie et adaptez-la à votre environnement spécifique. Avec ces outils et pratiques, vous serez bien équipé pour relever les défis de la gestion des journaux dans Kubernetes.

Comme prochaine étape, choisissez un composant à faible risque (comme l'activation du filtre de métadonnées Kubernetes) et testez-le dans un namespace non productif. Documentez le changement, vérifiez la sortie, puis planifiez un déploiement progressif vers la production. En procédant par étapes incrémentales et en vérifiant chacune, vous vous assurez que votre journalisation reste une source de vérité fiable pour vos applications.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO