Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid

Dit was 2019 en ons het steeds nie 'n standaardoplossing vir log-aggregasie in Kubernetes gehad nie. In hierdie artikel wil ons graag ons soektogte, probleme wat ondervind is en hul oplossings deel, deur werklike voorbeelde te gebruik.

Om mee te begin, sal ek egter 'n bespreking maak dat verskillende kliënte baie verskillende dinge verstaan ​​deur logs te versamel:

  • iemand wil sekuriteit en oudit logs sien;
  • iemand - gesentraliseerde aantekening van die hele infrastruktuur;
  • en vir sommige is dit genoeg om slegs toepassingslogboeke te versamel, met uitsondering van byvoorbeeld balanseerders.

Oor hoe ons verskeie "Wishlists" geïmplementeer het en watter probleme ons ondervind het - onder die knie.

Teorie: oor loginstrumente

Agtergrond oor die komponente van die logstelsel

Logging het 'n lang pad gevorder, as gevolg waarvan metodologieë vir die insameling en ontleding van logs ontwikkel is, wat is wat ons vandag gebruik. Terug in die 1950's het Fortran 'n analoog van standaard toevoer-uitsetstrome bekendgestel wat die programmeerder gehelp het om sy program te ontfout. Dit was die eerste rekenaarlogboeke wat die lewe vir daardie tye makliker gemaak het. Vandag sien ons in hulle die eerste komponent van die aantekenstelsel - bron of "produsent" (produsent) van logs.

Rekenaarwetenskap het nie stilgestaan ​​nie: rekenaarnetwerke het verskyn, die eerste groepe ... Komplekse stelsels wat uit verskeie rekenaars bestaan ​​het, het begin werk. Nou is stelseladministrateurs gedwing om logs van verskeie masjiene in te samel, en in spesiale gevalle kon hulle OS-kernboodskappe byvoeg ingeval hulle 'n stelselfout moes ondersoek. Om gesentraliseerde logstelsels te beskryf, in die vroeë 2000's, RFC 3164, wat remote_syslog gestandaardiseer het. So het nog 'n belangrike komponent verskyn: versamelaar (versamelaar) van stompe en hul bewaarplek.

Met die toename in die volume logs en die wydverspreide bekendstelling van webtegnologieë, het die vraag ontstaan ​​dat logs gerieflik aan gebruikers gewys moet word. Eenvoudige konsole-nutsgoed (awk/sed/grep) is vervang deur meer gevorderdes. log kykers is die derde komponent.

In verband met die toename in die volume stompe, het nog iets duidelik geword: stompe is nodig, maar nie almal nie. En verskillende stompe vereis verskillende vlakke van bewaring: sommige kan binne 'n dag verlore gaan, terwyl ander vir 5 jaar gestoor moet word. Dus, 'n filter- en roeteringskomponent vir datavloei is by die aantekenstelsel gevoeg - kom ons noem dit filter.

Bewaarplekke het ook 'n groot sprong gemaak: hulle het oorgeskakel van gewone lêers na relasionele databasisse, en toe na dokumentgeoriënteerde bergings (byvoorbeeld Elasticsearch). Die stoor is dus van die versamelaar geskei.

Op die ou end het die konsep van die log uitgebrei tot 'n soort abstrakte stroom gebeurtenisse wat ons vir die geskiedenis wil stoor. Of eerder, in die geval dat jy 'n ondersoek moet doen of 'n analitiese verslag moet opstel ...

Gevolglik het die versameling van logboeke in 'n relatief kort tydperk ontwikkel tot 'n belangrike substelsel, wat met reg een van die onderafdelings in Big Data genoem kan word.

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid
As eens gewone afdrukke genoeg kon wees vir 'n "log-stelsel", het die situasie nou baie verander.

Kubernetes en logs

Toe Kubernetes by die infrastruktuur gekom het, het die reeds bestaande probleem om stompe in te samel dit ook nie omseil nie. In 'n sekere sin het dit selfs meer pynlik geword: die bestuur van die infrastruktuurplatform is nie net vereenvoudig nie, maar terselfdertyd ook ingewikkeld. Baie ou dienste het na mikrodiensspore begin migreer. In die konteks van logs is dit weerspieël in die groeiende aantal bronne van logs, hul spesiale lewensiklus, en die behoefte om die onderlinge verbindings van alle stelselkomponente deur logs op te spoor ...

As ek vorentoe kyk, kan ek sê dat daar nou ongelukkig geen gestandaardiseerde aantekenopsie vir Kubernetes is wat gunstig met al die ander sal vergelyk nie. Die gewildste skemas in die gemeenskap kom op die volgende neer:

  • iemand rol die stapel af EFK (Elasticsearch, Fluentd, Kibana);
  • iemand probeer die nuut vrygestelde Loki of gebruike Teken operateur;
  • ons (en dalk nie net ons nie? ..) grootliks tevrede met hul eie ontwikkeling - houthuis...

As 'n reël gebruik ons ​​sulke bondels in K8s-klusters (vir self-gasheeroplossings):

Ek sal egter nie stilstaan ​​by die instruksies vir hul installasie en konfigurasie nie. In plaas daarvan sal ek fokus op hul tekortkominge en meer globale gevolgtrekkings oor die situasie met die logs in die algemeen.

Oefen met logs in K8s

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid

"Alledaagse logs", hoeveel van julle? ..

Gesentraliseerde versameling van stompe vanaf 'n voldoende groot infrastruktuur vereis aansienlike hulpbronne wat aan die versameling, berging en verwerking van logs bestee sal word. Tydens die bedryf van verskeie projekte het ons verskeie vereistes en gevolglike probleme in die bedryf teëgekom.

Kom ons probeer ClickHouse

Kom ons oorweeg 'n gesentraliseerde bewaarplek op 'n projek met 'n toepassing wat heelwat logs genereer: meer as 5000 reëls per sekonde. Kom ons begin werk met sy logboeke en voeg dit by ClickHouse.

Sodra die maksimum intydse tyd vereis word, sal die 4-kern bediener met ClickHouse reeds oorlaai wees op die skyf substelsel:

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid

Hierdie tipe aflaai is te wyte aan die feit dat ons probeer om so vinnig as moontlik in ClickHouse te skryf. En die databasis reageer hierop met 'n verhoogde skyflading, wat sulke foute kan veroorsaak:

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

Feit is dat MergeTree-tabelle in ClickHouse (hulle bevat logdata) het hul eie probleme met skryfbewerkings. Die data wat daarin ingevoeg word, genereer 'n tydelike partisie, wat dan saamgevoeg word met die hooftabel. As gevolg hiervan blyk die rekord baie veeleisend op die skyf te wees, en dit is ook onderhewig aan die beperking waaroor ons hierbo in kennis gestel is: nie meer as 1 subpartisies kan in 300 sekonde saamsmelt nie (dit is trouens 300 invoegings per tweede).

Om hierdie gedrag te vermy, moet aan ClickHouse skryf in so groot stukke as moontlik en nie meer as een keer elke 1 sekondes nie. Om in groot groepe te skryf, dui egter daarop dat ons minder gereeld aan ClickHouse moet skryf. Dit kan op sy beurt lei tot bufferoorvloei en verlies van stompe. Die oplossing is om die Fluentd-buffer te verhoog, maar dan sal die geheueverbruik ook toeneem.

Let daarop: Nog 'n problematiese kant van ons oplossing met ClickHouse was verwant aan die feit dat partisionering in ons geval (loghouse) geïmplementeer word deur eksterne tabelle wat gekoppel is Voeg tabel saam. Dit lei daartoe dat wanneer u groot tydintervalle haal, oormatige RAM benodig word, aangesien die metatable oor alle partisies herhaal word - selfs dié wat natuurlik nie die nodige data bevat nie. Nou kan hierdie benadering egter veilig as verouderd verklaar word vir huidige weergawes van ClickHouse (c 18.16).

As gevolg hiervan word dit duidelik dat nie elke projek genoeg hulpbronne sal hê om intydse logboeke in ClickHouse te versamel nie (meer presies, die verspreiding daarvan sal nie gepas wees nie). Daarbenewens sal jy moet gebruik battery, waarna ons sal terugkeer. Die geval hierbo beskryf is 'n ware een. En op daardie tydstip was ons nie in staat om 'n betroubare en stabiele oplossing te bied wat by die kliënt sou pas nie en wat die versameling van stompe met minimale vertraging sou toelaat...

Wat van elastiese soektog?

Dit is bekend dat Elasticsearch swaar werkladings hanteer. Kom ons probeer dit in dieselfde projek. Nou lyk die vrag so:

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid

Elasticsearch was in staat om die datastroom te verteer, maar om sulke volumes daaraan te skryf, verbruik baie SVE. Dit word deur die organisasie van die kluster besluit. Suiwer tegnies is dit nie 'n probleem nie, maar dit blyk dat ons net vir die werking van die logstelsel reeds ongeveer 8 kerne gebruik en 'n bykomende hoogs gelaaide komponent in die stelsel het ...

Bottom line: hierdie opsie kan geregverdig word, maar slegs as die projek groot is en die bestuur daarvan gereed is om aansienlike hulpbronne aan 'n gesentraliseerde logstelsel te bestee.

Dan ontstaan ​​'n natuurlike vraag:

Watter logs is regtig nodig?

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid Kom ons probeer om die benadering self te verander: die logs moet beide insiggewend wees en nie dek nie elke gebeurtenis in die stelsel.

Kom ons sê ons het 'n suksesvolle aanlynwinkel. Watter logs is belangrik? Om soveel moontlik inligting in te samel, byvoorbeeld vanaf 'n betaalpoort, is 'n goeie idee. Maar nie alle logs van die beeldsnydiens in die produkkatalogus is vir ons van kritieke belang nie: slegs foute en gevorderde monitering is genoeg (byvoorbeeld vir die persentasie van 500 foute wat hierdie komponent genereer).

Hier het ons tot die gevolgtrekking gekom dat gesentraliseerde aantekening is nie altyd geregverdig nie. Baie dikwels wil die kliënt al die logs op een plek versamel, alhoewel in werklikheid slegs 5% van die boodskappe wat krities is vir besigheid van die hele log vereis word:

  • Soms is dit genoeg om byvoorbeeld net die grootte van die houerlogboek en die foutversamelaar (byvoorbeeld Sentry) aan te pas.
  • Om voorvalle te ondersoek, kan 'n foutkennisgewing en 'n groot plaaslike logboek self dikwels genoeg wees.
  • Ons het projekte gehad wat heeltemal uitsluitlik bestuur is met funksionele toetse en foutinsamelingstelsels. Die ontwikkelaar het nie logs as sodanig nodig nie - hulle het alles van foutspore gesien.

lewens illustrasie

Nog 'n storie is 'n goeie voorbeeld. Ons het 'n versoek ontvang van die sekuriteitspan van een van die kliënte wat reeds 'n kommersiële oplossing gebruik het, wat lank voor die bekendstelling van Kubernetes ontwikkel is.

Dit was nodig om "vriende te maak" van die stelsel van gesentraliseerde versameling van logs met die korporatiewe sensor om probleme op te spoor - QRadar. Hierdie stelsel kan logs via die syslog-protokol ontvang, neem dit van FTP af. Dit was egter nie onmiddellik moontlik om dit met die remote_syslog-inprop vir fluentd te integreer nie (soos dit geblyk het, ons is nie alleen nie). Probleme met die opstel van QRadar het geblyk aan die kant van die kliënt se sekuriteitspan te wees.

Gevolglik is sommige besigheidskritiese logboeke na FTP QRadar opgelaai, terwyl die ander deel via afgeleë syslog direk vanaf die nodusse herlei is. Hiervoor het ons selfs geskryf eenvoudige grafiek - miskien sal dit iemand help om 'n soortgelyke probleem op te los ... Danksy die gevolglike skema het die kliënt self kritieke logboeke ontvang en ontleed (met sy gunsteling gereedskap), en ons kon die koste van die aantekenstelsel verminder, wat slegs die verlede maand.

Nog 'n voorbeeld is baie aanduidend van wat om nie te doen nie. Een van ons kliënte vir verwerking elkeen gebeure wat van die gebruiker af kom, het 'n multi-lyn gedoen ongestruktureerde uitset inligting in die logboek. Soos u kan raai, was sulke logboeke uiters ongerieflik om te lees en te stoor.

Kriteria vir logs

Sulke voorbeelde lei tot die gevolgtrekking dat benewens die keuse van 'n stelsel vir die versameling van stompe, dit nodig is om ontwerp die stompe self! Wat is die vereistes hier?

  • Die logs moet in 'n masjienleesbare formaat wees (byvoorbeeld JSON).
  • Die logs moet kompak wees en met die vermoë om die vlak van logging te verander om moontlike probleme te ontfout. Terselfdertyd, in produksie-omgewings, moet jy stelsels met 'n aantekenvlak soos waarskuwing of fout.
  • Logs moet genormaliseer word, dit wil sê, alle lyne in die log-objek moet dieselfde veldtipe hê.

Ongestruktureerde logs kan lei tot probleme met die oplaai van logs na die bewaarplek en om die verwerking daarvan heeltemal te stop. Ter illustrasie, hier is 'n voorbeeld met 'n 400-fout wat baie mense beslis in vloeiende logs teëgekom het:

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

Die fout beteken dat jy 'n veld waarvan die tipe onstabiel is na die indeks stuur met gereed kartering. Die eenvoudigste voorbeeld is 'n veld in die nginx-logboek met 'n veranderlike $upstream_status. Dit kan óf 'n nommer óf 'n string bevat. Byvoorbeeld:

{ "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"}

Die logs wys dat die bediener 10.100.0.10 met 'n 404-fout gereageer het en die versoek het na 'n ander inhoudwinkel gegaan. As gevolg hiervan het die waarde in die logboeke soos volg geword:

"upstream_response_time": "0.001, 0.007"

Hierdie situasie is so wydverspreid dat dit selfs 'n aparte verwysings in dokumentasie.

En wat van betroubaarheid?

Daar is tye wanneer al die logs sonder uitsondering noodsaaklik is. En hiermee het die tipiese skemas vir die versameling van logs vir K8's, voorgestel / hierbo bespreek, probleme.

Fluentd kan byvoorbeeld nie stompe van kortstondige houers versamel nie. In een van ons projekte het die databasismigrasiehouer vir minder as 4 sekondes geleef en is dan uitgevee - volgens die ooreenstemmende aantekening:

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

As gevolg hiervan is die migrasie-uitvoeringslogboek nie by die bewaarplek ingesluit nie. Beleid kan help in hierdie geval. before-hook-creation.

Nog 'n voorbeeld is Docker-logrotasie. Kom ons sê daar is 'n toepassing wat aktief na die logs skryf. Onder normale omstandighede het ons tyd om al die logs te verwerk, maar sodra daar 'n probleem is - byvoorbeeld, soos hierbo beskryf met die verkeerde formaat - stop verwerking, en Docker roteer die lêer. Bottom line - besigheid-kritiese logs kan verlore gaan.

Dis hoekom dit is belangrik om logstrome te skei, wat die stuur van die waardevolste direk in die toepassing insluit om hul veiligheid te verseker. Daarbenewens sal dit nie oorbodig wees om sommige te skep nie "battery" logs, wat 'n kort stooronderbreking kan oorleef terwyl kritieke boodskappe behou word.

Ten slotte moet ons dit nie vergeet nie enige substelsel is belangrik om kwalitatief te monitor. Andersins is dit maklik om in 'n situasie te beland waar fluentd in 'n toestand is CrashLoopBackOff en stuur niks nie, en dit beloof die verlies van belangrike inligting.

Bevindinge

In hierdie artikel oorweeg ons nie SaaS-oplossings soos Datadog nie. Baie van die probleme wat hier beskryf word, is reeds op een of ander manier opgelos deur kommersiële maatskappye wat spesialiseer in die versameling van logs, maar nie almal kan SaaS om verskeie redes gebruik nie. (die belangrikste is die koste en voldoening aan 152-FZ).

Gesentraliseerde loginsameling lyk aanvanklik na 'n eenvoudige taak, maar dit is glad nie. Dit is belangrik om te onthou dat:

  • Slegs kritieke komponente moet in detail aangeteken word, en vir ander stelsels kan monitering en foutversameling opgestel word.
  • Logs in produksie moet minimaal gehou word om nie 'n ekstra vrag te gee nie.
  • Logs moet masjienleesbaar, genormaliseer en streng geformateer wees.
  • Werklik kritiese logs moet in 'n aparte draad gestuur word, wat van die belangrikstes geskei moet word.
  • Dit is die moeite werd om 'n houtakkumulator te oorweeg, wat jou kan red van sarsies van hoë vrag en die las op die stoor meer egalig kan maak.

Log vandag in Kubernetes (en nie net nie): verwagtinge en werklikheid
Hierdie eenvoudige reëls, as dit oral toegepas word, sal die stroombane wat hierbo beskryf word, toelaat om te werk al het hulle nie belangrike komponente (die battery) nie. As jy nie by sulke beginsels hou nie, sal die taak jou en die infrastruktuur maklik na 'n ander hoogs gelaaide (en terselfdertyd ondoeltreffende) komponent van die stelsel lei.

PS

Lees ook op ons blog:

Bron: will.com

Voeg 'n opmerking