Dans ce post, je présente les étapes de mise en oeuvre d’une centralisation des logs via Kibana dans notre cluster kubernetes. Notre serveur kibana est accessible via ce lien.

Job de déploiement

Les sources du job de déploiement (merci Yvan :-)) des composants nécessaires (filebeat, logstash, elasticsearch, kibana) sont disponibles sur github.

Ce projet est un clone du projet kube-elk-filebeat. Cet article présente la configuration kubernetes.

Le déploiement est réalisé à partir du job jenkins.

Flux de centralisation des logs

Chaque application (déployée dans notre cluster K8s), envoie ses logs vers la sortie standard (STDOUT).

Sur chaque noeud du cluster, un démon filebeat remonte les logs (des applications déployées sur le noeud) vers un serveur logstash.

Le serveur logstash met en forme les logs (via des filtres grok) avant de les remonter vers le serveur elasticsearch. La mise en forme des logs impose de contrôler la structure des logs remontés via par exemple un format de log unique.

Le serveur kibana permet de gérer les données remontées.

Configuration Logback

La configuration Logback ci-dessous formatte les logs de la manière suivante :

  • Date du log
  • Niveau du log (DEBUG, INFO, …)
  • Loggeur utilisé
  • Message du log

De plus, elle redirige les logs vers la sortie standard.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
            </Pattern>
        </layout>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

Configuration Logstash

Les logs remontés sont formatés via une configuration Grok :

  • Grok permet de définir la structure des logs via une séquence de patterns
  • Grok découpe les lignes de logs en respectant cette structure (en générant une clef-valeur par pattern : le nom du pattern et la valeur associée)
  • Finalement Logstash remonte à elasticsearch, par ligne de log, un document comportant ces clefs-valeurs.

Extrait du fichier kibana/kubefiles/logstash-config.yaml

grok {
      match => { "message" => "%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day} %{TIME:time} %{LOGLEVEL:level}%{SPACE}%{JAVACLASS:logger} - %{GREEDYDATA:msg}" }
}

Configuration Docker

Par défaut, docker envoie les logs vers le journal systemd. Comme filebeat remonte des logs fichier (et non des logs systemd), une solution consiste à utiliser le driver de logs json-file (cf. extrait ci-dessous) pour les stocker sur fichier.

De cette manière, les logs des conteneurs sont stockés dans le répertoire /var/log/containers. Filebeat est configuré pour prospecter de nouveaux logs dans ce répertoire.

Extrait du fichier /etc/sysconfig/docker

OPTIONS='--selinux-enabled --log-driver=json-file --signature-verification=false'