Sběr logů z kontejnerů

Vaše aplikace běží pomocí Dockeru na několika serverech a automaticky se škálují. Jak z nich ale dostat logy? SSH, tail a grep jsou téměř nepoužitelné. Podívejte se, jak nakonfigurovat a spustit ELK stack.

ELK je zkratka pro Elastic Search, Logstash, Kibana:

  • Elastic Search je distribuovaný vyhledávací engine,
  • Logstash je nástroj pro směrování zpráv, a
  • Kibana je HTML rozhraní pro zobrazování dat z Elastic Search.

ELK stack je řešením pro problémy s logy: všechny zprávy posíláte na jedno místo, ale díky Elastic Search dobře škálují. V Kibaně si můžete prohlížet grafy, nebo si přímo z API Elastic Search tahat data ve formátu JSON.

Jak připojit kontejnery na ELK? Pomocí Logspout

Logspout je nástroj pro sběr a směrování logů z kontejnerů. Díky adaptéru logspout-logstash je připojení na Logstash jednoduché. Stačí jenom na každém serveru spustit jeden kontejner navíc, který se už o vše další postará sám.

Co musí aplikace a kontejnery umět

Aby se logy správně dostaly zevnitř kontejnerů do Logspout a dál, je potřeba splnit dvě podmínky:

  • Veškeré zprávy jsou zapisované na STDOUT a STDERR: tedy žádné soubory. Jestliže nemůžete výstup aplikace ovlivnit, můžete použít například nástroj dockerize.
  • Kontejnery s aplikací musí být spuštěné bez parametru -t.

Jak spustit ELK stack

Nejjednodušší je použít předpřipravený Docker image: pblittle/docker-logstash. Na stránce projektu je několik příkladů, jak image použít, ale chybí ten pro nás nejpodstatnější: vstup pomocí syslogu. Právě ten totiž používá i Logspout.

Musíte si tak vytvořit vlastní konfigurační soubor a v něm příslušné rozhraní otevřít. Dokumentace Logstash popisuje všechny možnosti, zde je minimální ukázka souboru conf.d/logstash.conf:

input {
  tcp {
    port => 5000
    type => syslog
  }
  udp {
    port => 5000
    type => syslog
  }
}
filter {
  if [type] == "syslog" {
    json {
      source => "message"
    }
  }
}
output {
  elasticsearch {
    embedded => true
    host => "127.0.0.1"
    port => "9200"
    protocol => "http"
  }
}

Při spouštění kontejneru pak musíte tento soubor připojit pomocí volume a zároveň otevřít příslušné porty: 5000 pro vstup logů, 9200 pro API Elastic Search, a 9292 pro rozhraní Kibany.

docker run \
  --volume $(pwd)/conf.d:/opt/logstash/conf.d \
  -p 5000:5000 \
  -p 5000:5000/udp \
  -p 9292:9292 \
  -p 9200:9200 \
  -p 9292:9292 \
  pblittle/docker-logstash

Jestliže se vše povedlo, uvidíte výstupy, prozatím prázdné:

  • http://localhost:9200/: Verze Elastic Search
  • http://localhost:9200/_search: Logy ve formátu JSON
  • http://localhost:9292/: Grafické rozhraní Kibany

Jestliže používáte boot2docker, namísto localhost použijte adresu z boot2docker ip: u mě je to 192.168.59.103.

Jak spustit Logspout

Pro Logspout taky existuje připravený Docker image: gliderlabs/logspout. Ten ale nemá nainstalovaný adaptér pro logstash. Naštěstí je instalace jednoduchá. Nejdřív si vytvořte vlastní soubor modules.go, kde sepíšete všechny pluginy, které budete potřebovat. Může vypadat třeba takhle:

package main

import (
 _ "github.com/gliderlabs/logspout/transports/tcp"
 _ "github.com/gliderlabs/logspout/transports/udp"
 _ "github.com/looplab/logspout-logstash"
)

Potom ve stejném adresáři vytvořte Dockerfile s jediným příkazem, FROM:

FROM gliderlabs/logspout:master

Nezapomeňte použít tag :master! Bez něj se nespustí kompilace.

Pak už stačí jenom vytvořit image. Kompilační skript si sám najde modules.go, nakopíruje ho dovnitř kontejneru a stáhne si moduly z githubu. Kontejner můžete hned spustit:

docker build -t zdrojak/logspout .
docker run -d \
  -v /var/run/docker.sock:/tmp/docker.sock \
  zdrojak/logspout \
  logstash://localhost:5000

Pak už můžete spustit libovolný další kontejner:

docker run --rm ubuntu echo "Hello, Kibana"

Výsledek uvidíte v Kibaně:

Co se do článku už nevešlo

  • Škálování: Elastic Search se umí roztáhnout přes víc serverů
  • Parsování příchozích zpráv: můžete použít například grok. Konfigurovat budete v souboru logstash.conf
  • Promazávání logů kontejnerů: Docker uchovává logy na věky věků. V budoucnu se to pravděpodobně změní (viz #7333 a #8911), ale prozatím to můžete vyřešít například pomocí logrotate.

Alternativní přístup

Mnou popsané řešení není jediné. S následujícími ale nemám zkušenosti a budu rád, když se o ty svoje podělíte v komentářích!

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 7

Přehled komentářů

Sniper Co se do clanku neveslo - bezpecnost
wsh Loggly
msgre Leakování dockeru
David Elasticsearch
msgre Re: Elasticsearch
David Re: Elasticsearch
Luděk docker-compose
Zdroj: https://www.zdrojak.cz/?p=14810