Logy v Kubernetes (a nejen) dnes: očekávání a realita

Logy v Kubernetes (a nejen) dnes: očekávání a realita

Je rok 2019 a stále nemáme standardní řešení pro agregaci protokolů v Kubernetes. V tomto článku bychom se rádi na příkladech z reálné praxe podělili o naše hledání, problémy a jejich řešení.

Nejprve však udělám rezervaci, že různí zákazníci chápou velmi odlišné věci pomocí shromažďování protokolů:

  • někdo chce vidět protokoly zabezpečení a auditu;
  • někdo - centralizované protokolování celé infrastruktury;
  • a někomu stačí sbírat pouze aplikační logy, vyjma například balancerů.

Níže je uveden střih níže o tom, jak jsme implementovali různé „seznamy přání“ a s jakými potížemi jsme se setkali.

Teorie: o protokolovacích nástrojích

Základní informace o součástech systému těžby dřeva

Protokolování ušlo dlouhou cestu, v důsledku čehož byly vyvinuty metodiky pro sběr a analýzu protokolů, které dnes používáme. V 1950. letech XNUMX. století představil Fortran analog standardních vstupních/výstupních proudů, které pomohly programátorovi odladit jeho program. Byly to první počítačové protokoly, které usnadnily život programátorům té doby. Dnes v nich vidíme první součást logovacího systému - zdroj nebo „výrobce“ kulatiny.

Informatika se nezastavila: objevily se počítačové sítě, první shluky... Začaly fungovat složité systémy složené z několika počítačů. Nyní byli správci systému nuceni shromažďovat protokoly z několika počítačů a ve zvláštních případech mohli přidat zprávy jádra OS pro případ, že by potřebovali prošetřit selhání systému. Pro popis centralizovaných systémů sběru protokolů byl publikován na počátku 2000. století RFC 3164, který standardizoval remote_syslog. Takto se objevila další důležitá součást: sběrač klád a jejich skladování.

S nárůstem objemu logů a plošným zaváděním webových technologií vyvstala otázka, jaké logy je potřeba uživatelům pohodlně ukazovat. Jednoduché konzolové nástroje (awk/sed/grep) byly nahrazeny pokročilejšími prohlížeče logů - třetí složka.

Vzhledem k nárůstu objemu kulatiny se ujasnilo něco jiného: kulatiny jsou potřeba, ale ne všechny. A různé protokoly vyžadují různé úrovně uchování: některé se mohou ztratit za den, zatímco jiné je třeba uchovávat po dobu 5 let. Takže do logovacího systému byla přidána komponenta pro filtrování a směrování datových toků – nazvěme to filtr.

Velký skok udělalo také úložiště: od běžných souborů k relačním databázím a poté k úložišti orientovanému na dokumenty (například Elasticsearch). Takže úložiště bylo odděleno od kolektoru.

V konečném důsledku se samotný koncept klády rozšířil na jakýsi abstraktní proud událostí, které chceme uchovat pro historii. Nebo spíše v případě, že potřebujete provést vyšetřování nebo vypracovat analytickou zprávu...

Díky tomu se sběr logů za relativně krátkou dobu vyvinul v důležitý subsystém, který lze právem nazvat jednou z podsekcí v Big Data.

Logy v Kubernetes (a nejen) dnes: očekávání a realita
Jestliže kdysi pro „logovací systém“ stačily obyčejné tisky, nyní se situace hodně změnila.

Kubernetes a protokoly

Když Kubernetes přišel do infrastruktury, neobešel ji ani již existující problém se sběrem logů. V některých ohledech to bylo ještě bolestivější: správa platformy infrastruktury se nejen zjednodušila, ale zároveň zkomplikovala. Mnoho starých služeb začalo migrovat na mikroslužby. V kontextu logů se to projevuje rostoucím počtem zdrojů logů, jejich speciálním životním cyklem a nutností sledovat vztahy všech komponent systému prostřednictvím logů...

Při pohledu do budoucna mohu konstatovat, že nyní bohužel neexistuje žádná standardizovaná možnost protokolování pro Kubernetes, která by byla srovnatelná se všemi ostatními. Nejoblíbenější schémata v komunitě jsou následující:

  • někdo rozbalí hromádku EFK (Elasticsearch, Fluentd, Kibana);
  • někdo zkouší nedávno vydané Loki nebo používá Operátor protokolování;
  • nás (a možná nejen my?..) Jsem velmi spokojen se svým vlastním vývojem - srub...

V clusterech K8s zpravidla používáme následující balíčky (pro samostatně hostovaná řešení):

Nebudu se však zdržovat návodem na jejich instalaci a konfiguraci. Místo toho se zaměřím na jejich nedostatky a globálnější závěry o situaci s logy obecně.

Cvičte s logy v K8s

Logy v Kubernetes (a nejen) dnes: očekávání a realita

"Každodenní záznamy", kolik vás tam je?...

Centralizovaný sběr protokolů z poměrně rozsáhlé infrastruktury vyžaduje značné prostředky, které budou vynaloženy na sběr, ukládání a zpracování protokolů. Při provozu různých projektů jsme se potýkali s různými požadavky a z nich vyplývajícími provozními problémy.

Zkusme ClickHouse

Podívejme se na centralizované úložiště na projektu s aplikací, která generuje protokoly poměrně aktivně: více než 5000 řádků za sekundu. Začněme pracovat s jeho protokoly a přidáme je do ClickHouse.

Jakmile je požadován maximální realtime, 4jádrový server s ClickHouse již bude přetížen na diskovém subsystému:

Logy v Kubernetes (a nejen) dnes: očekávání a realita

Tento typ načítání je způsoben tím, že se snažíme psát v ClickHouse co nejrychleji. A databáze na to reaguje zvýšeným zatížením disku, což může způsobit následující chyby:

DB::Exception: Too many parts (300). Merges are processing significantly slower than inserts

Faktem je, že MergeTree tabulky v ClickHouse (obsahují data protokolu) mají své vlastní potíže při operacích zápisu. Data do nich vložená vygenerují dočasný oddíl, který se následně sloučí s hlavní tabulkou. V důsledku toho se záznam ukazuje jako velmi náročný na disk a navíc podléhá omezení, které jsme obdrželi výše: za 1 sekundu nelze sloučit více než 300 pododdílů (ve skutečnosti je to 300 vložení za sekundu).

Chcete-li se tomuto chování vyhnout, měli napsat do ClickHouse na co největší kusy a ne více než 1krát za 2 sekundy. Psaní ve velkých dávkách však naznačuje, že bychom v ClickHouse měli psát méně často. To zase může vést k přetečení vyrovnávací paměti a ztrátě protokolů. Řešením je zvýšit vyrovnávací paměť Fluentd, ale pak se zvýší i spotřeba paměti.

Poznámka: Další problematický aspekt našeho řešení s ClickHouse souvisel s tím, že dělení v našem případě (srub) je realizováno prostřednictvím připojených externích tabulek Sloučit tabulku. To vede k tomu, že při vzorkování velkých časových intervalů je vyžadována nadměrná RAM, protože metatabulka prochází všemi oddíly - i těmi, které zjevně neobsahují potřebná data. Nyní však může být tento přístup bezpečně prohlášen za zastaralý pro aktuální verze ClickHouse (c 18.16).

V důsledku toho je zřejmé, že ne každý projekt má dostatek zdrojů na shromažďování protokolů v reálném čase v ClickHouse (přesněji jejich distribuce nebude vhodná). Kromě toho budete muset použít akumulátor, ke kterému se vrátíme později. Výše popsaný případ je skutečný. A v té době jsme nebyli schopni nabídnout spolehlivé a stabilní řešení, které by zákazníkovi vyhovovalo a umožnilo nám sbírat kulatiny s minimálním zpožděním...

A co Elasticsearch?

Je známo, že Elasticsearch zvládá velké pracovní zatížení. Zkusme to ve stejném projektu. Nyní zatížení vypadá takto:

Logy v Kubernetes (a nejen) dnes: očekávání a realita

Elasticsearch byl schopen strávit datový tok, ale zápis takových objemů do něj značně využívá CPU. O tom se rozhoduje uspořádáním klastru. Technicky to není problém, ale ukazuje se, že jen pro provoz systému sběru logů už používáme asi 8 jader a máme v systému navíc vysoce zatíženou komponentu...

Sečteno a podtrženo: tato možnost může být opodstatněná, ale pouze v případě, že je projekt rozsáhlý a jeho vedení je připraveno vynaložit značné prostředky na centralizovaný systém protokolování.

Pak vyvstává přirozená otázka:

Jaké protokoly jsou skutečně potřeba?

Logy v Kubernetes (a nejen) dnes: očekávání a realita Pokusme se změnit samotný přístup: protokoly by měly být zároveň informativní a neměly by pokrývat každý událost v systému.

Řekněme, že máme úspěšný internetový obchod. Jaké protokoly jsou důležité? Nasbírat co nejvíce informací například z platební brány je skvělý nápad. Ale ne všechny protokoly ze služby krájení obrázků v katalogu produktů jsou pro nás kritické: stačí pouze chyby a pokročilé monitorování (například procento 500 chyb, které tato komponenta generuje).

Takže jsme došli k závěru, že centralizované protokolování není vždy oprávněné. Klient chce velmi často shromáždit všechny protokoly na jednom místě, i když ve skutečnosti je z celého protokolu vyžadováno pouze podmíněných 5 % zpráv, které jsou pro podnik kritické:

  • Někdy stačí nakonfigurovat řekněme pouze velikost protokolu kontejneru a kolektoru chyb (například Sentry).
  • K prošetření incidentů může často stačit oznámení o chybě a samotný velký místní protokol.
  • Měli jsme projekty, které si vystačily výhradně s funkčními testy a systémy sběru chyb. Vývojář nepotřeboval protokoly jako takové - vše viděl ze stop chyb.

Ilustrace ze života

Jako dobrý příklad může posloužit jiný příběh. Obdrželi jsme požadavek od bezpečnostního týmu jednoho z našich klientů, který již používal komerční řešení vyvinuté dlouho před představením Kubernetes.

Bylo nutné „spřátelit“ centralizovaný systém sběru protokolů s podnikovým senzorem detekce problémů – QRadar. Tento systém může přijímat protokoly prostřednictvím protokolu syslog a získávat je z FTP. Nebylo však okamžitě možné jej integrovat s pluginem remote_syslog pro fluentd (jak se ukázalo, nejsme sami). Problémy s nastavením QRadaru se ukázaly být na straně bezpečnostního týmu klienta.

Výsledkem bylo, že část kritických protokolů byla nahrána do FTP QRadar a druhá část byla přesměrována přes vzdálený syslog přímo z uzlů. Kvůli tomu jsme si dokonce psali jednoduchý graf - snad to někomu pomůže vyřešit podobný problém... Díky výslednému schématu klient sám obdržel a analyzoval kritické protokoly (pomocí jeho oblíbených nástrojů) a nám se podařilo snížit náklady na logovací systém a ušetřit pouze minulý měsíc.

Další příklad je docela názorný, co nedělat. Jeden z našich klientů ke zpracování každý události pocházející od uživatele, provedené víceřádkové nestrukturovaný výstup informace v logu. Jak asi tušíte, takové protokoly byly extrémně nepohodlné jak pro čtení, tak pro ukládání.

Kritéria pro protokoly

Takové příklady vedou k závěru, že kromě výběru systému sběru protokolů musíte navrhnout také samotné kulatiny! Jaké jsou zde požadavky?

  • Protokoly musí být ve strojově čitelném formátu (například JSON).
  • Protokoly by měly být kompaktní a měly by mít možnost změnit stupeň protokolování za účelem ladění možných problémů. Zároveň byste v produkčním prostředí měli spouštět systémy s úrovní protokolování jako výstraha nebo Chyba.
  • Protokoly musí být normalizovány, to znamená, že v objektu protokolu musí mít všechny řádky stejný typ pole.

Nestrukturované protokoly mohou vést k problémům s načítáním protokolů do úložiště a úplnému zastavení jejich zpracování. Pro ilustraci uvádíme příklad s chybou 400, se kterou se mnozí určitě setkali v plynulých protokolech:

2019-10-29 13:10:43 +0000 [warn]: dump an error event: error_class=Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError error="400 - Rejected by Elasticsearch"

Chyba znamená, že do indexu posíláte pole, jehož typ je nestabilní, s připraveným mapováním. Nejjednodušším příkladem je pole v protokolu nginx s proměnnou $upstream_status. Může obsahovat číslo nebo řetězec. Například:

{ "ip": "1.2.3.4", "http_user": "-", "request_id": "17ee8a579e833b5ab9843a0aca10b941", "time": "29/Oct/2019:16:18:57 +0300", "method": "GET", "uri": "/staffs/265.png", "protocol": "HTTP/1.1", "status": "200", "body_size": "906", "referrer": "https://example.com/staff", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "request_time": "0.001", "cache_status": "-", "upstream_response_time": "0.001, 0.007", "upstream_addr": "127.0.0.1:9000", "upstream_status": "200", "upstream_response_length": "906", "location": "staff"}
{ "ip": "1.2.3.4", "http_user": "-", "request_id": "47fe42807f2a7d8d5467511d7d553a1b", "time": "29/Oct/2019:16:18:57 +0300", "method": "GET", "uri": "/staff", "protocol": "HTTP/1.1", "status": "200", "body_size": "2984", "referrer": "-", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "request_time": "0.010", "cache_status": "-", "upstream_response_time": "0.001, 0.007", "upstream_addr": "10.100.0.10:9000, 10.100.0.11:9000", "upstream_status": "404, 200", "upstream_response_length": "0, 2984", "location": "staff"}

Protokoly ukazují, že server 10.100.0.10 odpověděl chybou 404 a požadavek byl odeslán do jiného úložiště obsahu. V důsledku toho se hodnota v protokolech stala takto:

"upstream_response_time": "0.001, 0.007"

Tato situace je tak běžná, že si dokonce zaslouží samostatné odkazy v dokumentaci.

A co spolehlivost?

Jsou chvíle, kdy jsou všechny protokoly bez výjimky životně důležité. A s tím mají typická schémata shromažďování protokolů pro K8 navrhovaná/diskutovaná výše problémy.

Fluentd například nemůže sbírat polena z kontejnerů s krátkou životností. V jednom z našich projektů kontejner pro migraci databáze žil méně než 4 sekundy a poté byl smazán - podle odpovídající anotace:

"helm.sh/hook-delete-policy": hook-succeeded

Z tohoto důvodu nebyl protokol provádění migrace zahrnut do úložiště. V tomto případě může pomoci politika. before-hook-creation.

Dalším příkladem je rotace protokolu Docker. Řekněme, že existuje aplikace, která aktivně zapisuje do protokolů. Za normálních podmínek se nám podaří zpracovat všechny protokoly, ale jakmile se objeví problém - například jak je popsáno výše s nesprávným formátem - zpracování se zastaví a Docker otočí soubor. Výsledkem je, že kritické obchodní protokoly mohou být ztraceny.

To je důvod, proč je důležité oddělit proudy protokolů, vkládání odesílání těch nejcennějších přímo do aplikace, aby byla zajištěna jejich bezpečnost. Navíc by nebylo zbytečné nějaké vytvořit „akumulátor“ protokolů, které mohou přežít krátkou nedostupnost úložiště a zároveň uložit důležité zprávy.

Nakonec na to nesmíme zapomenout Je důležité řádně monitorovat jakýkoli subsystém. V opačném případě se snadno dostanete do situace, ve které se plynule nachází ve stavu CrashLoopBackOff a nic neposílá a to slibuje ztrátu důležitých informací.

Závěry

V tomto článku se nedíváme na řešení SaaS jako Datadog. Mnoho ze zde popsaných problémů již tak či onak vyřešily komerční společnosti specializující se na sběr logů, ale ne každý může z různých důvodů používat SaaS (hlavní jsou náklady a soulad s 152-FZ).

Centralizovaný sběr protokolů na první pohled vypadá jako jednoduchý úkol, ale vůbec tomu tak není. Je důležité mít na paměti, že:

  • Podrobně je třeba protokolovat pouze kritické komponenty, zatímco monitorování a shromažďování chyb lze konfigurovat pro jiné systémy.
  • Protokoly ve výrobě by měly být minimální, aby se zbytečně nezatěžovalo.
  • Protokoly musí být strojově čitelné, normalizované a musí mít striktní formát.
  • Opravdu kritické protokoly by měly být zasílány v samostatném proudu, který by měl být oddělen od hlavních.
  • Za zvážení stojí akumulátor kulatiny, který vás může ušetřit návalů vysoké zátěže a sjednotit zatížení skladu.

Logy v Kubernetes (a nejen) dnes: očekávání a realita
Tato jednoduchá pravidla, pokud by byla aplikována všude, by umožnila fungování výše popsaných obvodů - i když jim chybí důležité komponenty (baterie). Pokud takové zásady nedodržíte, úkol snadno zavede vás i infrastrukturu k další vysoce zatížené (a zároveň neefektivní) složce systému.

PS

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář