Modul 12 — Monitoring, logging a observabilita

59. Centralizované logování (ELK/EFK stack nebo Loki)

Proč logy z desítek serverů a kontejnerů nejde procházet jednotlivě a jak je centralizace přes ELK/EFK nebo Loki řeší.

Odhadovaná délka studia: 50 minut · Stav: nehotovo

Technologie: Centralizované logování

Úvod a kontext

V lekci o observabilitě jsme logy označili za druhý pilíř vedle metrik
a trasování. Dokud aplikace běží na jednom serveru, stačí tail -f /var/log/aplikace.log. Jakmile ale máte desítky serverů nebo stovky
krátkodobě žijících Kubernetes podů, je nemožné logy procházet
jednotlivě — pody navíc při restartu své logy ztrácí úplně, pokud
nejsou odeslány jinam. Řešením je centralizované logování: všechny
logy se z jednotlivých zdrojů posílají do jednoho centrálního systému,
kde jdou prohledávat a analyzovat pohromadě.

Teorie

Architektura centralizovaného logování

Typický pipeline má tři vrstvy:

  1. Sběr (collection) — agent běžící na každém uzlu nebo vedle
    každé aplikace, který čte logy (ze souborů, stdout kontejnerů,
    systemd journalu) a posílá je dál.
  2. Zpracování a uložení (processing & storage) — logy se
    parsují (extrahují se strukturovaná pole z textu), případně
    obohacují (přidá se název podu, jmenný prostor) a ukládají do
    úložiště optimalizovaného pro fulltextové vyhledávání.
  3. Vizualizace a dotazování (visualization) — webové rozhraní pro
    hledání, filtrování a tvorbu dashboardů nad logy.

ELK / EFK stack

Historicky nejrozšířenější kombinace:

  • Elasticsearch — distribuovaná fulltextová databáze, kde se logy
    ukládají a indexují pro rychlé vyhledávání.
  • Logstash (nebo Fluentd/Fluent Bit — pak se mluví o
    "EFK") — sběr, parsování a transformace logů před uložením.
    Fluent Bit je odlehčená varianta Fluentd, oblíbená jako
    Kubernetes DaemonSet díky nízké spotřebě zdrojů.
  • Kibana — vizualizační a dotazovací rozhraní nad Elasticsearch.

ELK/EFK je výkonný a flexibilní, ale Elasticsearch je paměťově a
výpočetně náročný na provoz ve velkém měřítku.

Grafana Loki

Loki je novější alternativa navržená s jinou filozofií: na rozdíl
od Elasticsearch neindexuje plný text logu, jen sadu labelů
(podobně jako Prometheus) — např. namespace, pod, app. To
výrazně snižuje nároky na úložiště a výpočet, za cenu toho, že
fulltextové hledání v obsahu logu (ne jen podle labelu) je při velkém
objemu dat pomalejší. Loki se přirozeně integruje s Grafanou (stejné
UI jako pro Prometheus metriky) a jeho agent pro sběr se jmenuje
Promtail (nebo modernější Grafana Alloy).

Strukturované logování

Ať zvolíte kteroukoliv variantu, klíčový předpoklad efektivního
centralizovaného logování je, aby aplikace produkovaly strukturované
logy
(JSON) místo volného textu — viz JSON příklad z minulé lekce.
Strukturovaná pole (level, service, trace_id, vlastní business
pole) jdou filtrovat a agregovat přesně, zatímco parsování volného
textu regulárními výrazy je křehké a pomalé.

Retence a náklady

Logy rostou objemem rychleji než metriky. Typická praxe je
stupňovaná retence: čerstvé logy (posledních 7–30 dní) v rychlém,
dražším úložišti pro aktivní vyšetřování; starší logy archivovat do
levného objektového úložiště (S3/GCS) nebo je po definované době
smazat — v souladu s případnými požadavky na compliance (viz pozdější
lekce o auditu).

Praktický příklad

Konfigurace Fluent Bit jako DaemonSetu v Kubernetes, který čte logy
kontejnerů z uzlu a posílá je do Elasticsearch:

[INPUT]
    Name              tail
    Path              /var/log/containers/*.log
    Parser            docker
    Tag               kube.*

[FILTER]
    Name                kubernetes
    Match               kube.*
    Merge_Log           On
    Keep_Log            Off

[OUTPUT]
    Name            es
    Match           *
    Host            elasticsearch.logging.svc
    Port            9200
    Index           kubernetes-logs

FILTER typu kubernetes obohatí každý log o metadata podu (jméno,
jmenný prostor, labely) — bez nich by log jen nesl text bez kontextu,
odkud pochází.

Ekvivalentní minimální konfigurace Promtailu pro Loki, ukazující
label-based přístup:

scrape_configs:
  - job_name: kubernetes-pods
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_namespace]
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        target_label: pod

Dotaz v Loki jazyce LogQL (syntakticky podobný PromQL), který
vyhledá chybové logy konkrétní služby za poslední hodinu:

{namespace="produkce", app="objednavky-servis"} |= "error" | json | level="error"

Nejprve se vyberou logy podle labelů (namespace, app — rychlé,
protože nejde o fulltext), teprve pak se filtruje textově (|= "error") a nakonec se log naparsuje jako JSON a filtruje podle pole
level.

Shrnutí

Centralizované logování shromažďuje logy z mnoha zdrojů do jednoho
systému přes tři vrstvy: sběr (agent na uzlu), zpracování/uložení a
vizualizaci. ELK/EFK (Elasticsearch + Logstash/Fluentd + Kibana)
indexuje plný text a je výkonný, ale náročný na zdroje; Loki ukládá
jen labely (jako Prometheus) a je levnější na provoz, s pomalejším
fulltextovým hledáním. Strukturované (JSON) logování a stupňovaná
retence jsou předpokladem efektivního provozu v obou přístupech.

Kontrolní otázky

  1. Proč je centralizované logování nutné zejména v Kubernetes prostředí
    s krátkodobě žijícími pody?
  2. Jaký je zásadní architektonický rozdíl mezi Elasticsearch a Loki
    v tom, co indexují?
  3. Proč je strukturované (JSON) logování lepší než volný text pro
    pozdější analýzu?
  4. Mini cvičení: navrhněte stupňovanou retenční politiku pro logy
    produkční aplikace (jak dlouho v rychlém úložišti, jak dlouho
    v archivu, kdy smazat).

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.