Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost

2019. je, a mi još uvijek nemamo standardno rješenje za agregaciju dnevnika u Kubernetesu. U ovom članku želimo, koristeći primjere iz stvarne prakse, podijeliti naša pretraživanja, probleme na koje smo naišli i njihova rješenja.

Međutim, prvo ću rezervirati da različiti korisnici shvaćaju vrlo različite stvari prikupljanjem zapisa:

  • netko želi vidjeti sigurnosne i revizijske zapisnike;
  • netko - centralizirano evidentiranje cijele infrastrukture;
  • a za neke je dovoljno prikupiti samo zapise aplikacija, isključujući, na primjer, balansere.

Ispod je isječak u nastavku o tome kako smo implementirali razne "popise želja" i na koje smo poteškoće naišli.

Teorija: o alatima za bilježenje

Pozadina komponenti sustava za bilježenje

Sječa je daleko odmakla, zbog čega su razvijene metodologije za prikupljanje i analizu trupaca, koje danas koristimo. Davnih 1950-ih, Fortran je predstavio analogiju standardnih ulazno/izlaznih tokova, koji su programeru pomogli u otklanjanju pogrešaka u njegovom programu. Bili su to prvi računalni zapisnici koji su programerima tog vremena olakšavali život. Danas u njima vidimo prvu komponentu sustava sječe - izvor ili "proizvođač" dnevnika.

Informatika nije stajala na mjestu: pojavile su se računalne mreže, prvi klasteri... Počeli su raditi složeni sustavi koji se sastoje od nekoliko računala. Sada su administratori sustava bili prisiljeni prikupljati zapise s nekoliko strojeva, au posebnim slučajevima mogli su dodati poruke jezgre OS-a u slučaju da trebaju istražiti kvar sustava. Kako bi se opisali centralizirani sustavi prikupljanja dnevnika, objavljen je početkom 2000-ih RFC 3164, koji je standardizirao remote_syslog. Ovako se pojavila još jedna važna komponenta: sakupljač trupaca i njihovo skladištenje.

S porastom količine logova i raširenim uvođenjem web tehnologija, postavilo se pitanje koje logove treba zgodno prikazati korisnicima. Jednostavni konzolni alati (awk/sed/grep) zamijenjeni su naprednijima gledatelji dnevnika - treća komponenta.

Zbog povećanja volumena cjepanica postalo je jasno još nešto: cjepanice su potrebne, ali ne sve. A različiti dnevnici zahtijevaju različite razine očuvanja: neki se mogu izgubiti u jednom danu, dok se drugi moraju čuvati 5 godina. Dakle, komponenta za filtriranje i usmjeravanje protoka podataka dodana je sustavu za bilježenje - nazovimo to filtar.

Pohrana je također napravila veliki skok: od običnih datoteka do relacijskih baza podataka, a zatim do pohrane orijentirane na dokumente (na primjer, Elasticsearch). Tako je skladište odvojeno od kolektora.

U konačnici, sam koncept loga proširio se na neku vrstu apstraktnog toka događaja koji želimo sačuvati za povijest. Ili bolje rečeno, u slučaju da trebate provesti istragu ili sastaviti analitičko izvješće...

Kao rezultat toga, u relativno kratkom vremenskom razdoblju, log collection se razvio u važan podsustav, koji se s pravom može nazvati jednim od pododjeljaka u Big Data.

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost
Ako su nekada obični ispisi mogli biti dovoljni za “sustav logovanja”, sada se situacija uvelike promijenila.

Kubernetes i dnevnici

Kada je Kubernetes došao na infrastrukturu, ni njega nije zaobišao već postojeći problem prikupljanja logova. Na neki način postalo je još bolnije: upravljanje infrastrukturnom platformom nije samo pojednostavljeno, već se u isto vrijeme i zakompliciralo. Mnoge stare usluge počele su migrirati na mikroservise. U kontekstu logova to se očituje u sve većem broju izvora logova, njihovom posebnom životnom ciklusu, te potrebi praćenja odnosa svih komponenti sustava putem logova...

Gledajući unaprijed, mogu reći da sada, nažalost, ne postoji standardizirana opcija zapisivanja za Kubernetes koja bi se povoljno usporedila sa svim ostalima. Najpopularnije sheme u zajednici su sljedeće:

  • netko razmota hrpu EFK (Elasticsearch, Fluentd, Kibana);
  • netko pokušava nedavno objavljen Loki ili koristi Operator zapisivanja;
  • nas (a možda i ne samo mi?..) Uglavnom sam zadovoljan vlastitim razvojem - brvnara...

U pravilu koristimo sljedeće pakete u K8s klasterima (za rješenja koja se samostalno hostiraju):

Međutim, neću se zadržavati na uputama za njihovu instalaciju i konfiguraciju. Umjesto toga, fokusirat ću se na njihove nedostatke i globalnije zaključke o situaciji s trupcima općenito.

Vježbajte s trupcima u K8s

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost

“Dnevnici”, koliko vas ima?..

Centralizirano prikupljanje dnevnika iz prilično velike infrastrukture zahtijeva značajna sredstva koja će se potrošiti na prikupljanje, pohranu i obradu dnevnika. Tijekom rada na različitim projektima suočavali smo se s različitim zahtjevima i operativnim problemima koji iz njih proizlaze.

Isprobajmo ClickHouse

Pogledajmo centraliziranu pohranu na projektu s aplikacijom koja prilično aktivno generira zapise: više od 5000 redaka u sekundi. Počnimo raditi s njegovim zapisima, dodajući ih u ClickHouse.

Čim bude potrebno maksimalno stvarno vrijeme, 4-jezgreni poslužitelj s ClickHouseom već će biti preopterećen na diskovnom podsustavu:

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost

Ova vrsta učitavanja je zbog činjenice da pokušavamo pisati u ClickHouse što je brže moguće. A baza podataka na to reagira povećanim opterećenjem diska, što može uzrokovati sljedeće pogreške:

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

Činjenica je da MergeTree tablice u ClickHouseu (sadrže podatke dnevnika) imaju svoje poteškoće tijekom operacija pisanja. Podaci umetnuti u njih generiraju privremenu particiju, koja se zatim spaja s glavnom tablicom. Kao rezultat toga, snimanje se pokazalo vrlo zahtjevnim za disk, a također je podložno ograničenju o kojem smo primili obavijest o gore: ne može se spojiti više od 1 podparticija u 300 sekundi (zapravo, ovo je 300 umetaka po sekundi).

Da biste izbjegli ovakvo ponašanje, treba pisati ClickHouseu u što većim komadima i ne više od 1 puta svake 2 sekunde. Međutim, pisanje u velikim rafalima sugerira da bismo trebali rjeđe pisati u ClickHouse. To zauzvrat može dovesti do prekoračenja međuspremnika i gubitka zapisa. Rješenje je povećati Fluentd međuspremnik, ali tada će se povećati i potrošnja memorije.

Primijetiti: Još jedan problematičan aspekt našeg rješenja s ClickHouseom bio je povezan s činjenicom da je particioniranje u našem slučaju (loghouse) implementirano putem povezanih vanjskih tablica Spoji tablicu. To dovodi do činjenice da je kod uzorkovanja velikih vremenskih intervala potreban prekomjerni RAM, budući da metatablica ponavlja kroz sve particije - čak i one koje očito ne sadrže potrebne podatke. Međutim, sada se ovaj pristup može sa sigurnošću proglasiti zastarjelim za trenutne verzije ClickHousea (c 18.16).

Kao rezultat toga, postaje jasno da nema svaki projekt dovoljno resursa za prikupljanje zapisa u stvarnom vremenu u ClickHouse (točnije, njihova distribucija neće biti odgovarajuća). Osim toga, morat ćete koristiti baterija, na koje ćemo se vratiti kasnije. Gore opisani slučaj je stvaran. A u to vrijeme nismo bili u mogućnosti ponuditi pouzdano i stabilno rješenje koje bi odgovaralo kupcu i omogućilo nam prikupljanje trupaca s minimalnim kašnjenjem...

Što je s Elasticsearchom?

Poznato je da Elasticsearch podnosi velika radna opterećenja. Pokušajmo to u istom projektu. Sada opterećenje izgleda ovako:

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost

Elasticsearch je uspio probaviti tok podataka, međutim, pisanje takvih volumena u njega uvelike iskorištava CPU. O tome se odlučuje organiziranjem klastera. Tehnički, to nije problem, ali ispada da samo za rad sustava za prikupljanje zapisa već koristimo oko 8 jezgri i imamo dodatnu visoko opterećenu komponentu u sustavu...

Zaključak: ova se opcija može opravdati, ali samo ako je projekt velik i njegovo je rukovodstvo spremno potrošiti značajna sredstva na centralizirani sustav evidentiranja.

Tada se postavlja prirodno pitanje:

Kakvi su dnevnici stvarno potrebni?

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost Pokušajmo promijeniti sam pristup: dnevnici bi istovremeno trebali biti informativni, a ne naslovni svaki događaj u sustavu.

Recimo da imamo uspješnu online trgovinu. Koji su zapisnici važni? Prikupiti što više informacija, na primjer, s pristupnika za plaćanje, odlična je ideja. Ali nisu nam svi zapisnici iz usluge rezanja slika u katalogu proizvoda kritični: dovoljni su samo pogreške i napredni nadzor (na primjer, postotak od 500 pogrešaka koje ova komponenta generira).

Tako smo došli do zaključka da centralizirano evidentiranje nije uvijek opravdano. Vrlo često klijent želi prikupiti sve logove na jednom mjestu, iako je zapravo od cijelog dnevnika potrebno samo uvjetno 5% poruka koje su kritične za poslovanje:

  • Ponekad je dovoljno konfigurirati, recimo, samo veličinu dnevnika spremnika i kolektora pogrešaka (na primjer, Sentry).
  • Obavijest o pogrešci i sam veliki lokalni dnevnik često mogu biti dovoljni za istraživanje incidenata.
  • Imali smo projekte koji su se zadovoljili isključivo funkcionalnim testovima i sustavima prikupljanja grešaka. Programeru nisu bili potrebni zapisnici kao takvi - sve su vidjeli iz tragova grešaka.

Ilustracija iz života

Druga priča može poslužiti kao dobar primjer. Dobili smo zahtjev od sigurnosnog tima jednog od naših klijenata koji je već koristio komercijalno rješenje koje je razvijeno davno prije predstavljanja Kubernetesa.

Bilo je potrebno „sprijateljiti“ centralizirani sustav prikupljanja zapisa s korporativnim senzorom za otkrivanje problema - QRadar. Ovaj sustav može primati zapise preko syslog protokola i dohvaćati ih s FTP-a. Međutim, nije ga bilo moguće odmah integrirati s dodatkom remote_syslog za fluentd (kako je ispalo, nismo sami). Ispostavilo se da su problemi s postavljanjem QRadara na strani sigurnosnog tima klijenta.

Kao rezultat toga, dio dnevnika kritičnih za poslovanje prenesen je na FTP QRadar, a drugi dio je preusmjeren putem udaljenog sysloga izravno s čvorova. Za ovo smo čak i napisali jednostavan grafikon - možda će nekome pomoći u rješavanju sličnog problema... Zahvaljujući rezultirajućoj shemi, klijent je sam primio i analizirao kritične zapise (koristeći svoje omiljene alate), a mi smo uspjeli smanjiti troškove sustava zapisivanja, štedeći samo prošli mjesec.

Još jedan primjer prilično je indikativan što ne treba činiti. Jedan od naših klijenata za obradu svaki događaji koji dolaze od korisnika, višelinijski nestrukturirani izlaz podaci u dnevniku. Kao što možda pretpostavljate, takvi su zapisnici bili vrlo nezgodni za čitanje i pohranjivanje.

Kriteriji za trupce

Takvi primjeri navode na zaključak da osim odabira sustava prikupljanja trupaca trebate također dizajnirajte same trupce! Koji su zahtjevi ovdje?

  • Dnevnici moraju biti u strojno čitljivom formatu (na primjer, JSON).
  • Dnevnici bi trebali biti kompaktni i s mogućnošću promjene stupnja zapisivanja kako bi se otklonili mogući problemi. U isto vrijeme, u proizvodnim okruženjima trebali biste pokretati sustave s razinom bilježenja kao što je Upozorenje ili greška.
  • Zapisi moraju biti normalizirani, to jest, u objektu dnevnika, sve linije moraju imati istu vrstu polja.

Nestrukturirani zapisi mogu dovesti do problema s učitavanjem zapisa u pohranu i potpunog zaustavljanja njihove obrade. Kao ilustracija, evo primjera s greškom 400, s kojom su se mnogi sigurno susreli u fluentd logovima:

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

Greška znači da šaljete polje čiji je tip nestabilan u indeks s gotovim mapiranjem. Najjednostavniji primjer je polje u nginx logu s varijablom $upstream_status. Može sadržavati ili broj ili niz. Na primjer:

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

Dnevnici pokazuju da je poslužitelj 10.100.0.10 odgovorio pogreškom 404 i zahtjev je poslan u drugu pohranu sadržaja. Kao rezultat toga, vrijednost u zapisnicima postala je ovakva:

"upstream_response_time": "0.001, 0.007"

Ova situacija je toliko česta da čak zaslužuje zaseban reference u dokumentaciji.

Što je s pouzdanošću?

Postoje trenuci kada su svi dnevnici bez iznimke vitalni. I s tim, tipične sheme prikupljanja dnevnika za K8 predložene/razmotrene gore imaju problema.

Na primjer, fluentd ne može prikupljati zapise iz kratkotrajnih spremnika. U jednom od naših projekata, spremnik za migraciju baze podataka živio je manje od 4 sekunde, a zatim je izbrisan - prema odgovarajućoj napomeni:

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

Zbog toga dnevnik izvršenja migracije nije bio uključen u pohranu. Politika u ovom slučaju može pomoći. before-hook-creation.

Drugi primjer je rotacija Docker dnevnika. Recimo da postoji aplikacija koja aktivno zapisuje zapise. U normalnim uvjetima uspijevamo obraditi sve zapisnike, ali čim se pojavi problem - na primjer, kao što je gore opisano s neispravnim formatom - obrada se zaustavlja, a Docker rotira datoteku. Rezultat je da se poslovni zapisnici mogu izgubiti.

Zato je važno je odvojiti tokove dnevnika, ugrađujući slanje najvrjednijih izravno u aplikaciju kako bi se osigurala njihova sigurnost. Osim toga, ne bi bilo suvišno stvoriti neke “akumulator” trupaca, koji može preživjeti kratku nedostupnost pohrane dok sprema kritične poruke.

Na kraju, to ne smijemo zaboraviti Važno je ispravno nadzirati svaki podsustav. Inače je lako doći u situaciju da je fluentd u stanju CrashLoopBackOff i ne šalje ništa, a to obećava gubitak važnih informacija.

Zaključci

U ovom članku ne razmatramo SaaS rješenja kao što je Datadog. Mnoge od ovdje opisanih problema već su na ovaj ili onaj način riješile komercijalne tvrtke specijalizirane za prikupljanje zapisa, ali ne može svatko koristiti SaaS iz različitih razloga (glavni su trošak i usklađenost s 152-FZ).

Centralizirano prikupljanje dnevnika na prvi pogled izgleda kao jednostavan zadatak, ali to uopće nije. Važno je zapamtiti sljedeće:

  • Samo kritične komponente moraju biti detaljno evidentirane, dok se nadzor i prikupljanje grešaka mogu konfigurirati za druge sustave.
  • Dnevnici u proizvodnji trebaju biti minimalni kako se ne bi dodavalo nepotrebno opterećenje.
  • Dnevnici moraju biti strojno čitljivi, normalizirani i imati strogi format.
  • Stvarno kritične zapisnike treba slati u zasebnom toku, koji treba biti odvojen od glavnih.
  • Vrijedno je razmisliti o akumulatoru cjepanica, koji vas može spasiti od naleta velikog opterećenja i učiniti opterećenje skladišta ravnomjernijim.

Dnevnici u Kubernetesu (i ne samo) danas: očekivanja i stvarnost
Ova jednostavna pravila, kad bi se svugdje primjenjivala, omogućila bi gore opisanim sklopovima da rade - iako im nedostaju važne komponente (baterija). Ako se ne pridržavate takvih načela, zadatak će vas i infrastrukturu lako odvesti do druge visoko opterećene (i istovremeno neučinkovite) komponente sustava.

PS

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar