Imazhe të gatshme për prodhim për k8s

Kjo histori ka të bëjë me mënyrën se si ne përdorim kontejnerët në një mjedis prodhimi, veçanërisht Kubernetes. Artikulli i kushtohet mbledhjes së metrikave dhe shkrimeve nga kontejnerët, si dhe ndërtimit të imazheve.

Imazhe të gatshme për prodhim për k8s

Ne jemi nga kompania fintech Exness, e cila zhvillon shërbime për tregtimin online dhe produkte fintech për B2B dhe B2C. Kërkimi dhe zhvillimi ynë ka shumë ekipe të ndryshme, departamenti i zhvillimit ka 100+ punonjës.

Ne përfaqësojmë ekipin që është përgjegjës për platformën që zhvilluesit tanë të mbledhin dhe ekzekutojnë kodin. Në veçanti, ne jemi përgjegjës për mbledhjen, ruajtjen dhe raportimin e metrikave, regjistrave dhe ngjarjeve nga aplikacionet. Aktualisht operojmë rreth tre mijë kontejnerë Docker në një mjedis prodhimi, ruajmë ruajtjen e të dhënave tona të mëdha prej 50 TB dhe ofrojmë zgjidhje arkitekturore që janë ndërtuar rreth infrastrukturës sonë: Kubernetes, Rancher dhe ofrues të ndryshëm publikë të reve kompjuterike. 

Motivimi ynë

Çfarë digjet? Askush nuk mund të përgjigjet. Ku është vatra? Është e vështirë të kuptohet. Kur mori flakë? Mund ta zbuloni, por jo menjëherë. 

Imazhe të gatshme për prodhim për k8s

Pse disa kontejnerë janë në këmbë ndërsa të tjerët kanë rënë? Cili kontejner ishte fajtor? Në fund të fundit, pjesa e jashtme e kontejnerëve është e njëjtë, por brenda secilës ka Neo-në e vet.

Imazhe të gatshme për prodhim për k8s

Zhvilluesit tanë janë djem kompetentë. Ata bëjnë shërbime të mira që sjellin fitim për kompaninë. Por ka dështime kur kontejnerët me aplikacione humbasin. Një kontejner konsumon shumë CPU, një tjetër konsumon rrjetin, një i tretë konsumon operacionet I/O dhe i katërti është plotësisht i paqartë se çfarë bën me prizat. Gjithçka bie dhe anija fundoset. 

Agjentët

Për të kuptuar se çfarë po ndodh brenda, vendosëm t'i vendosnim agjentët direkt në kontejnerë.

Imazhe të gatshme për prodhim për k8s

Këta agjentë janë programe frenuese që mbajnë kontejnerët në një gjendje të tillë që të mos thyejnë njëri-tjetrin. Agjentët janë të standardizuar dhe kjo lejon një qasje të standardizuar për servisimin e kontejnerëve. 

Në rastin tonë, agjentët duhet të ofrojnë regjistrat në një format standard, të etiketuar dhe të mbyllur. Ata gjithashtu duhet të na ofrojnë metrika të standardizuara që janë të zgjerueshme nga perspektiva e aplikimit të biznesit.

Agjentët nënkuptojnë gjithashtu shërbime për funksionimin dhe mirëmbajtjen që mund të funksionojnë në sisteme të ndryshme orkestrimi që mbështesin imazhe të ndryshme (Debian, Alpine, Centos, etj.).

Së fundi, agjentët duhet të mbështesin CI/CD të thjeshtë që përfshin skedarët Docker. Përndryshe, anija do të shpërbëhet, sepse kontejnerët do të fillojnë të dorëzohen përgjatë binarëve "të shtrembër".

Procesi i ndërtimit dhe objektivi i pajisjes së imazhit

Për të mbajtur gjithçka të standardizuar dhe të menaxhueshme, duhet të ndiqet një lloj procesi standard ndërtimi. Prandaj, vendosëm të mbledhim kontejnerë sipas kontejnerëve - ky është rekursion.

Imazhe të gatshme për prodhim për k8s

Këtu kontejnerët përfaqësohen nga skica të forta. Në të njëjtën kohë, ata vendosën të vendosnin kuti shpërndarëse në to, në mënyrë që "jeta të mos duket si mjedra". Pse u bë kjo, ne do të shpjegojmë më poshtë.
 
Rezultati është një mjet ndërtimi - një kontejner specifik për versionin që i referohet versioneve specifike të shpërndarjes dhe versioneve specifike të skriptit.

Si ta përdorim? Ne kemi një Docker Hub që përmban një kontejner. Ne e pasqyrojmë atë brenda sistemit tonë për të hequr qafe varësitë e jashtme. Rezultati është një enë e shënuar me të verdhë. Ne krijojmë një shabllon për të instaluar të gjitha shpërndarjet dhe skriptet që na duhen në kontejner. Pas kësaj, ne mbledhim një imazh të gatshëm për përdorim: zhvilluesit vendosin kodin dhe disa nga varësitë e tyre të veçanta në të. 

Çfarë është e mirë për këtë qasje? 

  • Së pari, kontrolli i plotë i versionit të veglave të ndërtimit - ndërtoni kontejnerin, skriptin dhe versionet e shpërndarjes. 
  • Së dyti, ne kemi arritur standardizimin: ne krijojmë shabllone, imazh të ndërmjetëm dhe të gatshëm për përdorim në të njëjtën mënyrë. 
  • Së treti, kontejnerët na japin transportueshmëri. Sot ne përdorim Gitlab dhe nesër do të kalojmë në TeamCity ose Jenkins dhe do të jemi në gjendje të përdorim kontejnerët tanë në të njëjtën mënyrë. 
  • Së katërti, minimizimi i varësive. Nuk ishte rastësi që vendosëm komplete shpërndarjeje në kontejner, sepse kjo na lejon të shmangim shkarkimin e tyre nga Interneti çdo herë. 
  • Së pesti, shpejtësia e ndërtimit është rritur - prania e kopjeve lokale të imazheve ju lejon të shmangni humbjen e kohës në shkarkim, pasi ekziston një imazh lokal. 

Me fjalë të tjera, ne kemi arritur një proces montimi të kontrolluar dhe fleksibël. Ne përdorim të njëjtat mjete për të ndërtuar çdo kontejnerë të versionuar plotësisht. 

Si funksionon procedura jonë e ndërtimit

Imazhe të gatshme për prodhim për k8s

Asambleja niset me një komandë, procesi ekzekutohet në imazh (i theksuar me të kuqe). Zhvilluesi ka një skedar Docker (të theksuar me të verdhë), ne e japim atë, duke zëvendësuar variablat me vlera. Dhe gjatë rrugës ne shtojmë koka dhe funde - këta janë agjentët tanë. 

Header shton shpërndarje nga imazhet përkatëse. Dhe footer instalon shërbimet tona brenda, konfiguron nisjen e ngarkesës së punës, regjistrimin dhe agjentët e tjerë, zëvendëson pikën hyrëse, etj. 

Imazhe të gatshme për prodhim për k8s

Ne menduam për një kohë të gjatë nëse do të instalonim një mbikëqyrës. Në fund, vendosëm se kishim nevojë për të. Ne zgjodhëm S6. Mbikëqyrësi siguron menaxhimin e kontejnerit: ju lejon të lidheni me të nëse procesi kryesor rrëzohet dhe siguron menaxhimin manual të kontejnerit pa e rikrijuar atë. Regjistrat dhe metrikat janë procese që ekzekutohen brenda kontejnerit. Ata gjithashtu duhet të kontrollohen disi, dhe ne e bëjmë këtë me ndihmën e një mbikëqyrësi. Së fundi, S6 kujdeset për mbajtjen e shtëpisë, përpunimin e sinjalit dhe detyra të tjera.

Meqenëse ne përdorim sisteme të ndryshme orkestrimi, pas ndërtimit dhe funksionimit, kontejneri duhet të kuptojë se në çfarë mjedisi ndodhet dhe të veprojë sipas situatës. Për shembull:
Kjo na lejon të ndërtojmë një imazh dhe ta ekzekutojmë në sisteme të ndryshme orkestrimi, dhe do të lëshohet duke marrë parasysh specifikat e këtij sistemi orkestrimi.

 Imazhe të gatshme për prodhim për k8s

Për të njëjtën enë marrim pemë të ndryshme procesi në Docker dhe Kubernetes:

Imazhe të gatshme për prodhim për k8s

Ngarkesa ekzekutohet nën mbikëqyrjen e S6. Kushtojini vëmendje koleksionistit dhe ngjarjeve - këta janë agjentët tanë përgjegjës për regjistrat dhe matjet. Kubernetes nuk i ka ato, por Docker i ka. Pse? 

Nëse shikojmë specifikimin e "pod" (në tekstin e mëtejmë - Kubernetes pod), do të shohim se kontejneri i ngjarjeve është ekzekutuar në një pod, i cili ka një enë kolektori të veçantë që kryen funksionin e mbledhjes së metrikës dhe regjistrave. Ne mund të përdorim aftësitë e Kubernetes: drejtimin e kontejnerëve në një pod, në një proces të vetëm dhe/ose hapësirë ​​rrjeti. Në fakt prezantoni agjentët tuaj dhe kryeni disa funksione. Dhe nëse i njëjti kontejner lëshohet në Docker, ai do të marrë të gjitha të njëjtat aftësi si prodhimi, domethënë do të jetë në gjendje të japë regjistrat dhe metrikat, pasi agjentët do të lëshohen brenda. 

Metrikat dhe regjistrat

Dorëzimi i metrikave dhe regjistrave është një detyrë komplekse. Vendimi i saj ka disa aspekte.
Infrastruktura është krijuar për ekzekutimin e ngarkesës, dhe jo për shpërndarjen masive të trungjeve. Kjo do të thotë, 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 Docker Hub, drejtojeni atë dhe ne mund t'i dorëzojmë regjistrat". 

Aspekti i dytë është kufizimi i vëllimit të regjistrave. Nëse një rritje në vëllimin e regjistrave ndodh në disa kontejnerë (aplikacioni nxjerr një stack-trace në një lak), ngarkesa në CPU, kanalet e komunikimit dhe sistemin e përpunimit të regjistrave rritet, dhe kjo ndikon në funksionimin e hostit si një kontejnerë të tërë dhe të tjerë në host, atëherë ndonjëherë kjo çon në "rënie" të hostit. 

Aspekti i tretë është se është e nevojshme të mbështeten sa më shumë metoda të mbledhjes së metrikës jashtë kutisë. Nga leximi i skedarëve dhe sondazhi i Prometheus-endpoint deri te përdorimi i protokolleve specifike të aplikacionit.

Dhe aspekti i fundit është minimizimi i konsumit të burimeve.

Ne zgjodhëm një zgjidhje Go me burim të hapur të quajtur Telegraf. Ky është një lidhës universal që mbështet më shumë se 140 lloje kanalesh hyrëse (shtojca hyrëse) dhe 30 lloje kanalesh dalëse (shtojca dalëse). Ne e kemi finalizuar dhe tani do t'ju tregojmë se si e përdorim duke përdorur Kubernetes si shembull. 

Imazhe të gatshme për prodhim për k8s

Le të themi se një zhvillues vendos një ngarkesë pune dhe Kubernetes merr një kërkesë për të krijuar një pod. Në këtë pikë, një enë e quajtur Kolektor krijohet automatikisht për çdo pod (ne përdorim uebhook mutacioni). Koleksionisti është agjenti ynë. Në fillim, ky kontejner konfigurohet për të punuar me Prometheun dhe sistemin e mbledhjes së regjistrave.

  • Për ta bërë këtë, ai përdor shënimet e pod, dhe në varësi të përmbajtjes së tij, krijon, të themi, një pikë fundore Prometheus; 
  • Bazuar në specifikimet e pod dhe cilësimet specifike të kontejnerit, ai vendos se si të dorëzohen regjistrat.

Ne mbledhim regjistrat nëpërmjet API-së Docker: zhvilluesit duhet vetëm t'i vendosin ato në stdout ose stderr, dhe Collector do t'i zgjidhë ato. Regjistrat mblidhen në copa me njëfarë vonese për të parandaluar mbingarkimin e mundshëm të hostit. 

Metrikat mblidhen nëpër instancat e ngarkesës së punës (proceset) në kontejnerë. Çdo gjë është etiketuar: hapësira e emrave, nën, dhe kështu me radhë, dhe më pas konvertohet në formatin Prometheus - dhe bëhet e disponueshme për grumbullim (përveç regjistrave). Ne gjithashtu dërgojmë regjistra, metrikë dhe ngjarje te Kafka dhe më tej:

  • Regjistrat janë të disponueshëm në Graylog (për analizë vizuale);
  • Regjistrat, metrikat, ngjarjet dërgohen në Clickhouse për ruajtje afatgjatë.

Gjithçka funksionon saktësisht njësoj në AWS, vetëm ne zëvendësojmë Graylog me Kafka me Cloudwatch. Ne i dërgojmë shkrimet atje dhe gjithçka rezulton shumë e përshtatshme: është menjëherë e qartë se cilit grup dhe enë i përkasin. E njëjta gjë është e vërtetë për Google Stackdriver. Kjo do të thotë, skema jonë funksionon si në premisë me Kafkën ashtu edhe në re. 

Nëse nuk kemi Kubernetes me pods, skema është pak më e ndërlikuar, por funksionon në të njëjtat parime.

Imazhe të gatshme për prodhim për k8s

Të njëjtat procese ekzekutohen brenda kontejnerit, ato orkestrohen duke përdorur S6. Të gjitha të njëjtat procese po zhvillohen brenda të njëjtit enë.

Si rezultat i kësaj,

Ne kemi krijuar një zgjidhje të plotë për ndërtimin dhe lëshimin e imazheve, me opsione për mbledhjen dhe dërgimin e regjistrave dhe metrikave:

  • Ne zhvilluam një qasje të standardizuar për montimin e imazheve dhe në bazë të saj zhvilluam shabllone CI;
  • Agjentët e mbledhjes së të dhënave janë zgjerimet tona të Telegraf. Ne i testuam mirë në prodhim;
  • Ne përdorim uebhook mutacioni për të implementuar kontejnerë me agjentë në pods; 
  • Integruar në ekosistemin Kubernetes/Rancher;
  • Ne mund të ekzekutojmë të njëjtat kontejnerë në sisteme të ndryshme orkestrimi dhe të marrim rezultatin që presim;
  • Krijoi një konfigurim plotësisht dinamik të menaxhimit të kontejnerëve. 

Bashkautor: Ilya Prudnikov

Burimi: www.habr.com

Shto një koment