Comment centraliser vos journaux Docker avec Fluentd et ElasticSearch sur Ubuntu 14.04

Un article de Fluentd

introduction

  • Qu’est-ce que Fluentd? *

Fluentd est un collecteur de données open source conçu pour unifier l’infrastructure de journalisation. Il est conçu pour réunir les ingénieurs d’exploitation, les ingénieurs d’application et les ingénieurs de données en simplifiant et en adaptant la collecte et le stockage des journaux.

Avant Fluentd

image: https: //assets.digitalocean.com/articles/dockerlogs_fluentd/1.jpg [Structure de journalisation malpropre montrant les relations entre de nombreux programmes]

Après Fluentd

image: https: //assets.digitalocean.com/articles/dockerlogs_fluentd/2.png [Fluentd collecte les journaux d’applications et d’accès de nombreuses sources et les dirige vers de nombreux résultats d’analyse, d’archivage et de mesures]

Principales caractéristiques

Fluentd possède quatre caractéristiques clés qui permettent de construire des pipelines de journalisation propres et fiables:

  • * Enregistrement unifié avec JSON: * Fluentd essaie autant que possible de structurer des données au format JSON. Cela permet à Fluentd d’unifier toutes les facettes des données de journal de traitement: collecte, filtrage, mise en mémoire tampon et sortie des journaux sur plusieurs sources et destinations. Le traitement de données en aval est beaucoup plus facile avec JSON, car il a suffisamment de structure pour être accessible sans forcer les schémas rigides

  • * Architecture pluggable: * Fluentd a un système de plugin flexible qui permet à la communauté d’étendre ses fonctionnalités. Les plus de 300 plugins fournis par la communauté connectent des dizaines de sources de données à des dizaines de sorties de données, manipulant les données en fonction des besoins. En utilisant des plugins, vous pouvez mieux utiliser vos journaux immédiatement

  • * Ressources minimales requises: * Un collecteur de données doit être léger pour que l’utilisateur puisse l’exécuter confortablement sur une machine occupée. Fluentd est écrit en C et Ruby et nécessite un minimum de ressources système. L’instance vanilla fonctionne sur 30 à 40 Mo de mémoire et peut traiter 13 000 événements / seconde / cœur.

  • * Fiabilité intégrée: * La perte de données ne devrait jamais se produire. Fluentd prend en charge la mise en mémoire tampon et la mise en mémoire tampon des fichiers pour éviter la perte de données entre nœuds. Fluentd prend également en charge le basculement robuste et peut être configuré pour la haute disponibilité.

Objectifs: Collecte de journaux de conteneurs docker centralisés avec Fluentd

Au fur et à mesure que les conteneurs Docker sont mis en production, il est de plus en plus nécessaire de conserver les journaux des conteneurs dans un endroit moins éphémère que les conteneurs.

Dans ce didacticiel, nous allons vous montrer comment installer Fluentd et l’utiliser pour collecter des journaux à partir de conteneurs Docker, en les stockant à l’extérieur afin que les données puissent être sauvegardées une fois les conteneurs arrêtés. Nous allons diffuser les données dans un autre conteneur exécutant Elasticsearch, sur le même serveur Ubuntu 14.04.

Comme indiqué dans la Le référentiel GitHub de Kubernetes, cette architecture utilise la capacité de Fluentd à suivre et à analyser JSON-per -ligne les fichiers journaux produits par le démon Docker pour chaque conteneur. Pour une configuration minimale, veuillez consulter cette recette.

À la fin de ce didacticiel, nous aborderons deux autres cas d’utilisation. Après avoir lu cet article, vous devez connaître les bases de l’utilisation de Fluentd.

Conditions préalables

Assurez-vous de remplir ces conditions préalables pour le tutoriel.

Étape 1 - Installation de Fluentd

Le moyen le plus courant de déployer Fluentd est via le package + td-agent. Treasure Data, l’auteur original de Fluentd, empaquette Fluentd avec son propre environnement d’exécution Ruby afin que l’utilisateur n’ait pas besoin de configurer son propre Ruby pour exécuter Fluentd.

Actuellement, + td-agent prend en charge les plateformes suivantes:

  • Ubuntu: lucide, précise et fiable

  • Debian: Wheezy et Squeeze

  • RHEL / Centos: 5, 6 et 7

  • Mac OSX: 10.9 et supérieur

Dans ce didacticiel, nous supposons que vous êtes sur DigitalOcean Droplet sous Ubuntu 14.04 LTS (Trusty).

Installez + td-agent avec la commande suivante:

curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-trusty-td-agent2.sh | sh

Démarrer + td-agent:

sudo /etc/init.d/td-agent start

Vérifiez les journaux pour vous assurer qu’il a été installé avec succès:

tail /var/log/td-agent/td-agent.log

Vous devriez voir une sortie similaire à celle-ci:

   port 24230
 </source>
</ROOT>
2015-02-22 18:27:45 -0500 [info]: adding source type="forward"
2015-02-22 18:27:45 -0500 [info]: adding source type="http"
2015-02-22 18:27:45 -0500 [info]: adding source type="debug_agent"
2015-02-22 18:27:45 -0500 [info]: adding match pattern="td.*.*" type="tdlog"
2015-02-22 18:27:45 -0500 [info]: adding match pattern="debug.**" type="stdout"
2015-02-22 18:27:45 -0500 [info]: listening fluent socket on 0.0.0.0:24224
2015-02-22 18:27:45 -0500 [info]: listening dRuby uri="druby://127.0.0.1:24230" object="Engine"

_ _ * Remarque: * Alternativement, Fluentd est disponible en tant que gem Ruby et peut être installé avec + gem install fluentd +. Si vous n’avez PAS les privilèges sudo, installez s’il vous plaît Ruby (voir https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-debian-7-wheezy [Installer Ruby] ici, par exemple) et lancez:

gem install fluentd --no-rdoc --no-ri

_ _

Étape 2 - Installation de Docker

Nous allons maintenant installer Docker. Ce tutoriel a été testé avec Docker v1.5.0.

Ajoutez la clé pour le référentiel Docker afin que nous puissions obtenir un package Docker à jour:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9

Ajoutez le référentiel à vos sources:

sudo sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"

Mettez à jour votre système:

sudo apt-get update

Installer Docker:

sudo apt-get install lxc-docker

Vérifiez que Docker a été installé en vérifiant la version:

docker --version

Vous devriez voir une sortie comme celle-ci:

Docker version 1.5.0, build a8a31ef

Étape 3 - Ajout d’un utilisateur à un groupe de menus

Docker s’exécute en tant que * root *. Par conséquent, pour émettre les commandes + docker +, ajoutez votre utilisateur sudo au groupe * docker *. Remplacez «++» par l’utilisateur de votre choix.

sudo gpasswd -a  docker

Ensuite, redémarrez Docker.

sudo service docker restart

Enfin, si vous êtes actuellement connecté en tant qu’utilisateur sudo, vous devez vous déconnecter et vous reconnecter.

Étape 4 - Construire l’image Fluentd

Dans cette section, nous allons créer l’image Docker pour le conteneur Fluentd Docker. Si vous souhaitez en savoir plus sur Docker en général, veuillez consulter de ce didacticiel d’introduction.

Créez un nouveau répertoire pour vos ressources Fluentd Docker et accédez-y:

mkdir ~/fluentd-docker && cd ~/fluentd-docker

Créez le + Dockerfile + suivant:

sudo nano Dockerfile

Ajoutez exactement le contenu suivant à votre fichier. Ce fichier indique à Docker de mettre à jour le conteneur Docker et d’installer Ruby, Fluentd et Elasticsearch:

FROM ruby:2.2.0
MAINTAINER [email protected]
RUN apt-get update
RUN gem install fluentd -v "~>0.12.3"
RUN mkdir /etc/fluent
RUN apt-get install -y libcurl4-gnutls-dev make
RUN /usr/local/bin/gem install fluent-plugin-elasticsearch
ADD fluent.conf /etc/fluent/
ENTRYPOINT ["/usr/local/bundle/bin/fluentd", "-c", "/etc/fluent/fluent.conf"]

Vous devez également créer un fichier + fluent.conf + dans le même répertoire.

sudo nano fluent.conf

Le fichier + fluent.conf + devrait ressembler à ceci. Vous pouvez copier ce fichier exactement:

<source>
 type tail
 read_from_head true
 path /var/lib/docker/containers/*/*-json.log
 pos_file /var/log/fluentd-docker.pos
 time_format %Y-%m-%dT%H:%M:%S
 tag docker.*
 format json
</source>
# Using filter to add container IDs to each event
<filter docker.var.lib.docker.containers.*.*.log>
 type record_transformer
 <record>
   container_id ${tag_parts[5]}
 </record>
</filter>

<match docker.var.lib.docker.containers.*.*.log>
 type elasticsearch
 logstash_format true
 host "#{ENV['ES_PORT_9200_TCP_ADDR']}" # dynamically configured to use Docker's link feature
 port 9200
 flush_interval 5s
</match>

Ce fichier a pour but d’indiquer à Fluentd où trouver les journaux des autres conteneurs Docker.

Ensuite, construisez votre image Docker, appelée + fluentd-es +:

docker build -t fluentd-es .

Cela prendra quelques minutes à compléter. Vérifiez que vous avez bien construit les images:

docker images

Vous devriez voir la sortie comme ceci:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
fluentd-es          latest              89ba1fb47b23        2 minutes ago       814.1 MB
ruby                2.2.0               51473a2975de        6 weeks ago         774.9 MB

Étape 5 - Démarrage du conteneur Elasticsearch

Revenez maintenant à votre répertoire personnel ou à votre répertoire préféré pour votre conteneur Elasticsearch:

cd ~

Téléchargez et démarrez le conteneur Elasticsearch. Il existe déjà une construction automatisée pour cela:

docker run -d -p 9200:9200 -p 9300:9300 --name es dockerfile/elasticsearch

Attendez que l’image du conteneur soit téléchargée et démarrée.

Ensuite, assurez-vous que le conteneur Elasticsearch fonctionne correctement en vérifiant les processus Docker:

docker ps

Vous devriez voir la sortie comme ceci:

CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS              PORTS                                           NAMES
c474fd99ce43        dockerfile/elasticsearch:latest   "/elasticsearch/bin/   4 minutes ago      Up 4 minutes        0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es

Étape 6 - Démarrage du conteneur Fluentd-to-Elasticsearch

Nous allons maintenant démarrer le conteneur qui exécute Fluentd, collecte les journaux et les envoie à Elastcisearch.

docker run -d --link es:es -v /var/lib/docker/containers:/var/lib/docker/containers fluentd-es

Dans la commande ci-dessus, la partie + - link es: es + relie le conteneur Elasticsearch au conteneur Fluentd. La partie + -v / var / lib / docker / containers: / var / lib / docker / containers + est nécessaire pour monter le répertoire de journalisation du conteneur hôte dans le conteneur Fluentd, afin que Fluentd puisse créer des fichiers journaux lors de la création des conteneurs. .

Enfin, vérifiez que le conteneur est en cours d’exécution en consultant nos processus Docker actifs:

docker ps

Cette fois, vous devriez voir à la fois le conteneur Elasticsearch et le nouveau conteneur + fluentd-es +:

CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS              PORTS                                           NAMES
f0d2cac81ac8        fluentd-es:latest               "/usr/local/bundle/b   2 seconds ago    Up 2 seconds                                                        stupefied_brattain
c474fd99ce43        dockerfile/elasticsearch:latest   "/elasticsearch/bin/   6 minutes ago      Up 6 minutes        0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es

Étape 7 - Confirmation qu’Elasticsearch reçoit les événements

Enfin, confirmons que Elasticsearch reçoit les événements:

curl -XGET 'http://localhost:9200/_all/_search?q=*'

La sortie devrait contenir des événements qui ressemblent à ceci:

{"took":66,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
{"took":59,"timed_out":false,"_shards":{"tod","_id":"AUwLaKjcnpi39wqZnTXQ","_score":1.0,"_source":{"log":"2015-03-12 00:35:44 +0000 [info]: following tail of /var/lib/docker/containers/6abeb6ec0019b2198ed708315f4770fc7ec6cc44a10705ea59f05fae23b81ee9/6abeb6ec0019b2198ed708315f4770fc7ec6cc44a10705ea59f05fae23b81ee9-json.log\n","stream":"stdout","container_id":"6abeb6ec0019b2198ed708315f4770fc7ec6cc44a10705ea59f05fae23b81ee9","@timestamp":"2015-03-12T00:35:44+00:00"}}]}}

Vous pouvez avoir plusieurs événements enregistrés en fonction de votre configuration. Un seul événement devrait commencer par + {" prenant ": + et se terminer par un horodatage.

Comme le montre cette sortie, Elasticsearch reçoit des données. (Votre identifiant de conteneur sera différent de celui indiqué ci-dessus!)

Étape 8 - Passer les journaux d’événements au niveau suivant

Maintenant que vos événements conteneur sont sauvegardés par Elasticsearch, que devriez-vous faire ensuite? Elasticsearch propose de nombreuses activités utiles. Si vous recherchez des idées, vous pouvez consulter:

Conclusion

La collecte de journaux à partir de conteneurs Docker n’est qu’un des moyens d’utiliser Fluentd. Dans cette section, nous allons présenter deux autres cas d’utilisation courants de Fluentd.

Cas d’utilisation 1: recherche de journaux en temps réel et archivage de journaux

De nombreux utilisateurs ont recours à Fluentd pour créer un pipeline de journalisation qui effectue à la fois une recherche de journal en temps réel et un stockage à long terme. L’architecture ressemble à ceci:

image: https: //assets.digitalocean.com/articles/dockerlogs_fluentd/3.png [Transmission des journaux de plusieurs backends à Elasticsearch, MongoDB et Hadoop]

Cette architecture tire parti de la capacité de Fluentd à copier des flux de données et à les exporter vers plusieurs systèmes de stockage. Dans les paramètres ci-dessus, Elasticsearch est utilisé pour la recherche en temps réel, tandis que MongoDB et / ou Hadoop sont utilisés pour l’analyse par lots et le stockage à long terme.

Cas d’utilisation 2: enregistrement d’application centralisé

Les applications Web produisent de nombreux journaux, qui sont souvent formatés de manière arbitraire et stockés sur le système de fichiers local. C’est mauvais pour deux raisons:

  • Les journaux sont difficiles à analyser par programmation (nécessitant de nombreuses expressions régulières) et ne sont donc pas très accessibles pour ceux qui souhaitent comprendre le comportement des utilisateurs par le biais d’analyses statistiques (tests A / B, détection de fraude, etc.).

  • Les journaux ne sont pas accessibles en temps réel car ils sont chargés en bloc dans les systèmes de stockage. De plus, si le disque du serveur est corrompu entre des chargements en bloc, les journaux sont perdus ou corrompus.

Fluentd résout ces problèmes en:

  • Fourniture de bibliothèques de consignateurs pour différents langages de programmation avec une API cohérente: chaque consignateur envoie un triple de (horodatage, balise, événement au format JSON) à Fluentd. Il existe actuellement des bibliothèques de consignateurs pour Ruby, Node.js, Go, Python, Perl, PHP, Java et C ++.

  • Permettre à l’application de «déclencher et d’oublier»: le consignateur peut se connecter de manière asynchrone à Fluentd, ce qui met ensuite les tampons en mémoire tampon avant le téléchargement sur les systèmes dorsaux.

Ressources: