Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė

Dabar 2019 m., o mes vis dar neturime standartinio rąstų sujungimo sprendimo Kubernetes. Šiame straipsnyje, pasitelkdami realios praktikos pavyzdžius, norėtume pasidalinti savo paieškomis, iškilusiomis problemomis ir jų sprendimais.

Tačiau pirmiausia aš padarysiu išlygą, kad skirtingi klientai, rinkdami žurnalus, supras labai skirtingus dalykus:

  • kažkas nori matyti saugos ir audito žurnalus;
  • kažkas – centralizuotas visos infrastruktūros registravimas;
  • o kai kuriems užtenka rinkti tik programų žurnalus, neįskaitant, pavyzdžiui, balansuotojų.

Žemiau yra iškarpa apie tai, kaip įgyvendinome įvairius „norų sąrašus“ ir su kokiais sunkumais susidūrėme.

Teorija: apie registravimo įrankius

Fonas apie medienos ruošos sistemos komponentus

Miško ruoša nuėjo ilgą kelią, dėl to buvo sukurtos rąstų rinkimo ir analizės metodikos, kurias naudojame šiandien. Dar šeštajame dešimtmetyje Fortran pristatė standartinių įvesties/išvesties srautų analogą, kuris padėjo programuotojui derinti savo programą. Tai buvo pirmieji kompiuterių žurnalai, palengvinę tų laikų programuotojų gyvenimą. Šiandien juose matome pirmąjį registravimo sistemos komponentą - rąstų šaltinis arba „gamintojas“..

Informatika nestovėjo vietoje: atsirado kompiuterių tinklai, pirmieji klasteriai... Pradėjo veikti sudėtingos sistemos, susidedančios iš kelių kompiuterių. Dabar sistemos administratoriai buvo priversti rinkti žurnalus iš kelių mašinų ir ypatingais atvejais galėjo pridėti OS branduolio pranešimus, jei prireiktų ištirti sistemos gedimą. 2000-ųjų pradžioje buvo paskelbtas centralizuotas žurnalų rinkimo sistemas RFC 3164, kuris standartizavo remote_syslog. Taip atsirado dar vienas svarbus komponentas: rąstų surinkėjas ir jų saugojimas.

Didėjant žurnalų apimtims ir plačiai diegiant žiniatinklio technologijas, iškilo klausimas, kokius žurnalus reikia patogiai parodyti vartotojams. Paprasti konsolės įrankiai (awk/sed/grep) buvo pakeisti pažangesniais žurnalo žiūrovai - trečiasis komponentas.

Padidėjus rąstų apimčiai paaiškėjo dar kai kas: rąstų reikia, bet ne visų. O skirtingiems rąstams reikalingas skirtingas konservavimo lygis: vienus galima pamesti per dieną, o kitus reikia saugoti 5 metus. Taigi į registravimo sistemą buvo įtrauktas duomenų srautų filtravimo ir nukreipimo komponentas - pavadinkime jį filtras.

Saugykla taip pat padarė didelį šuolį: nuo įprastų failų prie reliacinių duomenų bazių, o vėliau prie į dokumentus orientuotos saugyklos (pavyzdžiui, Elasticsearch). Taigi saugykla buvo atskirta nuo kolektoriaus.

Galiausiai pati rąsto sąvoka išsiplėtė iki savotiško abstraktaus įvykių srauto, kurį norime išsaugoti istorijai. Arba, jei reikia atlikti tyrimą ar surašyti analitinę ataskaitą...

Dėl to per gana trumpą laiką žurnalų rinkimas tapo svarbiu posistemiu, kurį teisėtai galima vadinti vienu iš Big Data poskyrių.

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė
Jei kažkada „logavimo sistemai“ užtekdavo paprastų spaudinių, tai dabar situacija labai pasikeitė.

Kubernetes ir rąstai

„Kubernetes“ atėjus į infrastruktūrą, jos neaplenkė ir jau egzistuojanti rąstų rinkimo problema. Kai kuriais atžvilgiais tai tapo dar skaudžiau: infrastruktūros platformos valdymas ne tik supaprastėjo, bet ir kartu komplikavosi. Daugelis senų paslaugų pradėjo pereiti prie mikro paslaugų. Žurnalų kontekste tai atsispindi augant žurnalų šaltinių skaičiui, ypatingam jų gyvavimo ciklui ir būtinybei sekti visų sistemos komponentų ryšius per žurnalus...

Žvelgiant į ateitį, galiu teigti, kad dabar, deja, nėra standartizuotos Kubernetes registravimo galimybės, kuri būtų palankesnė su visomis kitomis. Populiariausios schemos bendruomenėje yra šios:

  • kažkas išvynioja krūvą EFK (Elasticsearch, Fluentd, Kibana);
  • kažkas bando neseniai išleistą Loki arba naudoja Miško ruošos operatorius;
  • mums (o gal ne tik mes?..) Esu labai patenkintas savo tobulėjimu - rąstinis namas...

Paprastai K8s grupėse naudojame šiuos paketus (savarankiniams sprendimams):

Tačiau aš nesigilinsiu ties jų įrengimo ir konfigūravimo instrukcijomis. Vietoj to aš sutelksiu dėmesį į jų trūkumus ir globalesnes išvadas apie situaciją su rąstais apskritai.

Praktika su rąstais K8s

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė

„Kasdieniai rąstai“, kiek jūsų yra?..

Centralizuotas žurnalų surinkimas iš gana didelės infrastruktūros reikalauja nemažų resursų, kurie bus skirti rąstų rinkimui, saugojimui ir apdorojimui. Vykdant įvairius projektus, susidūrėme su įvairiais reikalavimais ir iš jų kylančiomis veiklos problemomis.

Pabandykime ClickHouse

Pažvelkime į centralizuotą projekto saugyklą su programa, kuri gana aktyviai generuoja žurnalus: daugiau nei 5000 eilučių per sekundę. Pradėkime dirbti su jo žurnalais, įtraukdami juos į ClickHouse.

Kai tik prireiks maksimalaus realaus laiko, 4 branduolių serveris su ClickHouse jau bus perkrautas disko posistemyje:

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė

Tokio tipo įkėlimas yra susijęs su tuo, kad mes stengiamės kuo greičiau parašyti ClickHouse. Ir duomenų bazė į tai reaguoja padidindama disko apkrovą, o tai gali sukelti šias klaidas:

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

Faktas yra tai, kad MergeTree lentelės „ClickHouse“ (jose yra žurnalo duomenų) rašymo operacijų metu turi savo sunkumų. Į juos įterpti duomenys sukuria laikiną skaidinį, kuris vėliau sujungiamas su pagrindine lentele. Dėl to įrašymas diske yra labai reiklus, be to, jam taip pat taikomas apribojimas, apie kurį gavome aukščiau pateiktą pranešimą: per 1 sekundę galima sujungti ne daugiau kaip 300 poskyrių (iš tikrųjų tai yra 300 įterpimų). per sekundę).

Norėdami išvengti tokio elgesio, turėtų parašyti ClickHouse kuo didesniais gabalais ir ne dažniau kaip 1 kartą per 2 sekundes. Tačiau rašymas didelėmis serijomis rodo, kad ClickHouse turėtume rašyti rečiau. Tai savo ruožtu gali sukelti buferio perpildymą ir žurnalų praradimą. Sprendimas yra padidinti Fluentd buferį, bet tada padidės ir atminties sąnaudos.

Atkreipti dėmesį: Kitas probleminis mūsų sprendimo su ClickHouse aspektas buvo susijęs su tuo, kad skaidymas mūsų atveju (rąstiniame name) įgyvendinamas per prijungtas išorines lenteles. Sujungti lentelę. Tai lemia tai, kad atimant didelius laiko intervalus reikia per daug RAM, nes metalentelė kartojasi per visus skaidinius - net tuos, kuriuose akivaizdžiai nėra reikiamų duomenų. Tačiau dabar šis metodas gali būti saugiai paskelbtas pasenusiu dabartinėse ClickHouse versijose (c 18.16).

Dėl to tampa aišku, kad ne kiekvienas projektas turi pakankamai resursų rinkti žurnalus realiu laiku ClickHouse (tiksliau, jų paskirstymas nebus tinkamas). Be to, reikės naudoti akumuliatorius, prie kurios grįšime vėliau. Aukščiau aprašytas atvejis yra tikras. Ir tuo metu negalėjome pasiūlyti patikimo ir stabilaus sprendimo, kuris tiktų klientui ir leistų surinkti rąstus su minimaliu vėlavimu...

O kaip Elasticsearch?

Yra žinoma, kad Elasticsearch atlaiko didelius darbo krūvius. Išbandykime tai tame pačiame projekte. Dabar apkrova atrodo taip:

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė

„Elasticsearch“ sugebėjo suvirškinti duomenų srautą, tačiau rašant tokius tomus labai išnaudojamas centrinis procesorius. Tai nusprendžiama organizuojant klasterį. Techniškai tai nėra problema, tačiau pasirodo, kad vien tik žurnalų surinkimo sistemai valdyti jau naudojame apie 8 branduolius ir sistemoje turime papildomą labai apkrautą komponentą...

Apatinė eilutė: ši galimybė gali būti pateisinama, tačiau tik tuo atveju, jei projektas yra didelis ir jo valdymas yra pasirengęs išleisti daug išteklių centralizuotai registravimo sistemai.

Tada kyla natūralus klausimas:

Kokių rąstų iš tikrųjų reikia?

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė Pabandykime pakeisti patį požiūrį: žurnalai vienu metu turėtų būti informatyvūs, o ne dengiantys kiekvienas įvykis sistemoje.

Tarkime, kad turime sėkmingą internetinę parduotuvę. Kokie rąstai yra svarbūs? Surinkti kuo daugiau informacijos, pavyzdžiui, iš mokėjimo šliuzo, yra puiki idėja. Tačiau ne visi vaizdų pjaustymo paslaugos žurnalai produktų kataloge mums yra svarbūs: pakanka tik klaidų ir išplėstinio stebėjimo (pavyzdžiui, 500 klaidų procentas, kurį sukuria šis komponentas).

Taigi padarėme tokią išvadą centralizuotas kirtimas ne visada pateisinamas. Labai dažnai klientas nori surinkti visus žurnalus vienoje vietoje, nors iš tikrųjų iš viso žurnalo reikalingi tik sąlyginiai 5% verslui svarbių pranešimų:

  • Kartais užtenka sukonfigūruoti, tarkime, tik konteinerio žurnalo dydį ir klaidų rinkiklį (pavyzdžiui, Sentry).
  • Įvykiams ištirti dažnai gali pakakti pranešimo apie klaidą ir paties didelio vietinio žurnalo.
  • Turėjome projektų, kurie apsigyveno tik funkciniais testais ir klaidų rinkimo sistemomis. Kūrėjui žurnalų kaip tokių nereikėjo – jie matė viską nuo klaidų pėdsakų.

Iliustracija iš gyvenimo

Kita istorija gali būti geras pavyzdys. Gavome vieno iš mūsų klientų apsaugos komandos užklausą, kuri jau naudojo komercinį sprendimą, kuris buvo sukurtas gerokai prieš „Kubernetes“ pristatymą.

Reikėjo „susidraugauti“ su centralizuota žurnalų surinkimo sistema su įmonės problemų aptikimo jutikliu - QRadar. Ši sistema gali gauti žurnalus per syslog protokolą ir nuskaityti juos iš FTP. Tačiau nebuvo iš karto įmanoma jo integruoti su remote_syslog papildiniu, skirtu fluentd (kaip paaiškėjo, mes ne vieni). Paaiškėjo, kad problemos, susijusios su QRadar nustatymu, kilo iš kliento apsaugos komandos.

Dėl to dalis verslui svarbių žurnalų buvo įkelti į FTP QRadar, o kita dalis buvo nukreipta per nuotolinį sistemos žurnalą tiesiai iš mazgų. Už tai net parašėme paprasta diagrama - gal kam nors padės išspręsti panašią problemą... Dėl susidariusios schemos klientas pats gavo ir išanalizavo kritinius žurnalus (naudodamas savo mėgstamus įrankius), o mes sugebėjome sumažinti registravimo sistemos kainą, sutaupydami tik praeitą mėnesį.

Kitas pavyzdys puikiai parodo, ko nedaryti. Vienas iš mūsų klientų apdorojimui kiekvienas įvykiai, gaunami iš vartotojo, sudaryti iš kelių eilučių nestruktūrizuota produkcija informacija žurnale. Kaip galima numanyti, tokius žurnalus buvo itin nepatogu tiek skaityti, tiek saugoti.

Rąstų kriterijai

Tokie pavyzdžiai leidžia daryti išvadą, kad be rąstų surinkimo sistemos pasirinkimo reikia taip pat suprojektuoti pačius rąstus! Kokie čia reikalavimai?

  • Žurnalai turi būti mašininio skaitomo formato (pvz., JSON).
  • Žurnalai turi būti kompaktiški ir su galimybe keisti registravimo laipsnį, kad būtų galima derinti galimas problemas. Tuo pačiu metu gamybinėse aplinkose turėtumėte paleisti tokias sistemas kaip registravimo lygis įspėjimas arba klaida.
  • Žurnalai turi būti normalizuoti, tai yra, žurnalo objekte visos eilutės turi turėti tą patį lauko tipą.

Nestruktūrizuoti rąstai gali sukelti problemų pakraunant rąstus į saugyklą ir visiškai sustabdyti jų apdorojimą. Kaip iliustraciją, čia pateikiamas pavyzdys su 400 klaida, su kuria daugelis neabejotinai susidūrė „fluentd“ žurnaluose:

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

Klaida reiškia, kad siunčiate lauką, kurio tipas yra nestabilus, indeksui su paruoštu susiejimu. Paprasčiausias pavyzdys yra laukas nginx žurnale su kintamuoju $upstream_status. Jame gali būti skaičius arba eilutė. Pavyzdžiui:

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

Žurnalai rodo, kad serveris 10.100.0.10 atsakė su 404 klaida ir užklausa buvo išsiųsta į kitą turinio saugyklą. Dėl to žurnalų reikšmė tapo tokia:

"upstream_response_time": "0.001, 0.007"

Ši situacija tokia įprasta, kad net nusipelno atskiro nuorodos dokumentuose.

O kaip dėl patikimumo?

Būna atvejų, kai visi be išimties rąstai yra gyvybiškai svarbūs. Dėl to kyla problemų dėl tipinių K8s rąstų surinkimo schemų, pasiūlytų / aptartų aukščiau.

Pavyzdžiui, fluentd negali rinkti rąstų iš trumpaamžių konteinerių. Viename iš mūsų projektų duomenų bazės perkėlimo konteineris veikė mažiau nei 4 sekundes, o tada buvo ištrintas – pagal atitinkamą anotaciją:

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

Dėl šios priežasties perkėlimo vykdymo žurnalas nebuvo įtrauktas į saugyklą. Šiuo atveju gali padėti politika. before-hook-creation.

Kitas pavyzdys yra „Docker“ žurnalo pasukimas. Tarkime, kad yra programa, kuri aktyviai rašo į žurnalus. Įprastomis sąlygomis mums pavyksta apdoroti visus žurnalus, tačiau vos tik iškyla problema – pavyzdžiui, kaip aprašyta aukščiau su netinkamu formatu – apdorojimas sustabdomas, o „Docker“ pasuka failą. Dėl to gali būti prarasti verslui svarbūs žurnalai.

Štai kodėl svarbu atskirti rąstų srautus, įterpdami vertingiausius tiesiai į programą, kad būtų užtikrintas jų saugumas. Be to, nebūtų nereikalinga sukurti keletą rąstų „akumuliatorius“., kuri gali išgyventi, kai saugykla nebus pasiekiama trumpam laikui, išsaugant svarbius pranešimus.

Galiausiai, mes neturime to pamiršti Svarbu tinkamai stebėti bet kurį posistemį. Priešingu atveju lengva patekti į situaciją, kurioje fluentd yra būsenoje CrashLoopBackOff ir nieko nesiunčia, ir tai žada prarasti svarbią informaciją.

išvados

Šiame straipsnyje mes nenagrinėjame „SaaS“ sprendimų, tokių kaip „Datadog“. Daugelį čia aprašytų problemų vienaip ar kitaip jau išsprendė komercinės įmonės, kurios specializuojasi renkant žurnalus, tačiau ne visi dėl įvairių priežasčių gali naudotis SaaS (pagrindiniai yra kaina ir atitikimas 152-FZ).

Centralizuotas žurnalų rinkimas iš pradžių atrodo kaip paprasta užduotis, tačiau taip nėra. Svarbu atsiminti, kad:

  • Tik svarbiausi komponentai turi būti išsamiai registruojami, o stebėjimą ir klaidų rinkimą galima konfigūruoti kitoms sistemoms.
  • Rąstai gamyboje turėtų būti minimalūs, kad nebūtų papildomos apkrovos.
  • Žurnalai turi būti nuskaitomi mašininiu būdu, normalizuoti ir turėti griežtą formatą.
  • Tikrai svarbūs žurnalai turėtų būti siunčiami atskiru srautu, kuris turėtų būti atskirtas nuo pagrindinių.
  • Verta pagalvoti apie rąstų akumuliatorių, kuris gali išgelbėti jus nuo didelės apkrovos sprogimų ir padaryti saugyklos apkrovą tolygesnę.

Žurnalai Kubernetes (ir ne tik) šiandien: lūkesčiai ir realybė
Šios paprastos taisyklės, jei būtų taikomos visur, leistų veikti aukščiau aprašytoms grandinėms, net jei jose trūksta svarbių komponentų (akumuliatoriaus). Jei tokių principų nesilaikysite, užduotis lengvai nuves jus ir infrastruktūrą prie kito labai apkrauto (o kartu ir neefektyvaus) sistemos komponento.

PS

Taip pat skaitykite mūsų tinklaraštyje:

Šaltinis: www.habr.com

Добавить комментарий