Kjo është një histori se si ne përdorim kontejnerët në ambientin produktiv, veçanërisht nën Kubernetes. Artikulli është dedikuar mbledhjes së metrike dhe logeve nga kontejnerët, si dhe ndërtimit të imazheve.

Ne jemi nga kompania fintech Exness, e cila zhvillon shërbime për tregtimin online dhe produkte fintech për B2B dhe B2C. Në R&D tonin ka shumë ekipe të ndryshme, me mbi 100 punonjës në departamentin e zhvillimit.
Ne paraqesim ekipin qĂ« Ă«shtĂ« pĂ«rgjegjĂ«s pĂ«r platformĂ«n pĂ«r mbledhjen dhe ekzekutimin e kodit nga zhvilluesit tanĂ«. Me konkretisht, ne jemi pĂ«rgjegjĂ«s pĂ«r mbledhjen, ruajtjen dhe ofrimin e metrikeve, logeve dhe ngjarjeve nga aplikacionet. Aktualisht operojmĂ« me pĂ«rafĂ«rsisht tri mijĂ« kontejnerĂ« Docker nĂ« ambientin produktiv, mbĂ«shtesim depo big data me kapacitet prej 50 TB dhe ofrojmĂ« zgjidhje arkitektonike qĂ« ndĂ«rtohen rreth infrastrukturĂ«s tonĂ«: Kubernetes, Rancher dhe ofrues tĂ« ndryshĂ«m tĂ« cloud-it publik.Â
Motivimi ynë
ĂfarĂ« po digjet? Askush nuk mund ta pĂ«rgjigjet. Ku Ă«shtĂ« qendra? E kuptojmĂ« me vĂ«shtirĂ«si. Kur ka filluar tĂ« digjet? Mund tĂ« zbulohet, por jo menjĂ«herĂ«.Â

Pse disa kontejnerë ndalen, ndërsa të tjerë bien? Cili kontejner e shkaktoi atë? Sepse nga jashtë, kontejnerët duken të njëjtë, por brenda secili ka Neo-n e vet.

Zhvilluesit tanĂ« janĂ« djem tĂ« aftĂ«. Ata bĂ«jnĂ« shĂ«rbime tĂ« mira qĂ« sjellin fitim pĂ«r kompaninĂ«. Por ndodhin gabime, kur kontejnerĂ«t me aplikacione shkojnĂ« nĂ« mĂ«nyrĂ« kaotike. NjĂ« kontejner konsumon shumĂ« CPU, njĂ« tjetĂ«r rrjetin, njĂ« i tretĂ« operacionet e hyrjes dhe daljes, ndĂ«rsa njĂ« i katĂ«rt gjithashtu nuk dihet se çfarĂ« bĂ«n me soketĂ«t. TĂ« gjithĂ« kĂ«ta e dĂ«rgojnĂ« broçkullĂ«n, dhe anija po fundoset.Â
Agjentët
Për të kuptuar çfarë po ndodh brenda, ne vendosëm të instalojmë agjentët direkt në kontejnerë.

KĂ«ta agjentĂ« janĂ« programe mbikĂ«qyrĂ«se, qĂ« mbajnĂ« kontejnerĂ«t nĂ« gjendje tĂ« tillĂ« qĂ« tĂ« mos shkatĂ«rrojnĂ« njĂ«ri-tjettrin. AgjentĂ«t janĂ« standardizuar, dhe kjo lejon standardizimin e qasjes pĂ«r mirĂ«mbajtjen e kontejnerĂ«ve.Â
Në rastin tonë, agjentët duhet të ofrojnë loge në një format standard, të etiketuar dhe me throttling. Po ashtu, ata duhet të na ofrojnë metrika standardizuar, të zgjerueshme nga ana e aplikacioneve biznesore.
Nën agjentët gjithashtu nënkuptohen utilitetet për operacion dhe mirëmbajtje, që janë të afta të funksionojnë në sisteme të ndryshme orkestrimi, duke mbështetur imazhe të ndryshme (Debian, Alpine, Centos etj.).
Së fundi, agjentët duhet të mbështesin një CI/CD të thjeshtë, që përfshin skedarë Docker. Në të kundërt, anija do të shembet, sepse kontejnerët do të fillojnë të dërgohen nëpër "binarë" të shtrembër.
Procesi i ndërtimit dhe struktura e imazhit të synuar
PĂ«r tĂ« pasur gjithçka tĂ« standardizuar dhe menaxhueshme, Ă«shtĂ« e nevojshme tĂ« ndiqet njĂ« proces standard ndĂ«rtimi. Prandaj, ne vendosĂ«m tĂ« ndĂ«rtojmĂ« kontejnerĂ« me kontejnerĂ« â njĂ« recursivitet i tillĂ«.

Këtu kontejnerët paraqiten si kontura të plota. Po ashtu vendosëm të futim në to distribucione, për të mos e bërë "jetën si një mollë". Pse e bëmë këtë, do ta tregojmë më poshtë.
Â
Si rezultat, kemi krijuar njĂ« mjet ndĂ«rtimi â njĂ« kontejner tĂ« versionit tĂ« caktuar, i cili lidhet me versione tĂ« caktuara distribucionesh dhe me versione tĂ« caktuara skenesh.
Si e aplikojmĂ« atĂ«? Ne kemi Docker Hub, ku ndodhet kontejneri. Ne e pasqyrojmĂ« atĂ« brenda sistemit tonĂ«, pĂ«r tĂ« eliminuar varĂ«sitĂ« e jashtme. Kemi krijuar njĂ« kontejner tĂ« markuar me ngjyrĂ« tĂ« verdhĂ«. Ne krijojmĂ« njĂ« template pĂ«r tĂ« instaluar nĂ« kontejner tĂ« gjitha distribucionet dhe skenat e nevojshme pĂ«r ne. Pas kĂ«saj, ne ndĂ«rtojmĂ« imazhin gati pĂ«r t'u pĂ«rdorur: zhvilluesit e vendosin brenda kodin dhe varĂ«sitĂ« e tyre specifike.Â
ĂfarĂ« Ă«shtĂ« e mirĂ« nĂ« kĂ«tĂ« qasje?Â
- SĂ« pari, kontrolli i plotĂ« i versioneve tĂ« mjeteve tĂ« ndĂ«rtimit â kontejneri i ndĂ«rtimit, versionet e skripteve dhe distribucioneve.Â
- SĂ« dyti, ne arritĂ«m standardizimin: krijojmĂ« modele nĂ« njĂ« mĂ«nyrĂ« tĂ« njĂ«jtĂ«, imazhe ndĂ«rmjetĂ«se dhe gati pĂ«r t'u pĂ«rdorur.Â
- SĂ« treti, kontejnerĂ«t na ofrojnĂ« portabilitet. Sot ne pĂ«rdorim Gitlab, dhe nesĂ«r do tĂ« kalojmĂ« nĂ« TeamCity ose Jenkins dhe do tĂ« jemi nĂ« gjendje tĂ« ekzekutojmĂ« po ashtu kontejnerĂ«t tanĂ«.Â
- SĂ« katĂ«rti, minimizimi i varĂ«sive. Nuk e kemi vendosur rastĂ«sisht distribucionet nĂ« kontejner, sepse kjo lejon qĂ« tĂ« mos i shkarkojmĂ« ato çdo herĂ« nga Interneti.Â
- SĂ« pesti, Ă«shtĂ« rritur shpejtĂ«sia e ndĂ«rtimit â pranimi i kopjeve lokale tĂ« imazheve na lejon tĂ« mos harxhojmĂ« kohĂ« nĂ« shkarkim, pasi e kemi njĂ« imazh lokal.Â
Me fjalĂ« tĂ« tjera, ne arritĂ«m njĂ« proces ndĂ«rtimi tĂ« kontrollueshĂ«m dhe fleksibĂ«l. Ne pĂ«rdorim mjete tĂ« njĂ«jta pĂ«r tĂ« ndĂ«rtuar çdo kontejner me versionim tĂ« plotĂ«.Â
Si funksionon procedura jonë e ndërtimit

Grumbullimi aktivizohet me njĂ« komandĂ«, procesi kryhet nĂ« imazh (i shĂ«nuar me tĂ« kuqe). Zhvilluesi ka njĂ« skedĂ« Docker (e shĂ«nuar me tĂ« verdhĂ«), ne e renditim atĂ« duke zĂ«vendĂ«suar variablat me vlera. NdĂ«rkohĂ«, shtojmĂ« header dhe footer â kĂ«to janĂ« agjentĂ«t tanĂ«.Â
Header-in e shton distribucionet nga imazhet pĂ«rkatĂ«se. NdĂ«rsa footer-i vendos brenda shĂ«rbimet tona, konfiguron nisjen e ngarkesĂ«s punuese, regjistrimin dhe agjentĂ«t e tjerĂ«, zĂ«vendĂ«son entrypoint etj.Â

Ne menduam për një kohë të gjatë nëse duhet të vendosim një supervizor. Në fund të fundit, vendosëm se na nevojitet. Zgjodhëm S6. Supervizori ofron menaxhimin e kontejnerit: lejon lidhjen me të në rast të rënies së procesit kryesor dhe ofron menaxhim manual të kontejnerit pa e ri-krijuar atë. Loget dhe metrikat janë procese që ekzekutohen brenda kontejnerit. Edhe ato duhet të kontrollohen në një farë mënyre, dhe ne e bëjmë këtë përmes supervizorit. Së fundi, S6 merr përsipër kryerjen e punëve të shtëpisë, përpunimin e sinjaleve dhe detyra të tjera.
Pasi aplikojmë sisteme të ndryshme orkestrimi, pas grumbullimit dhe aktivizimit, kontejneri duhet të kuptojë se në cilin mjedis ndodhet dhe të veprojë sipas situatës. Për shembull:
Kjo na lejon të grumbullojmë një imazh dhe ta aktivizojmë atë në sisteme të ndryshme orkestrimi, dhe ai do të aktivizohet duke marrë parasysh specifikat e këtij sistemi orkestrimi.
 
Për të njëjtin kontejner, ne marrim struktura të ndryshme procesi në Docker dhe Kubernetes:

Ngarkesa ekzekutohet nĂ«n supervizorin S6. Vini re collector dhe events â kĂ«to janĂ« agjentĂ«t tanĂ« qĂ« pĂ«rgjigjen pĂ«r logĂ«t dhe metrikat. NĂ« Kubernetes ata nuk ekzistojnĂ«, ndĂ«rsa nĂ« Docker po. Pse?Â
NĂ«se shohim specifikimin e 'pod'-it (kĂ«tu e tutje â Kubernetes pod), do tĂ« shohim se kontejneri events ekzekutohet nĂ« podin ku ndodhet njĂ« kontejner tjetĂ«r collector, qĂ« kryen funksionin e mbledhjes sĂ« metrikave dhe logĂ«ve. Ne mund tĂ« shfrytĂ«zojmĂ« mundĂ«sitĂ« e Kubernetes: aktivizimin e kontejnerĂ«ve nĂ« njĂ« pod, nĂ« njĂ« hapĂ«sirĂ« procesi dhe/ose rrjeti tĂ« njĂ«jtĂ«. NĂ« thelb, tĂ« implementojmĂ« agjentĂ«t tanĂ« dhe tĂ« realizojmĂ« disa funksione. Dhe nĂ«se ky kontejner aktivizohet nĂ« Docker, ai do tĂ« marrĂ« tĂ« njĂ«jtat mundĂ«si, domethĂ«nĂ« do tĂ« jetĂ« nĂ« gjendje tĂ« dĂ«rgojĂ« logĂ« dhe metrika, pasi agjentĂ«t do tĂ« aktivizohen brenda.Â
Metrikat dhe logët
Dërgimi i metrikave dhe logëve është një detyrë e komplikuar. Zgjidhja e saj lidhet me disa aspekte.
Infrastruktura krijohet pĂ«r tĂ« pĂ«rmbushur ngarkesĂ«n e dobishme, jo pĂ«r shpĂ«rndarjen masive tĂ« logĂ«ve. Pra, ky proces duhet tĂ« kryhet me kĂ«rkesa minimale pĂ«r burimet e kontejnerĂ«ve. Ne pĂ«rpiqemi tĂ« ndihmojmĂ« zhvilluesit tanĂ«: "Merrni njĂ« kontejner nga Docker Hub, hapeni, dhe ne do tĂ« mund tĂ« dĂ«rgojmĂ« logĂ«t."Â
Aspekti i dytĂ« â kufizimi i vĂ«llimit tĂ« logĂ«ve. NĂ«se disa kontejnerĂ« pĂ«rjetojnĂ« njĂ« shpĂ«rthim tĂ« vĂ«llimit tĂ« logĂ«ve (njĂ« aplikacion nĂ« cikĂ«l tregon stack-trace), rritet ngarkesa mbi CPU, lidhjet dhe sistemin e pĂ«rpunimit tĂ« logĂ«ve, dhe kjo ndikon nĂ« funksionimin e hostit nĂ« pĂ«rgjithĂ«si dhe tĂ« kontejnerĂ«ve tĂ« tjerĂ« nĂ« host, ndonjĂ«herĂ« duke çuar nĂ« "rĂ«nien" e hostit.Â
Aspekti i tretĂ« â Ă«shtĂ« e nevojshme tĂ« mbĂ«shteten sa mĂ« shumĂ« metodika tĂ« mbledhjes sĂ« metrikave nga kutia. Nga leximi i skedarĂ«ve dhe pyetja e pikĂ«s sĂ« fundit Prometheus deri te pĂ«rdorimi i protokolleve specifike tĂ« aplikacioneve.
Dhe aspekti i fundit â Ă«shtĂ« e nevojshme tĂ« minimizohet konsumimi i burimeve.
Ne zgjodhĂ«m njĂ« zgjidhje open-source nĂ« Go tĂ« quajtur Telegraf. Ky Ă«shtĂ« njĂ« konktor universal qĂ« mbĂ«shtet mĂ« shumĂ« se 140 lloje tĂ« kanalizimeve tĂ« hyjshĂ«m (input plugins) dhe 30 lloje tĂ« kanalizimeve tĂ« dalĂ«se (output plugins). Ne e kemi pĂ«rmirĂ«suar dhe tani do t'ju tregojmĂ« se si e pĂ«rdorim atĂ« nĂ« shembullin e Kubernetes.Â

Supozoni se zhvilluesi shpërndan ngarkesën dhe Kubernetes merr një kërkesë për të krijuar një pod. Në këtë moment për çdo pod krijohet automatikisht një kontejner i quajtur Collector (ne përdorim mutation webhook). Collector është agjenti ynë. Në fillim, ky kontejner e konfiguroni veten për të punuar me Prometheus dhe sistemin e mbledhjes së logëve.
- PĂ«r kĂ«tĂ«, ai pĂ«rdor anotimet e pod-it, dhe nĂ« varĂ«si tĂ« pĂ«rmbajtjes sĂ« saj, krijon, le tĂ« themi, njĂ« pikĂ« fundit tĂ« Prometheus;Â
- Në bazë të specifikacioneve të pod-it dhe parametrave specifikë të kontejnerëve, vendos se si të dërgojë logët.
Ne mbledhim logĂ«t pĂ«rmes Docker API: zhvilluesit mjafton t'i vendosin ato nĂ« stdout ose stderr, dhe pastaj Collector do tĂ« merret me to. LogĂ«t mblidhen nĂ« grupe me disa vonesa, pĂ«r tĂ« parandaluar mbingarkesĂ«n e mundshme tĂ« hostit.Â
Metrikat mblidhen sipas instancave tĂ« ngarkesĂ«s sĂ« punĂ«s (proceseve) nĂ« kontejnerĂ«. Gjithçka shĂ«nohet me etiketa: namespace, pod dhe kĂ«shtu me radhĂ«, dhe pastaj konvertohet nĂ« formatin Prometheus â dhe bĂ«het e disponueshme pĂ«r mbledhje (pĂ«rveç logĂ«ve). Po ashtu, logĂ«t, metrikat dhe ngjarjet ne i dĂ«rgojmĂ« nĂ« Kafka dhe mĂ« pas:
- Logët janë të disponueshme në Graylog (për analizë vizuale);
- Logët, metrikat, dhe ngjarjet dërgohen në Clickhouse për ruajtje afatgjatë.
Po ashtu punon gjithçka nĂ« AWS, vetĂ«m se ne zĂ«vendĂ«sojmĂ« Graylog me Kafka me Cloudwatch. DĂ«rgojmĂ« logĂ«t atje, dhe gjithçka bĂ«het shumĂ« e convenient: menjĂ«herĂ« kuptohet, pĂ«r cilin klaster dhe kontejner i takojnĂ«. E njĂ«jta gjĂ« vlen edhe pĂ«r Google Stackdriver. Kjo do tĂ« thotĂ« se skema jonĂ« punon si on-premise me Kafka, ashtu edhe nĂ« cloud.Â
Nëse nuk kemi Kubernetes me pod-e, skema bëhet pak më e komplikuar, por punon sipas të njëjtave principe.

Brenda kontejnerit ekzekutohen procese të njëjta, të orkestruara me S6. Të njëjtat procese janë të ngarkuara brenda një kontejneri.
NĂ« fund
Krijuam një zgjidhje të plotë për ndërtimin dhe ekzekutimin e imazheve në prodhim, me mundësi për mbledhjen dhe dërgimin e logëve dhe metrikave:
- Kemi zhvilluar një qasje të standardizuar për ndërtimin e imazheve, mbi të cilën kemi zhvilluar CI-shabllonet;
- Agjentët për mbledhjen e të dhënave janë zgjerime tona Telegraf. I kemi testuar mirë në prodhim;
- PĂ«rdorim webhook tĂ« mutation pĂ«r implementimin e kontejnerĂ«ve me agjentĂ« nĂ« pod-e;Â
- Jemi integruar në ekosistemin Kubernetes/Rancher;
- Mund të ekzekutojmë kontejnerë të njëjtë në sisteme të ndryshme orkestrimi dhe të marrim rezultatin që presim;
- Krijuam njĂ« konfigurim tĂ« plotĂ« dinamik pĂ«r menaxhimin e kontejnerĂ«ve.Â
Bashkëautor: Ilya Prudnikov
Burimi: habr.com
