Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco

Estas 2019, kaj ni ankoraŭ ne havas norman solvon por protokolo-agregado en Kubernetes. En ĉi tiu artikolo, ni ŝatus, uzante ekzemplojn el reala praktiko, kunhavigi niajn serĉojn, problemojn renkontitajn kaj iliajn solvojn.

Tamen, unue, mi faros rezervon, ke malsamaj klientoj komprenas tre malsamajn aferojn kolektante protokolojn:

  • iu volas vidi sekurecajn kaj reviziajn protokolojn;
  • iu - centralizita arbohakado de la tuta infrastrukturo;
  • kaj por iuj, sufiĉas kolekti nur aplikajn protokolojn, ekskludante, ekzemple, ekvilibrilojn.

Malsupre estas la suba tranĉo pri kiel ni efektivigis diversajn "dezirlistojn" kaj kiajn malfacilaĵojn ni renkontis.

Teorio: pri registradaj iloj

Fono pri la komponantoj de registradsistemo

Arbodehakado faris longan vojon, rezulte de kiu estis evoluigitaj metodaroj por kolekti kaj analizi ŝtipojn, kio estas tio, kion ni uzas hodiaŭ. Reen en la 1950-aj jaroj, Fortran lanĉis analogon de normaj enig-/eligaj fluoj, kiuj helpis al la programisto senarmigi sian programon. Ĉi tiuj estis la unuaj komputilaj protokoloj, kiuj faciligis la vivon al tiutempaj programistoj. Hodiaŭ ni vidas en ili la unuan komponanton de la registra sistemo - fonto aŭ "produktanto" de ŝtipoj.

Komputiko ne staris senmove: aperis komputilaj retoj, la unuaj aretoj... Kompleksaj sistemoj konsistantaj el pluraj komputiloj ekfunkciis. Nun sistemadministrantoj estis devigitaj kolekti protokolojn de pluraj maŝinoj, kaj en specialaj kazoj ili povis aldoni OS-kernmesaĝojn en kazo ili bezonus esplori sisteman fiaskon. Por priskribi centralizitajn trungajn sistemojn, en la fruaj 2000-aj jaroj ĝi estis publikigita RFC 3164, kiu normigis remote_syslog. Jen kiel aperis alia grava ero: ŝtipkolektanto kaj ilia konservado.

Kun la kresko de la volumo de ŝtipoj kaj la disvastigita enkonduko de retaj teknologioj, ŝprucis la demando, kiaj ŝtipoj devas esti oportune montritaj al uzantoj. Simplaj konzoliloj (awk/sed/grep) estis anstataŭigitaj per pli progresintaj protokoloj rigardantoj - tria komponanto.

Pro la kresko de la volumo de ŝtipoj evidentiĝis io alia: ŝtipoj estas bezonataj, sed ne ĉiuj. Kaj malsamaj ŝtipoj postulas malsamajn nivelojn de konservado: kelkaj povas esti perditaj en tago, dum aliaj devas esti konservitaj dum 5 jaroj. Do, komponanto por filtri kaj direkti datumfluojn estis aldonita al la registra sistemo - ni nomu ĝin filtrilo.

Stokado ankaŭ faris gravan salton: de regulaj dosieroj al interrilataj datumbazoj, kaj poste al dokument-orientita stokado (ekzemple, Elasticsearch). Do la stokado estis apartigita de la kolektanto.

Finfine, la koncepto mem de ŝtipo disetendiĝis al speco de abstrakta fluo de eventoj, kiujn ni volas konservi por la historio. Aŭ pli ĝuste, se vi bezonas fari enketon aŭ ellabori analizan raporton...

Kiel rezulto, en relative mallonga tempodaŭro, ŝtipkolekto evoluis al grava subsistemo, kiu povas prave esti nomita unu el la subsekcioj en Big Data.

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco
Se iam ordinaraj presaĵoj povus sufiĉi por "dehaka sistemo", nun la situacio multe ŝanĝiĝis.

Kubernetes kaj protokoloj

Kiam Kubernetes venis al la infrastrukturo, la jam ekzistanta problemo pri kolektado de ŝtipoj ankaŭ ne preteriris ĝin. Iasence, ĝi fariĝis eĉ pli dolora: administri la infrastrukturan platformon estis ne nur simpligita, sed ankaŭ komplika samtempe. Multaj malnovaj servoj komencis migri al mikroservoj. En la kunteksto de protokoloj, ĉi tio estas reflektita en la kreskanta nombro da protokolaj fontoj, ilia speciala vivociklo, kaj la bezono spuri la rilatojn de ĉiuj sistemkomponentoj per protokoloj...

Rigardante antaŭen, mi povas konstati, ke nun, bedaŭrinde, ne ekzistas normigita ensaluta opcio por Kubernetes, kiu komparus favore kun ĉiuj aliaj. La plej popularaj skemoj en la komunumo estas kiel sekvas:

  • iu malruligas la stakon EFK (Elasticsearch, Fluentd, Kibana);
  • iu provas la ĵus liberigitan Loki aŭ uzoj Registranta operatoro;
  • ni (kaj eble ne nur ni?..) Mi estas plejparte kontenta pri mia propra evoluo - ŝtipdomo...

Kiel regulo, ni uzas la sekvajn pakaĵojn en K8s-aretoj (por memgastigitaj solvoj):

Tamen, mi ne traktos instrukciojn por ilia instalado kaj agordo. Anstataŭe, mi koncentriĝos pri iliaj mankoj kaj pli tutmondaj konkludoj pri la situacio kun ŝtipoj ĝenerale.

Praktiku kun ŝtipoj en K8s

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco

"Ĉiutagaj ŝtipoj", kiom da vi estas tie?...

Alcentrigita kolekto de ŝtipoj de sufiĉe granda infrastrukturo postulas konsiderindajn rimedojn, kiuj estos elspezitaj por kolektado, stokado kaj prilaborado de ŝtipoj. Dum la funkciado de diversaj projektoj, ni alfrontis diversajn postulojn kaj operaciajn problemojn devenantajn de ili.

Ni provu ClickHouse

Ni rigardu centralizitan stokadon en projekto kun aplikaĵo, kiu generas protokolojn sufiĉe aktive: pli ol 5000 linioj sekundo. Ni komencu labori kun liaj protokoloj, aldonante ilin al ClickHouse.

Tuj kiam necesas maksimuma reala tempo, la 4-kerna servilo kun ClickHouse jam estos troŝarĝita sur la disksubsistemo:

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco

Ĉi tiu tipo de ŝarĝo estas pro la fakto, ke ni provas skribi en ClickHouse kiel eble plej rapide. Kaj la datumbazo reagas al tio kun pliigita disko-ŝarĝo, kio povas kaŭzi la jenajn erarojn:

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

Punkto estas ke MergeTree-tabloj en ClickHouse (ili enhavas protokolojn) havas siajn proprajn malfacilaĵojn dum skribaj operacioj. La datumoj enmetitaj en ilin generas provizoran sekcion, kiu tiam estas kunfandita kun la ĉefa tablo. Kiel rezulto, la registrado montriĝas tre postulema sur la disko, kaj ĝi ankaŭ estas submetita al la limigo, pri kiu ni ricevis avizon supre: ne pli ol 1 subsekcioj povas esti kunfanditaj en 300 sekundo (fakte, ĉi tio estas 300 enmetoj. je sekundo).

Por eviti ĉi tiun konduton, devus skribi al ClickHouse en kiel eble plej grandaj pecoj kaj ne pli ol 1 fojon ĉiu 2 sekundoj. Tamen, skribi en grandaj eksplodoj sugestas, ke ni skribu malpli ofte en ClickHouse. Ĉi tio, siavice, povas kaŭzi bufran superfluon kaj perdon de ŝtipoj. La solvo estas pliigi la bufron Fluentd, sed tiam ankaŭ pliiĝos la memorkonsumo.

Примечание: Alia problema aspekto de nia solvo kun ClickHouse estis rilatita al la fakto ke dispartigo en nia kazo (trabdomo) estas efektivigita per eksteraj tabloj konektitaj. Kunfandi tablon. Ĉi tio kondukas al la fakto, ke dum provado de grandaj tempintervaloj, troa RAM estas postulata, ĉar la metatablo ripetas tra ĉiuj sekcioj - eĉ tiuj kiuj evidente ne enhavas la necesajn datumojn. Tamen, nun ĉi tiu aliro povas esti sekure deklarita malnoviĝinta por nunaj versioj de ClickHouse (ĉ 18.16).

Kiel rezulto, evidentiĝas, ke ne ĉiu projekto havas sufiĉajn rimedojn por kolekti ŝtipojn en reala tempo en ClickHouse (pli precize, ilia distribuo ne taŭgos). Krome, vi devos uzi baterio, al kiu ni revenos poste. La kazo priskribita supre estas reala. Kaj tiam ni ne povis proponi fidindan kaj stabilan solvon, kiu konvenus al la kliento kaj permesus al ni kolekti ŝtipojn kun minimuma prokrasto...

Kio pri Elasticsearch?

Elasticsearch povas trakti pezajn laborŝarĝojn. Ni provu ĝin en la sama projekto. Nun la ŝarĝo aspektas jene:

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco

Elasticsearch povis digesti la datumfluon, tamen, skribi tiajn volumojn al ĝi multe uzas la CPU. Ĉi tio estas decidita per organizado de areto. Teknike ĉi tio ne estas problemo, sed rezultas, ke nur por funkciigi la ŝtipkolektan sistemon ni jam uzas ĉirkaŭ 8 kernojn kaj havas aldonan tre ŝarĝitan komponanton en la sistemo...

Fundo: ĉi tiu opcio povas esti pravigita, sed nur se la projekto estas granda kaj ĝia administrado pretas elspezi signifajn rimedojn por centralizita registra sistemo.

Tiam aperas natura demando:

Kiuj ŝtipoj vere bezonas?

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco Ni provu ŝanĝi la aliron mem: protokoloj devas esti samtempe informaj kaj ne kovri ĉiu evento en la sistemo.

Ni diru, ke ni havas sukcesan interretan vendejon. Kiuj ŝtipoj estas gravaj? Kolekti kiel eble plej multe da informoj, ekzemple, de pagpordejo, estas bonega ideo. Sed ne ĉiuj protokoloj de la bildtranĉa servo en la produkta katalogo estas kritikaj por ni: sufiĉas nur eraroj kaj altnivela monitorado (ekzemple la procento de 500 eraroj, kiujn ĉi tiu komponanto generas).

Do ni venis al la konkludo ke centralizita arbohakado ne ĉiam pravigas. Tre ofte la kliento volas kolekti ĉiujn protokolojn en unu loko, kvankam fakte, el la tuta protokolo, necesas nur kondiĉa 5% de mesaĝoj, kiuj estas kritikaj por la komerco:

  • Kelkfoje sufiĉas agordi, ekzemple, nur la grandecon de la ujo-protokolo kaj la erarkolektilo (ekzemple, Sentry).
  • Erara sciigo kaj granda loka protokolo mem ofte povas sufiĉi por esplori okazaĵojn.
  • Ni havis projektojn, kiuj kontentiĝis kun ekskluzive funkciaj testoj kaj erarkolektaj sistemoj. La programisto ne bezonis protokolojn kiel tiajn - ili vidis ĉion el erarspuroj.

Ilustraĵo el vivo

Alia rakonto povas servi kiel bona ekzemplo. Ni ricevis peton de la sekureca teamo de unu el niaj klientoj, kiu jam uzis komercan solvon, kiu estis evoluigita longe antaŭ la enkonduko de Kubernetes.

Necesis "amiki" de la centralizita ŝtipkolekta sistemo kun la kompania problemo-detekta sensilo - QRadar. Ĉi tiu sistemo povas ricevi protokolojn per la syslog-protokolo kaj preni ilin de FTP. Tamen, ne tuj eblis integri ĝin kun la aldonaĵo remote_syslog por fluentd (kiel evidentiĝis, ni ne estas solaj). Problemoj kun agordo de QRadar montriĝis flanke de la sekureca teamo de la kliento.

Kiel rezulto, parto de la komercaj kritikaj protokoloj estis alŝutita al FTP QRadar, kaj la alia parto estis redirektita per fora syslog rekte de la nodoj. Por tio ni eĉ skribis simpla diagramo - eble ĝi helpos iun solvi similan problemon... Dank' al la rezulta skemo, la kliento mem ricevis kaj analizis kritikajn protokolojn (uzante siajn plej ŝatatajn ilojn), kaj ni povis redukti la koston de la registra sistemo, ŝparante nur la pasintmonate.

Alia ekzemplo estas sufiĉe indika pri kio ne fari. Unu el niaj klientoj por prilaborado ĉiu eventoj venantaj de la uzanto, faritaj multilinio nestrukturita eligo informoj en protokolo. Kiel vi povas supozi, tiaj protokoloj estis ege maloportunaj por legi kaj konservi.

Kriterioj por ŝtipoj

Tiaj ekzemploj kondukas al la konkludo, ke krom elekti log-kolektan sistemon, vi devas ankaŭ desegni la ŝtipojn mem! Kio estas la postuloj ĉi tie?

  • Registroj devas esti en maŝinlegebla formato (ekzemple, JSON).
  • Registroj devus esti kompaktaj kaj kun la kapablo ŝanĝi la gradon de protokolado por sencimigi eblajn problemojn. Samtempe, en produktadmedioj vi devus ruli sistemojn kun registra nivelo kiel Avertoeraro.
  • Protokoloj devas esti normaligitaj, tio estas, en logobjekto, ĉiuj linioj devas havi la saman kampospecon.

Senstrukturaj tagaloj povas konduki al problemoj kun ŝarĝado de tagaloj en stokado kaj kompleta halto en ilia prilaborado. Kiel ilustraĵo, jen ekzemplo kun eraro 400, kiun multaj certe renkontis en fluaj protokoloj:

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

La eraro signifas, ke vi sendas kampon, kies tipo estas malstabila al la indekso kun preta mapado. La plej simpla ekzemplo estas kampo en la nginx-protokolo kun variablo $upstream_status. Ĝi povas enhavi aŭ nombron aŭ ĉenon. Ekzemple:

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

La protokoloj montras, ke servilo 10.100.0.10 respondis per 404-eraro kaj la peto estis sendita al alia enhavo-stokado. Kiel rezulto, la valoro en la protokoloj fariĝis jene:

"upstream_response_time": "0.001, 0.007"

Ĉi tiu situacio estas tiel ofta, ke ĝi eĉ meritas apartan referencoj en dokumentado.

Kio pri fidindeco?

Estas tempoj, kiam ĉiuj protokoloj sen escepto estas esencaj. Kaj kun ĉi tio, la tipaj ŝtipkolektoskemoj por K8s proponitaj/diskutitaj supre havas problemojn.

Ekzemple, fluentd ne povas kolekti tagalojn de mallongdaŭraj ujoj. En unu el niaj projektoj, la datumbaza migrada ujo vivis malpli ol 4 sekundojn kaj poste estis forigita - laŭ la responda komentario:

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

Pro tio, la migra ekzekutprotokolo ne estis inkluzivita en la stokado. Politiko povas helpi en ĉi tiu kazo. before-hook-creation.

Alia ekzemplo estas Docker-protokolo-rotacio. Ni diru, ke ekzistas aplikaĵo, kiu aktive skribas al protokoloj. En normalaj kondiĉoj, ni sukcesas prilabori ĉiujn protokolojn, sed tuj kiam problemo aperas - ekzemple, kiel priskribite supre kun malĝusta formato - la prilaborado ĉesas, kaj Docker turnas la dosieron. La rezulto estas, ke komercaj kritikaj protokoloj povas esti perditaj.

Tial gravas apartigi protokolojn, enigante sendante la plej valorajn rekte en la aplikaĵon por certigi ilian sekurecon. Krome, ne estus superflue krei kelkajn "akumulilo" de ŝtipoj, kiu povas postvivi mallongan stokan nehaveblecon dum konservado de kritikaj mesaĝoj.

Fine, ni ne devas forgesi tion Gravas kontroli ajnan subsistemon ĝuste. Alie, estas facile renkonti situacion en kiu fluentd estas en stato CrashLoopBackOff kaj nenion sendas, kaj ĉi tio promesas la perdon de gravaj informoj.

trovoj

En ĉi tiu artikolo, ni ne rigardas SaaS-solvojn kiel Datadog. Multaj el la ĉi tie priskribitaj problemoj jam estis solvitaj en unu aŭ alia maniero de komercaj kompanioj specialigitaj pri kolektado de ŝtipoj, sed ne ĉiuj povas uzi SaaS pro diversaj kialoj. (la ĉefaj estas kosto kaj konformeco al 152-FZ).

Alcentrigita registrokolekto unue aspektas kiel simpla tasko, sed ĝi tute ne estas. Gravas memori tion:

  • Nur kritikaj komponantoj devas esti ensalutitaj detale, dum monitorado kaj erarkolekto povas esti agordita por aliaj sistemoj.
  • Registroj en produktado devas esti minimumaj por ne aldoni nenecesan ŝarĝon.
  • Registroj devas esti maŝinlegeblaj, normaligitaj kaj havi striktan formaton.
  • Vere kritikaj protokoloj estu senditaj en aparta fluo, kiu estu apartigita de la ĉefaj.
  • Indas konsideri ŝtipan akumulilon, kiu povas savi vin de eksplodoj de alta ŝarĝo kaj fari la ŝarĝon sur la stokado pli uniforma.

Ensalutas en Kubernetes (kaj ne nur) hodiaŭ: atendoj kaj realeco
Ĉi tiuj simplaj reguloj, se aplikitaj ĉie, permesus al la supre priskribitaj cirkvitoj funkcii - kvankam mankas al ili gravaj komponentoj (la baterio). Se vi ne aliĝas al tiaj principoj, la tasko facile kondukos vin kaj la infrastrukturon al alia tre ŝarĝita (kaj samtempe neefika) komponanto de la sistemo.

PS

Legu ankaŭ en nia blogo:

fonto: www.habr.com

Aldoni komenton