Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Sot kam në plan të flas për mënyrën e shkrimit të aplikacioneve dhe cilat janë kërkesat që aplikacioni juaj të funksionojë mirë në Kubernetes. Në mënyrë që të mos ketë dhimbje koke me aplikacionin, në mënyrë që të mos keni nevojë të shpikni dhe të ndërtoni ndonjë "gërvishtje" rreth tij - dhe gjithçka funksionon ashtu siç synonte vetë Kubernetes.

Ky leksion është pjesë e "Shkolla e Natës Slurm në Kubernetes" Mund të shikoni ligjëratat e hapura teorike të Shkollës së Mbrëmjes në Youtube, të grupuara në një listë dëgjimi. Për ata që preferojnë tekstin dhe jo videon, ne kemi përgatitur këtë artikull.

Emri im është Pavel Selivanov, aktualisht jam inxhinieri kryesor i DevOps në Mail.ru Cloud Solutions, ne krijojmë retë, bëjmë kubernetet e menaxhimit dhe kështu me radhë. Detyrat e mia tani përfshijnë ndihmën në zhvillim, hapjen e këtyre reve, nxjerrjen e aplikacioneve që shkruajmë dhe zhvillimin e drejtpërdrejtë të mjeteve që ofrojmë për përdoruesit tanë.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Unë kam bërë DevOps, mendoj për tre vitet e fundit, me siguri. Por, në parim, unë kam bërë atë që bën DevOps për rreth pesë vjet tani. Para kësaj, unë isha i përfshirë kryesisht në gjëra të administratorit. Kam filluar të punoj me Kubernetes shumë kohë më parë - ndoshta kanë kaluar rreth katër vjet që kur fillova të punoja me të.

Në përgjithësi, fillova kur Kubernetes ishte versioni 1.3, ndoshta, dhe ndoshta 1.2 - kur ishte ende në fillimet e tij. Tani nuk është më në fillimet e tij - dhe është e qartë se ka një kërkesë të madhe në treg për inxhinierë që dëshirojnë të jenë në gjendje të bëjnë Kubernetes. Dhe kompanitë kanë një kërkesë shumë të madhe për njerëz të tillë. Prandaj, në fakt, u shfaq kjo leksion.

Nëse flasim sipas planit të asaj që do të flas, duket kështu, në kllapa shkruhet (TL;DR) - “shumë e gjatë; mos lexo". Prezantimi im sot do të përbëhet nga lista të pafundme.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Në fakt, unë vetë nuk më pëlqejnë prezantime të tilla kur bëhen, por kjo është një temë e tillë që kur po përgatisja këtë prezantim, thjesht nuk e kuptova se si ta organizoja ndryshe këtë informacion.

Sepse, në përgjithësi, ky informacion është "ctrl+c, ctrl+v", nga, ndër të tjera, nga Wiki ynë në seksionin DevOps, ku ne kemi kërkesa të shkruara për zhvilluesit: "djema, në mënyrë që ta nisim aplikacionin tuaj në Kubernetes, duhet të jetë kështu."

Kjo është arsyeja pse prezantimi doli të ishte një listë kaq e madhe. Na vjen keq. Do të përpiqem të tregoj sa më shumë që të mos jetë e mërzitshme nëse është e mundur.

Çfarë do të shohim tani:

  • këto janë, së pari, regjistrat (regjistrat e aplikacioneve?), çfarë të bëni me ta në Kubernetes, çfarë të bëni me ta, çfarë duhet të jenë;
  • çfarë të bëni me konfigurimet në Kubernetes, cilat janë mënyrat më të mira dhe më të këqija për të konfiguruar një aplikacion për Kubernetes;
  • Le të flasim se cilat janë kontrollet e aksesueshmërisë në përgjithësi, si duhet të duken;
  • le të flasim për atë që është një mbyllje e këndshme;
  • le të flasim përsëri për burimet;
  • Le të prekim edhe një herë temën e ruajtjes së të dhënave;
  • dhe në fund do t'ju tregoj se cili është termi ky aplikacion misterioz në renë kompjuterike. Cloudnativeness, si mbiemër i këtij termi.

Regjistrat

Unë sugjeroj të filloni me regjistrat - ku duhet të futen këto regjistra në Kubernetes. Tani ju keni nisur një aplikacion në Kubernetes. Sipas klasikëve, më parë aplikacionet gjithmonë shkruanin regjistra diku në një skedar. Aplikacionet e këqija shkruan regjistra në një skedar në drejtorinë kryesore të zhvilluesit që nisi aplikacionin. Aplikacionet e mira shkruan regjistra në një skedar diku brenda /var/log.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Prandaj, më tej, administratorët e mirë kishin disa gjëra të konfiguruara në infrastrukturat e tyre që këto regjistra mund të rrotulloheshin - i njëjti rsyslog, i cili shikon këto regjistra dhe kur u ndodh diçka, ka shumë prej tyre, krijon kopje rezervë, vendos regjistrat atje. , fshin skedarët e vjetër, më shumë se një javë, gjashtë muaj e disa të tjera. Teorikisht, duhet të kemi dispozita që thjesht për shkak se aplikacioni shkruan logs, hapësira në serverët e prodhimit (serverët luftarakë?) të mos mbarojë. Dhe, në përputhje me rrethanat, i gjithë prodhimi nuk u ndal për shkak të trungjeve.

Kur kalojmë në botën e Kubernetes dhe drejtojmë të njëjtën gjë atje, gjëja e parë që mund t'i kushtoni vëmendje është fakti që njerëzit, siç shkruan regjistrat në një skedar, vazhdojnë t'i shkruajnë ato.

Rezulton se nëse flasim për Kubernetes, vendi i duhur për të shkruar regjistrat diku nga një kontejner docker është thjesht t'i shkruani ato nga aplikacioni në të ashtuquajturin Stdout/Stderr, domethënë rrjedhat standarde të daljes së sistemit operativ, prodhimi standard i gabimit. Kjo është mënyra më e saktë, më e thjeshtë dhe më logjike për të vendosur regjistrat në parim në Docker dhe konkretisht në Kubernetis. Sepse nëse aplikacioni juaj shkruan regjistra në Stdout/Stderr, atëherë i takon Docker dhe shtesës Kubernetes të vendosin se çfarë të bëjnë me këto regjistra. Docker si parazgjedhje do të ndërtojë skedarët e tij të veçantë në formatin JSON.

Këtu lind pyetja, çfarë do të bëni më pas me këto shkrime? Mënyra më e lehtë është e qartë, ne kemi aftësinë për të bërë kubectl logs dhe shikoni këto shkrime të këtyre "pods". Por, me siguri, ky nuk është një opsion shumë i mirë - diçka tjetër duhet bërë me shkrimet.

Tani për tani, le të flasim në të njëjtën kohë, pasi kemi prekur temën e shkrimet, për një gjë të tillë si shkrimet duhet të duken. Kjo do të thotë, kjo nuk vlen drejtpërdrejt për Kubernetes, por kur fillojmë të mendojmë se çfarë të bëjmë me shkrimet, do të ishte mirë të mendonim edhe për këtë.

Ne kemi nevojë për një lloj mjeti, në një mënyrë miqësore, që do t'i marrë këto regjistra që dokeri ynë i vendos në skedarët e tij dhe do t'i dërgojë diku. Në përgjithësi, ne zakonisht lëshojmë një lloj agjenti brenda Kubernetes në formën e një DaemonSet - një koleksionist regjistrash, i cili thjesht tregohet se ku ndodhen regjistrat që mbledh Docker. Dhe ky agjent grumbullues thjesht i merr ato, ndoshta edhe i analizon disi gjatë rrugës, ndoshta i pasuron me disa meta-informacione shtesë dhe, në fund të fundit, i dërgon për ruajtje diku. Ndryshimet janë tashmë të mundshme atje. Më i zakonshmi është ndoshta Elasticsearch, ku mund të ruani shkrimet dhe mund t'i merrni me lehtësi prej andej. Më pas, duke përdorur një kërkesë, duke përdorur Kibana, për shembull, ndërtoni grafikë në bazë të tyre, ndërtoni sinjalizime bazuar në to, etj.

Ideja më e rëndësishme, dua ta përsëris përsëri, është se brenda Docker, veçanërisht brenda Kubernetes, ruajtja e regjistrave tuaj në një skedar është një ide shumë e keqe.

Sepse së pari, është e vështirë të futësh shkrimet brenda kontejnerit në një skedar. Së pari duhet të futeni në kontejner, të ekzekutoni atje dhe më pas të shikoni regjistrat. Pika tjetër është se nëse keni regjistra në një skedar, atëherë kontejnerët zakonisht kanë një mjedis minimalist dhe nuk ka shërbime që zakonisht nevojiten për punë normale me shkrime. Varrosini, shikoni, hapini në një redaktues teksti. Momenti tjetër është kur kemi regjistrat në një skedar brenda një kontejneri, nëse ky kontejner fshihet, e kuptoni, shkrimet do të vdesin së bashku me të. Prandaj, çdo rinisje e kontejnerit do të thotë se nuk ka më regjistra. Përsëri, opsion i keq.

Dhe pika e fundit është se brenda kontejnerëve zakonisht keni aplikacionin tuaj dhe kaq - zakonisht është i vetmi proces që funksionon. Nuk flitet fare për ndonjë proces që do të rrotullonte skedarët me regjistrat tuaj. Sapo regjistrat fillojnë të shkruhen në një skedar, kjo do të thotë që, më falni, do të fillojmë të humbasim serverin e prodhimit. Sepse, së pari, ato janë të vështira për t'u gjetur, askush nuk i gjurmon, plus askush nuk i kontrollon - në përputhje me rrethanat, skedari rritet pafund derisa hapësira në server thjesht të mbarojë. Prandaj, e them përsëri se regjistrimi në Docker, veçanërisht në Kubernetes, në një skedar është një ide e keqe.

Pika tjetër, këtu dua të flas përsëri për këtë - meqenëse po prekim temën e regjistrave, do të ishte mirë të flasim se si duhet të duken regjistrat në mënyrë që të jetë e përshtatshme të punohet me ta. Siç thashë, tema nuk lidhet drejtpërdrejt me Kubernetes, por lidhet shumë mirë me temën e DevOps. Në temën e kulturës së zhvillimit dhe miqësisë midis këtyre dy departamenteve të ndryshme - Dev dhe Ops, në mënyrë që të gjithë të jenë të rehatshëm.

Kjo do të thotë që në mënyrë ideale, sot, regjistrat duhet të shkruhen në formatin JSON. Nëse keni ndonjë aplikacion tuajin të pakuptueshëm, i cili shkruan regjistrat në formate të pakuptueshme sepse futni një lloj printimi ose diçka të tillë, atëherë është koha të kërkoni në google një lloj kuadri, një lloj mbështjellësi që ju lejon të zbatoni regjistrimin normal; aktivizoni parametrat e regjistrimit në JSON atje, sepse JSON është një format i thjeshtë, analizimi i tij është i thjeshtë.

Nëse JSON juaj nuk funksionon sipas disa kritereve, askush nuk e di se çfarë, atëherë të paktën shkruani regjistrat në një format që mund të analizohet. Këtu, përkundrazi, ia vlen të mendoni për faktin se, për shembull, nëse jeni duke drejtuar një grup kontejnerësh ose thjesht përpunoni me nginx, dhe secila ka cilësimet e veta të regjistrimit, atëherë me siguri duket se do të jetë shumë e papërshtatshme për ju të analizojini ato. Sepse për çdo shembull të ri nginx ju duhet të shkruani analizuesin tuaj, sepse ata shkruajnë regjistrat ndryshe. Përsëri, ndoshta ia vlente të mendohej për t'u siguruar që të gjitha këto instanca nginx të kishin të njëjtin konfigurim të prerjeve dhe t'i shkruanin të gjitha regjistrat e tyre absolutisht uniformisht. E njëjta gjë vlen për absolutisht të gjitha aplikacionet.

Në fund, dua t'i shtoj edhe benzinë ​​zjarrit se, në mënyrë ideale, regjistrat e formatit me shumë rreshta duhet të shmangen. Këtu është gjëja, nëse keni punuar ndonjëherë me mbledhës të trungjeve, atëherë me shumë mundësi keni parë atë që ju premtojnë, se ata mund të punojnë me shkrime me shumë rreshta, të dinë t'i mbledhin ato, etj. Në fakt, për mendimin tim, asnjë koleksionist i vetëm sot nuk mund të mbledhë shkrimet me shumë rreshta normalisht, plotësisht dhe pa gabime. Në mënyrë njerëzore, në mënyrë që të jetë e përshtatshme dhe pa gabime.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Por gjurmimi i stivës është gjithmonë regjistra me shumë rreshta dhe si t'i shmangni ato. Pyetja këtu është se një regjistër është një regjistrim i një ngjarjeje, dhe stactrace nuk është në të vërtetë një regjistër. Nëse mbledhim regjistrat dhe i vendosim diku në Elasticsearch dhe më pas nxjerrim grafikë prej tyre, ndërtojmë disa raporte të aktivitetit të përdoruesve në faqen tuaj, atëherë kur të merrni një gjurmë stack, kjo do të thotë se diçka e papritur po ndodh. një situatë e patrajtuar në aplikacionin tuaj. Dhe ka kuptim që të ngarkoni automatikisht një gjurmë stack diku në një sistem që mund t'i gjurmojë ato.

Ky është softuer (i njëjti Sentry) që është krijuar posaçërisht për të punuar me stack trace. Mund të krijojë menjëherë detyra të automatizuara, t'i caktojë ato dikujt, të sinjalizojë kur ndodhin gjurmët e stakteve, t'i grupojë këto gjurmë statike sipas një lloji, e kështu me radhë. Në parim, nuk ka shumë kuptim të flasim për stactraces kur flasim për trungje, sepse këto janë, në fund të fundit, gjëra të ndryshme me qëllime të ndryshme.

konfiguracion

Më tej flasim për konfigurimin në Kubernetes: çfarë të bëjmë me të dhe si duhet të konfigurohen aplikacionet brenda Kubernetes. Në përgjithësi, unë zakonisht them që Docker nuk ka të bëjë me kontejnerët. Të gjithë e dinë që Docker ka të bëjë me kontejnerët, madje edhe ata që nuk kanë punuar shumë me Docker. E përsëris, Docker nuk ka të bëjë me kontejnerët.

Docker, për mendimin tim, ka të bëjë me standardet. Dhe ka standarde praktikisht për gjithçka: standarde për ndërtimin e aplikacionit tuaj, standarde për instalimin e aplikacionit tuaj.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Dhe kjo gjë - e kemi përdorur më parë, sapo u bë veçanërisht e popullarizuar me ardhjen e kontejnerëve - kjo gjë quhet variablat ENV (mjedisi), domethënë variablat e mjedisit që janë në sistemin tuaj operativ. Kjo është përgjithësisht një mënyrë ideale për të konfiguruar aplikacionin tuaj, sepse nëse keni aplikacione në JAVA, Python, Go, Perl, Zoti na ruajt dhe ata të gjithë mund të lexojnë hostin e bazës së të dhënave, përdoruesin e bazës së të dhënave, variablat e fjalëkalimit të bazës së të dhënave, atëherë është ideale. Ju keni aplikacione në katër gjuhë të ndryshme të konfiguruara në planin e bazës së të dhënave në të njëjtën mënyrë. Nuk ka më konfigurime të ndryshme.

Gjithçka mund të konfigurohet duke përdorur variablat ENV. Kur flasim për Kubernetes, ekziston një mënyrë e shkëlqyeshme për të deklaruar variablat ENV pikërisht brenda Deployment. Prandaj, nëse po flasim për të dhëna sekrete, atëherë mund t'i shtyjmë menjëherë të dhënat sekrete nga variablat ENV (fjalëkalimet në bazat e të dhënave, etj.) në një sekret, të krijojmë një grup sekret dhe të tregojmë në përshkrimin ENV në Deployment që nuk po e deklarojmë drejtpërdrejt vlera e kësaj variabli dhe vlera e kësaj ndryshoreje fjalëkalimi të bazës së të dhënave do të lexohen nga sekreti. Kjo është sjellje standarde e Kubernetes. Dhe ky është opsioni më ideal për të konfiguruar aplikacionet tuaja. Vetëm në nivelin e kodit, përsëri kjo vlen për zhvilluesit. Nëse jeni DevOps, mund të pyesni: “Djema, ju lutemi mësoni aplikacionin tuaj të lexojë variablat e mjedisit. Dhe ne të gjithë do të jemi të lumtur.”

Nëse të gjithë në kompani lexojnë variabla të mjedisit me të njëjtin emër, atëherë kjo është e mrekullueshme. Që të mos ndodhë që disa presin bazën e të dhënave postgres, të tjerët presin emrin e bazës së të dhënave, të tjerët presin diçka tjetër, të tjerët presin një dbn të një lloji, në mënyrë që, në përputhje me rrethanat, të ketë uniformitet.

Problemi vjen kur keni kaq shumë variabla mjedisore sa hapni Deployment - dhe ka pesëqind rreshta të variablave të mjedisit. Në këtë rast, ju thjesht i keni tejkaluar variablat e mjedisit - dhe nuk keni më nevojë të torturoni veten. Në këtë rast, do të kishte kuptim të filloni të përdorni konfigurime. Kjo do të thotë, stërvitni aplikacionin tuaj për të përdorur konfigurimet.

Pyetja e vetme është se konfigurimet nuk janë ato që mendoni. Config.pi nuk është një konfigurim që është i përshtatshëm për t'u përdorur. Ose ndonjë konfigurim në formatin tuaj, alternativisht i talentuar - kjo nuk është gjithashtu konfigurimi që dua të them.

Ajo për të cilën po flas është konfigurimi në formate të pranueshme, domethënë, standardi më i njohur është standardi .yaml. Është e qartë se si lexohet, është e lexueshme nga njeriu, është e qartë se si lexohet nga aplikacioni.

Prandaj, përveç YAML, ju gjithashtu mund të përdorni, për shembull, JSON, analizimi është po aq i përshtatshëm sa YAML për sa i përket leximit të konfigurimit të aplikacionit nga atje. Është dukshëm më e papërshtatshme për njerëzit të lexojnë. Mund ta provoni formatin, a la ini. Është mjaft i përshtatshëm për t'u lexuar, nga pikëpamja njerëzore, por mund të jetë e papërshtatshme për ta përpunuar atë automatikisht, në kuptimin që nëse ndonjëherë dëshironi të gjeneroni konfigurimet tuaja, formati ini mund të jetë tashmë i papërshtatshëm për t'u gjeneruar.

Por në çdo rast, çfarëdo formati që zgjidhni, çështja është se nga këndvështrimi i Kubernetes është shumë i përshtatshëm. Ju mund të vendosni të gjithë konfigurimin tuaj brenda Kubernetes, në ConfigMap. Dhe pastaj merrni këtë konfigurim dhe kërkoni që ajo të montohet brenda pod tuaj në një direktori specifike, ku aplikacioni juaj do të lexojë konfigurimin nga kjo konfigurim si të ishte thjesht një skedar. Kjo, në fakt, është ajo që është mirë të bëni kur keni shumë opsione konfigurimi në aplikacionin tuaj. Ose është thjesht një lloj strukture komplekse, ka fole.

Nëse keni një konfigurim, atëherë mund ta mësoni shumë mirë aplikacionin tuaj, për shembull, të gjurmojë automatikisht ndryshimet në skedarin ku është montuar harta e konfigurimit dhe gjithashtu të rifreskojë automatikisht aplikacionin tuaj kur ndryshojnë konfigurimet. Në përgjithësi, ky do të ishte një opsion ideal.

Përsëri, unë kam folur tashmë për këtë - informacioni sekret nuk është në konfigurim, informacioni sekret nuk është në ndryshore, informacioni sekret nuk është në sekrete. Nga atje, lidhni këtë informacion sekret me diplomacinë. Zakonisht ne ruajmë të gjitha përshkrimet e objekteve Kubernetes, vendosjet, konfigurimet, shërbimet në git. Prandaj, vendosja e fjalëkalimit në bazën e të dhënave në git, edhe nëse është git-i juaj, të cilin e keni brenda në kompani, është një ide e keqe. Sepse, në minimum, git kujton gjithçka dhe thjesht heqja e fjalëkalimeve nga atje nuk është aq e lehtë.

Kontroll shëndetësor

Pika tjetër është kjo gjë që quhet kontroll shëndetësor. Në përgjithësi, një kontroll shëndetësor thjesht kontrollon nëse aplikacioni juaj po funksionon. Në të njëjtën kohë, ne po flasim më shpesh për aplikacione të caktuara në internet, për të cilat, në përputhje me rrethanat, nga pikëpamja e kontrollit shëndetësor (është më mirë të mos përkthehet këtu dhe më tej) kjo do të jetë një URL e veçantë, të cilën ata e përpunojnë si një standard, ata zakonisht e bëjnë /health.

Kur hyni në këtë URL, në përputhje me rrethanat, aplikacioni ynë thotë ose "po, në rregull, gjithçka është në rregull me mua, 200" ose "jo, gjithçka nuk është në rregull me mua, rreth 500". Prandaj, nëse aplikacioni ynë nuk është http, jo një aplikacion në internet, tani po flasim për një lloj demon, ne mund të kuptojmë se si të bëjmë kontrolle shëndetësore. Kjo do të thotë, nuk është e nevojshme, nëse aplikacioni nuk është http, atëherë gjithçka funksionon pa një kontroll shëndetësor dhe kjo nuk mund të bëhet në asnjë mënyrë. Ju mund të përditësoni periodikisht disa informacione në skedar, mund të krijoni një komandë të veçantë për demonin tuaj, si p.sh. daemon status, i cili do të thotë "po, gjithçka është në rregull, demon po funksionon, është i gjallë."

Për çfarë është? Gjëja e parë dhe më e dukshme është ndoshta pse nevojitet një kontroll shëndetësor - për të kuptuar që aplikacioni po funksionon. Dua të them, është thjesht marrëzi, kur është gati tani, duket sikur po funksionon, kështu që mund të jeni i sigurt se po funksionon. Dhe rezulton se aplikacioni po funksionon, kontejneri po funksionon, shembulli po funksionon, gjithçka është në rregull - dhe më pas përdoruesit tashmë kanë prerë të gjithë numrat e telefonit nga mbështetja teknike dhe thonë "çfarë je..., ti ra në gjumë, asgjë nuk po funksionon.”

Një kontroll shëndetësor është vetëm një mënyrë e tillë për të parë nga këndvështrimi i përdoruesit se ai funksionon. Një nga metodat. Le ta themi në këtë mënyrë. Nga këndvështrimi i Kubernetes, kjo është gjithashtu një mënyrë për të kuptuar se kur fillon aplikacioni, sepse kuptojmë se ka një ndryshim midis kohës kur kontejneri u lançua, u krijua dhe filloi dhe kur aplikacioni u lançua drejtpërdrejt në këtë kontejner. Sepse nëse marrim një aplikacion mesatar java dhe përpiqemi ta lançojmë në dok, atëherë për dyzet sekonda, apo edhe një minutë, apo edhe dhjetë, ai mund të fillojë mirë. Në këtë rast, të paktën mund të trokitni në portet e tij, ai nuk do të përgjigjet atje, domethënë nuk është ende gati për të marrë trafik.

Përsëri, me ndihmën e një kontrolli shëndetësor dhe me ndihmën e faktit që po kthehemi këtu, ne mund të kuptojmë në Kubernetes që jo vetëm një enë është ngritur në aplikacion, por vetë aplikacioni ka filluar, ai tashmë i përgjigjet kontroll shëndetësor, që do të thotë se mund të dërgojmë trafik atje.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Ajo për të cilën po flas tani quhen teste gatishmërie/jetesë brenda Kubernetes; në përputhje me rrethanat, testet tona të gatishmërisë janë përgjegjëse për disponueshmërinë e aplikacionit në balancim. Kjo do të thotë, nëse testet e gatishmërisë kryhen në aplikacion, atëherë gjithçka është në rregull, trafiku i klientit po shkon në aplikacion. Nëse testet e gatishmërisë nuk kryhen, atëherë aplikacioni thjesht nuk merr pjesë, ky shembull i veçantë nuk merr pjesë në balancim, ai hiqet nga balancimi, trafiku i klientit nuk rrjedh. Prandaj, testet e Liveness brenda Kubernetes janë të nevojshme në mënyrë që nëse aplikacioni ngec, ai mund të riniset. Nëse testi i gjallërisë nuk funksionon për një aplikacion që është deklaruar në Kubernetes, atëherë aplikacioni jo vetëm që hiqet nga balancimi, por riniset.

Dhe këtu është një pikë e rëndësishme që dua të përmend: nga pikëpamja praktike, testi i gatishmërisë zakonisht përdoret më shpesh dhe nevojitet më shpesh sesa testi i gjallërisë. Kjo do të thotë, thjesht deklarimi i pamenduar i testeve të gatishmërisë dhe gjallërisë, sepse Kubernetes mund ta bëjë këtë, dhe le të përdorim gjithçka që mund të bëjë, nuk është një ide shumë e mirë. Unë do të shpjegoj pse. Sepse pika numër dy në testim është se do të ishte një ide e mirë të kontrolloni shërbimin themelor në kontrollet tuaja shëndetësore. Kjo do të thotë që nëse keni një aplikacion në internet që jep disa informacione, të cilat nga ana tjetër, natyrisht, duhet t'i marrë nga diku. Në një bazë të dhënash, për shembull. Epo, ai ruan informacionin që vjen në këtë API REST në të njëjtën bazë të dhënash. Pastaj, në përputhje me rrethanat, nëse kontrolli juaj shëndetësor përgjigjet thjesht si slashhealth i kontaktuar, aplikacioni thotë "200, në rregull, gjithçka është në rregull" dhe në të njëjtën kohë baza e të dhënave e aplikacionit tuaj është e paarritshme dhe aplikacioni i kontrollit shëndetësor thotë "200, në rregull, gjithçka është në rregull ” - Ky është një kontroll i keq shëndetësor. Kjo nuk është se si duhet të funksionojë.

Kjo është, aplikacioni juaj, kur i vjen një kërkesë /health, ai nuk përgjigjet vetëm, "200, ok", ai së pari shkon, për shembull, në bazën e të dhënave, përpiqet të lidhet me të, bën diçka shumë themelore atje, si për shembull, zgjidhni një, thjesht kontrollon nëse ka një lidhje në bazën e të dhënave dhe ju mund të kërkoni bazën e të dhënave. Nëse e gjithë kjo ishte e suksesshme, atëherë përgjigja është "200, ok." Nëse nuk është i suksesshëm, thotë se ka një gabim, baza e të dhënave nuk është e disponueshme.

Prandaj, në lidhje me këtë, unë përsëri i kthehem testeve të Gatishmërisë/Gjallërisë - pse me shumë mundësi keni nevojë për një test gatishmërie, por testi i gjallërisë është në pyetje. Sepse nëse i përshkruani kontrollet shëndetësore saktësisht siç thashë, atëherë do të rezultojë se nuk disponohet në pjesën e shembullitв или со всех instancenë një bazë të dhënash, për shembull. Kur deklaruat një test gatishmërie, kontrollet tona shëndetësore filluan të dështojnë, dhe rrjedhimisht të gjitha aplikacionet nga të cilat baza e të dhënave nuk është e aksesueshme, ato thjesht fiken nga balancimi dhe në fakt "varen" thjesht në një gjendje të neglizhuar dhe presin që bazat e të dhënave të tyre të puna.

Nëse kemi deklaruar një test të gjallërisë, atëherë imagjinoni, baza jonë e të dhënave është prishur dhe në Kubernetes tuaj gjysma e gjithçkaje fillon të rifillojë sepse testi i gjallërisë dështon. Kjo do të thotë që ju duhet të rinisni. Kjo nuk është aspak ajo që dëshironi, madje kam pasur përvojë personale në praktikë. Ne kishim një aplikacion chat që ishte shkruar në JS dhe futur në një bazë të dhënash Mongo. Dhe problemi ishte se ishte në fillim të punës sime me Kubernetes, ne përshkruam gatishmërinë, gjallërinë e testeve në parimin që Kubernetes mund ta bëjë atë, kështu që ne do ta përdorim atë. Prandaj, në një moment Mongo u bë pak "i shurdhër" dhe mostra filloi të dështojë. Prandaj, sipas testit të shiut, bishtajat filluan të "vrasin".

Siç e kuptoni, kur ata "vriten", kjo është një bisedë, domethënë ka shumë lidhje nga klientët që varen në të. Ata gjithashtu "vriten" - jo, jo klientë, vetëm lidhje - jo të gjitha në të njëjtën kohë, dhe për faktin se nuk vriten në të njëjtën kohë, disa më herët, disa më vonë, nuk fillojnë në të njëjtën kohë. koha. Plus standarde të rastësishme, ne nuk mund të parashikojmë me saktësi milisekonda kohën e fillimit të aplikacionit çdo herë, kështu që ata e bëjnë atë një nga një. Ngrihet një infospot, i shtohet balancimit, aty vijnë të gjithë klientët, nuk e përballon dot një ngarkesë të tillë, sepse është vetëm dhe, përafërsisht, punojnë një duzinë dhe bie. Ngrihet tjetri, e gjithë ngarkesa është mbi të, edhe ai bie. Epo, këto ujëvarë thjesht vazhdojnë të kaskadojnë. Në fund, si u zgjidh kjo - thjesht duhej të ndalonim rreptësisht trafikun e përdoruesve në këtë aplikacion, t'i linim të gjitha rastet të ngriheshin dhe më pas të fillonim të gjithë trafikun e përdoruesve menjëherë, në mënyrë që të ishte shpërndarë tashmë në të dhjetë instancat.

Nëse nuk do të ishte shpallur ky test i gjallërisë, i cili do ta detyronte të gjithë të rifillonte, aplikacioni do ta kishte trajtuar mirë. Por gjithçka që nga balancimi është i çaktivizuar për ne, sepse bazat e të dhënave janë të paarritshme dhe të gjithë përdoruesit kanë "ranë". Më pas, kur kjo bazë të dhënash bëhet e disponueshme, gjithçka përfshihet në balancim, por aplikacionet nuk kanë nevojë të rifillojnë dhe nuk ka nevojë të humbni kohë dhe burime për këtë. Ata janë të gjithë tashmë këtu, ata janë gati për trafik, kështu që trafiku sapo hapet, gjithçka është në rregull - aplikacioni është në vend, gjithçka vazhdon të funksionojë.

Prandaj, testet e gatishmërisë dhe të gjallërisë janë të ndryshme, madje për më tepër, teorikisht mund të bëni kontrolle të ndryshme shëndetësore, një lloj rreze, një lloj liv p.sh. dhe të kontrolloni gjëra të ndryshme. Gjatë testeve të gatishmërisë, kontrolloni bazën tuaj. Dhe në një test të gjallërisë, për shembull, ju nuk kontrolloni nga pikëpamja që testi i gjallërisë është përgjithësisht vetëm një aplikacion që përgjigjet, nëse është në gjendje të përgjigjet fare.

Sepse testi i gjallërisë, në përgjithësi, është kur jemi "të mbërthyer". Ka filluar një qark i pafund ose diçka tjetër - dhe nuk përpunohen më kërkesa. Prandaj, ka kuptim t'i veçojmë ato - dhe të zbatojmë logjikë të ndryshme në to.

Në lidhje me atë që duhet të përgjigjeni kur bëni një test, kur bëni kontrolle shëndetësore. Është thjesht një dhimbje. Ata që e njohin këtë ndoshta do të qeshin - por seriozisht, unë kam parë shërbime në jetën time që përgjigjen "200" në XNUMX% të rasteve. Domethënë kush është i suksesshëm. Por në të njëjtën kohë në trupin e përgjigjes ata shkruajnë "ashtu dhe një gabim i tillë".

Kjo do të thotë, statusi i përgjigjes ju vjen - gjithçka është e suksesshme. Por në të njëjtën kohë, ju duhet të analizoni trupin, sepse trupi thotë "më falni, kërkesa përfundoi me një gabim" dhe ky është thjesht realitet. E pashë këtë në jetën reale.

Dhe në mënyrë që disa njerëz të mos e shohin atë qesharake, dhe të tjerëve ta kenë shumë të dhimbshme, ia vlen t'i përmbahemi një rregulli të thjeshtë. Në kontrollet shëndetësore, dhe në parim kur punoni me aplikacione në internet.

Nëse gjithçka shkoi mirë, atëherë përgjigjuni me përgjigjen e dyqindtë. Në parim, çdo përgjigje e dyqindëshit do t'ju përshtatet. Nëse lexoni shumë mirë "ragsy" dhe e dini se disa statuse përgjigjesh janë të ndryshme nga të tjerat, përgjigjuni me ato të përshtatshmet: 204, 5, 10, 15, çfarëdo qoftë. Nëse nuk është shumë mirë, atëherë vetëm "dy zero zero". Nëse gjithçka shkon keq dhe kontrolli shëndetësor nuk përgjigjet, atëherë përgjigjuni me çdo të pesëqindtën. Përsëri, nëse kuptoni se si të përgjigjeni, si ndryshojnë statuset e ndryshme të përgjigjeve nga njëri-tjetri. Nëse nuk e kuptoni, atëherë 502 është opsioni juaj për t'iu përgjigjur kontrolleve shëndetësore nëse diçka shkon keq.

Kjo është një pikë tjetër, dua të kthehem pak në lidhje me kontrollin e shërbimeve themelore. Nëse filloni, për shembull, të kontrolloni të gjitha shërbimet themelore që qëndrojnë pas aplikacionit tuaj - gjithçka në përgjithësi. Ajo që marrim nga pikëpamja e arkitekturës së mikroshërbimeve, ne kemi një koncept të tillë si "bashkim i ulët" - domethënë, kur shërbimet tuaja varen minimalisht nga njëri-tjetri. Nëse njëri prej tyre dështon, të gjithë të tjerët pa këtë funksionalitet thjesht do të vazhdojnë të punojnë. Disa nga funksionet thjesht nuk funksionojnë. Prandaj, nëse i lidhni të gjitha kontrollet shëndetësore me njëri-tjetrin, atëherë do të përfundoni me një gjë që bie në infrastrukturë, dhe për shkak se ajo ra, të gjitha kontrollet shëndetësore të të gjitha shërbimeve gjithashtu fillojnë të dështojnë - dhe ka më shumë infrastrukturë në përgjithësi për e gjithë arkitektura e mikroshërbimit Nr. Gjithçka u errësua atje.

Prandaj, dua ta përsëris edhe një herë se duhet të kontrolloni shërbimet themelore, ato pa të cilat aplikacioni juaj në njëqind për qind të rasteve nuk mund të bëjë punën e tij. Kjo do të thotë, është logjike që nëse keni një API REST përmes të cilit përdoruesi ruan në bazën e të dhënave ose merr nga baza e të dhënave, atëherë në mungesë të një baze të dhënash, nuk mund të garantoni punën me përdoruesit tuaj.

Por nëse përdoruesit tuaj, kur i hiqni nga baza e të dhënave, pasurohen më tej me disa meta të dhëna të tjera, nga një backend tjetër, të cilat i futni përpara se të dërgoni një përgjigje në frontend - dhe ky backend nuk është i disponueshëm, kjo do të thotë që ju jepni përgjigje pa asnjë pjesë të meta të dhënave.

Më tej, ne kemi gjithashtu një nga çështjet e dhimbshme kur nisim aplikacionet.

Në fakt, kjo nuk vlen vetëm për Kubernetes në përgjithësi; ndodhi që kultura e një lloj zhvillimi masiv dhe DevOps në veçanti filloi të përhapet në të njëjtën kohë me Kubernetes. Prandaj, në përgjithësi, rezulton se ju duhet të mbyllni me hijeshi aplikacionin tuaj pa Kubernetes. Edhe para Kubernetes, njerëzit e bënin këtë, por me ardhjen e Kubernetes, ne filluam të flasim për të në masë.

Mbyllje e këndshme

Në përgjithësi, çfarë është Graceful Shutdown dhe pse është i nevojshëm? Kjo ka të bëjë kur aplikacioni juaj rrëzohet për ndonjë arsye, duhet ta bëni app stop - ose ju merrni, për shembull, një sinjal nga sistemi operativ, aplikacioni juaj duhet ta kuptojë atë dhe të bëjë diçka për të. Skenari më i keq, natyrisht, është kur aplikacioni juaj merr një SIGTERM dhe është si "SIGTERM, le të qëndrojmë, të punojmë, të mos bëjmë asgjë". Ky është një opsion krejtësisht i keq.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Një opsion pothuajse po aq i keq është kur aplikacioni juaj merr një SIGTERM dhe është si "ata thanë segterm, kjo do të thotë se po mbarojmë, nuk kam parë, nuk di asnjë kërkesë përdoruesi, nuk e di se çfarë lloj kërkesat për të cilat kam punuar tani, ata thanë SIGTERM, kjo do të thotë se po mbarojmë " Ky është gjithashtu një opsion i keq.

Cili opsion është i mirë? Pika e parë është të merret parasysh përfundimi i operacioneve. Një opsion i mirë është që serveri juaj të marrë ende parasysh atë që bën nëse merr një SIGTERM.

SIGTERM është mbyllje e butë, është projektuar posaçërisht, mund të përgjohet në nivelin e kodit, mund të përpunohet, thuaj tani, prisni, fillimisht do të mbarojmë punën që kemi, pastaj do të dalim.

Nga perspektiva e Kubernetes, kjo është se si duket. Kur i themi një pod që po funksionon në grupin Kubernetes, "ju lutem ndalo, largohu", ose ne rifillojmë, ose ndodh një përditësim kur Kubernetes rikrijon pods, Kubernetes dërgon të njëjtin mesazh SIGTERM në pod, pret ca kohë, dhe, kjo është koha që ai pret, është gjithashtu e konfiguruar, ka një parametër kaq të veçantë në diploma dhe quhet Graceful ShutdownTimeout. Siç e kuptoni, nuk quhet kot kështu dhe jo më kot po flasim tani.

Aty mund të themi konkretisht se sa kohë duhet të presim midis kohës që dërgojmë SIGTERM në aplikacion dhe kur kuptojmë se aplikacioni duket se është çmendur për diçka ose është "i mbërthyer" dhe nuk do të përfundojë - dhe ne duhet të dërgojeni SIGKILL, domethënë, përfundojeni me zor punën e tij. Kjo do të thotë, në përputhje me rrethanat, ne kemi një lloj demon që funksionon, ai përpunon operacione. Ne e kuptojmë se mesatarisht operacionet tona mbi të cilat punon daemoni nuk zgjasin më shumë se 30 sekonda në të njëjtën kohë. Prandaj, kur të mbërrijë SIGTERM, ne e kuptojmë se daemon-i ynë mund të përfundojë maksimumi 30 sekonda pas SIGTERM. Ne e shkruajmë atë, për shembull, 45 sekonda për çdo rast dhe themi se SIGTERM. Pas kësaj presim 45 sekonda. Në teori, gjatë kësaj kohe demoni duhet të kishte përfunduar punën e tij dhe të kishte përfunduar vetë. Por nëse befas nuk mundet, do të thotë se ka shumë të ngjarë të ketë ngecur—nuk po i përpunon më kërkesat tona normalisht. Dhe në 45 sekonda mund ta gozhdoni me siguri, në fakt.

Dhe këtu, në fakt, mund të merren parasysh edhe 2 aspekte. Së pari, kuptoni se nëse keni marrë një kërkesë, keni filluar të punoni me të disi dhe nuk i keni dhënë përgjigje përdoruesit, por keni marrë SIGTERM, për shembull. Ka kuptim ta rafinoni atë dhe t'i jepni një përgjigje përdoruesit. Kjo është pika numër një në këtë drejtim. Pika numër dy këtu është se nëse shkruani aplikacionin tuaj, në përgjithësi ndërtoni arkitekturën në mënyrë të tillë që të merrni një kërkesë për aplikacionin tuaj, atëherë filloni një punë, filloni të shkarkoni skedarë nga diku, të shkarkoni një bazë të dhënash, dhe jo më shumë. - Se. Në përgjithësi, përdoruesi juaj, kërkesa juaj varet për gjysmë ore dhe pret që ju t'i përgjigjeni atij - atëherë, ka shumë të ngjarë, ju duhet të punoni në arkitekturë. Kjo do të thotë, thjesht merrni parasysh edhe sensin e përbashkët që nëse operacionet tuaja janë të shkurtra, atëherë ka kuptim të injoroni SIGTERM dhe ta modifikoni atë. Nëse operacionet tuaja janë të gjata, atëherë nuk ka kuptim të injoroni SIGTERM në këtë rast. Ka kuptim të ridizajnohet arkitektura për të shmangur operacione kaq të gjata. Në mënyrë që përdoruesit të mos rrinë dhe të presin. Unë nuk e di, bëni një lloj websocket atje, bëni grepa të kundërt që serveri juaj do t'i dërgojë tashmë klientit, çdo gjë tjetër, por mos e detyroni përdoruesin të rrijë për gjysmë ore dhe thjesht prisni një seancë derisa të përgjigjuni atij. Sepse është e paparashikueshme se ku mund të prishet.

Kur aplikimi juaj përfundon, duhet të jepni një kod të duhur daljeje. Kjo do të thotë, nëse aplikacionit tuaj iu kërkua të mbyllej, ndalonte dhe ai ishte në gjendje të ndalonte vetë normalisht, atëherë nuk keni nevojë të ktheni një lloj kodi daljeje 1,5,255 e kështu me radhë. Çdo gjë që nuk është kod zero, të paktën në sistemet Linux, jam i sigurt për këtë, konsiderohet e pasuksesshme. Domethënë, konsiderohet se aplikimi juaj në këtë rast ka përfunduar me gabim. Prandaj, në mënyrë miqësore, nëse aplikacioni juaj është përfunduar pa gabim, ju thoni 0 në dalje. Nëse aplikacioni juaj dështon për ndonjë arsye, ju thoni jo-0 në dalje. Dhe ju mund të punoni me këtë informacion.

Dhe opsioni i fundit. Është keq kur përdoruesi juaj dërgon një kërkesë dhe qëndron pezull për gjysmë ore ndërsa ju e përpunoni atë. Por në përgjithësi, unë gjithashtu do të doja të them për atë që në përgjithësi ia vlen nga ana e klientit. Nuk ka rëndësi nëse keni një aplikacion celular, front-end, etj. Është e nevojshme të merret parasysh që në përgjithësi seanca e përdoruesit mund të ndërpritet, gjithçka mund të ndodhë. Një kërkesë mund të dërgohet, për shembull, e nënpërpunuar dhe asnjë përgjigje nuk kthehet. Frontend juaj ose aplikacioni juaj celular - çdo frontend në përgjithësi, le ta themi kështu - duhet ta marrë këtë parasysh. Nëse punoni me fole në internet, kjo është përgjithësisht dhimbja më e keqe që kam pasur ndonjëherë.

Kur zhvilluesit e disa bisedave të rregullta nuk e dinë se, rezulton, faqja e internetit mund të prishet. Për ta, kur diçka ndodh në proxy, ne thjesht ndryshojmë konfigurimin dhe ai bën një ringarkim. Natyrisht, të gjitha seancat jetëgjata janë grisur në këtë rast. Zhvilluesit vijnë me vrap tek ne dhe thonë: "Djema, çfarë po bëni, biseda është prishur për të gjithë klientët tanë!" Ne u themi atyre: “Çfarë po bëni? A nuk mund të rilidhen klientët tuaj? Ata thonë: "Jo, ne kemi nevojë që seancat të mos prishen". Me pak fjalë, kjo është në të vërtetë marrëzi. Duhet të merret parasysh edhe ana e klientit. Sidomos, siç them unë, me sesione jetëgjata siç janë uebsocketet, mund të prishet dhe, pa u vënë re nga përdoruesi, duhet të jeni në gjendje të riinstaloni seanca të tilla. Dhe pastaj gjithçka është perfekte.

burime

Në fakt, këtu do t'ju tregoj vetëm një histori të drejtpërdrejtë. Përsëri nga jeta reale. Gjëja më e sëmurë që kam dëgjuar ndonjëherë për burimet.

Burimet në këtë rast, dua të them, një lloj kërkesash, kufijsh që mund të vendosni në pods në grupimet tuaja Kubernetes. Gjëja më qesharake që kam dëgjuar nga një zhvillues... Një nga kolegët e mi zhvillues në një vend të mëparshëm pune tha një herë: "Aplikacioni im nuk do të fillojë në grup." Shikova se nuk po fillonte, por ose nuk përshtatej me burimet, ose kishin vendosur kufij shumë të vegjël. Me pak fjalë, aplikacioni nuk mund të fillojë për shkak të burimeve. Unë them: "Nuk do të fillojë për shkak të burimeve, ju vendosni se sa keni nevojë dhe vendosni një vlerë të përshtatshme." Ai thotë: "Çfarë lloj burimesh?" Fillova t'i shpjegoj se Kubernetes, duhet të vendosen kufizime në kërkesat dhe blah, blah, blah. Burri dëgjoi për pesë minuta, tundi kokën dhe tha: "Kam ardhur këtu për të punuar si zhvillues, nuk dua të di asgjë për asnjë burim. Erdha këtu për të shkruar kodin dhe kaq.” Është e trishtueshme. Ky është një koncept shumë i trishtuar nga këndvështrimi i një zhvilluesi. Sidomos në botën moderne, si të thuash, të devopëve përparimtarë.

Pse nevojiten fare burimet? Ka 2 lloje burimesh në Kubernetes. Disa quhen kërkesa, të tjera quhen limite. Nga burimet do të kuptojmë se në thelb gjithmonë ekzistojnë vetëm dy kufizime themelore. Kjo do të thotë, kufijtë kohorë të CPU dhe kufijtë e RAM-it për një kontejner që funksionon në Kubernetes.

Një limit vendos një kufi të sipërm se si një burim mund të përdoret në aplikacionin tuaj. Kjo do të thotë, në përputhje me rrethanat, nëse thoni 1 GB RAM në kufij, atëherë aplikacioni juaj nuk do të jetë në gjendje të përdorë më shumë se 1 GB RAM. Dhe nëse ai papritmas dëshiron dhe përpiqet ta bëjë këtë, atëherë një proces i quajtur oom killer, jashtë kujtesës, domethënë, do të vijë dhe do të vrasë aplikacionin tuaj - domethënë, ai thjesht do të rifillojë. Aplikacionet nuk do të rifillojnë bazuar në CPU. Për sa i përket CPU-së, nëse një aplikacion përpiqet të përdorë shumë, më shumë se sa specifikohet në kufij, CPU thjesht do të zgjidhet rreptësisht. Kjo nuk çon në rinisje. Ky është kufiri - ky është kufiri i sipërm.

Dhe ka një kërkesë. Një kërkesë është se si Kubernetes kupton se si nyjet në grupin tuaj Kubernetes janë të mbushura me aplikacione. Kjo do të thotë, një kërkesë është një lloj angazhimi i aplikacionit tuaj. Ai thotë se çfarë dua të përdor: "Unë do të doja që të rezervoni kaq shumë CPU dhe kaq shumë memorie për mua." Një analogji kaq e thjeshtë. Po sikur të kemi një nyje që ka, nuk e di, 8 CPU në total. Dhe aty mbërrin një pod, kërkesat e të cilit thonë 1 CPU, që do të thotë se nyja ka 7 CPU të mbetura. Kjo do të thotë, në përputhje me rrethanat, sapo 8 pods arrijnë në këtë nyje, secila prej të cilave ka 1 CPU në kërkesat e tyre, nyja, sikur nga këndvështrimi i Kubernetes, ka mbaruar CPU dhe më shumë pods me kërkesa nuk mund të jenë nisur në këtë nyje. Nëse të gjitha nyjet mbarojnë nga CPU, atëherë Kubernetes do të fillojë të thotë se nuk ka nyje të përshtatshme në grup për të ekzekutuar podet tuaja sepse CPU-ja ka mbaruar.

Pse nevojiten kërkesat dhe pse pa kërkesa, mendoj se nuk ka nevojë të lançohet asgjë në Kubernetes? Le të imagjinojmë një situatë hipotetike. Ju nisni aplikacionin tuaj pa kërkesa, Kubernetes nuk e di se sa nga ato që keni, në cilat nyje mund ta shtyni atë. Epo, ai shtyn, shtyn, shtyn mbi nyjet. Në një moment, do të filloni të merrni trafik në aplikacionin tuaj. Dhe një nga aplikacionet befas fillon të përdorë burime deri në kufijtë që ka sipas limiteve. Rezulton se ka një aplikacion tjetër afër dhe gjithashtu ka nevojë për burime. Nyja në fakt fillon të mbarojë fizikisht pa burime, për shembull, OP. Nyja në fakt fillon të mbarojë fizikisht pa burime, për shembull, memorie me akses të rastësishëm (RAM). Kur një nyje i mbaron fuqia, para së gjithash doker-i do të ndalojë së përgjigjuri, më pas kubeleti, më pas OS. Ata thjesht do të humbasin ndjenjat dhe GJITHÇKA do të pushojë së punuari patjetër për ju. Kjo do të thotë, kjo do të bëjë që nyja juaj të mbërthehet dhe do t'ju duhet ta rinisni atë. Me pak fjalë, situata nuk është shumë e mirë.

Dhe kur keni kërkesa, kufijtë nuk janë shumë të ndryshëm, të paktën jo shumë herë më shumë se kufijtë ose kërkesat, atëherë mund të keni një mbushje kaq normale, racionale të aplikacioneve nëpër nyjet e grupimeve Kubernetes. Në të njëjtën kohë, Kubernetes është afërsisht i vetëdijshëm se sa nga çfarë vendos ku, sa nga çfarë përdoret ku. Kjo do të thotë, është vetëm një moment i tillë. Është e rëndësishme për ta kuptuar atë. Dhe është e rëndësishme të kontrolloni që kjo të tregohet.

Ruajtja e të dhënave

Pika jonë tjetër ka të bëjë me ruajtjen e të dhënave. Çfarë të bëni me ta dhe në përgjithësi, çfarë të bëni me këmbënguljen në Kubernetes?

Unë mendoj, përsëri, brenda tonë Shkolla e Mbrëmjes, kishte një temë në lidhje me bazën e të dhënave në Kubernetes. Dhe më duket se madje e di përafërsisht atë që ju thanë kolegët tuaj kur u pyetën: "A është e mundur të ekzekutosh një bazë të dhënash në Kubernetes?" Për disa arsye, më duket se kolegët tuaj duhet t'ju kishin thënë se nëse po bëni pyetjen nëse është e mundur të ekzekutoni një bazë të dhënash në Kubernetes, atëherë është e pamundur.

Logjika këtu është e thjeshtë. Për çdo rast, unë do ta shpjegoj edhe një herë, nëse jeni një djalë vërtet i lezetshëm që mund të ndërtojë një sistem mjaft tolerant ndaj gabimeve të ruajtjes së rrjetit të shpërndarë, kuptoni se si të vendosni një bazë të dhënash në këtë rast, si duhet të funksionojë rea vendase në kontejnerë në një bazë të dhënash në përgjithësi. Me shumë mundësi, nuk keni pyetje se si ta ekzekutoni atë. Nëse keni një pyetje të tillë dhe dëshironi të siguroheni që gjithçka të shpaloset dhe të qëndrojë drejt vdekjes në prodhim dhe të mos bjerë kurrë, atëherë kjo nuk ndodh. Ju jeni të garantuar të qëlloni veten në këmbë me këtë qasje. Prandaj, është më mirë të mos.

Çfarë duhet të bëjmë me të dhënat që aplikacioni ynë do të dëshironte të ruante, disa fotografi që ngarkojnë përdoruesit, disa gjëra që aplikacioni ynë gjeneron gjatë funksionimit të tij, për shembull gjatë fillimit? Çfarë të bëni me ta në Kubernetes?

Në përgjithësi, në mënyrë ideale, po, sigurisht, Kubernetes është projektuar shumë mirë dhe në përgjithësi u konceptua fillimisht për aplikacione pa shtetësi. Kjo është, për ato aplikacione që nuk ruajnë fare informacion. Kjo është ideale.

Por, sigurisht, opsioni ideal nuk ekziston gjithmonë. Edhe çfarë? Pika e parë dhe më e thjeshtë është të marrësh një lloj S3, thjesht jo një të bërë në shtëpi, e cila është gjithashtu e paqartë se si funksionon, por nga një ofrues. Një ofrues i mirë, normal - dhe mësoni aplikacionin tuaj të përdorë S3. Kjo do të thotë, kur përdoruesi juaj dëshiron të ngarkojë një skedar, thoni "këtu, ju lutem, ngarkoni atë në S3". Kur ai dëshiron ta marrë atë, thuaj: "Këtu është një lidhje me S3 mbrapa dhe merre nga këtu." Kjo është ideale.

Nëse papritmas për ndonjë arsye ky opsion ideal nuk është i përshtatshëm, keni një aplikacion që nuk e keni shkruar, nuk e keni zhvilluar, ose është një lloj trashëgimie e tmerrshme, nuk mund të përdorë protokollin S3, por duhet të punojë me drejtoritë lokale në dosjet lokale. Merrni diçka pak a shumë të thjeshtë, vendosni Kubernetes. Domethënë, të rrethosh menjëherë Cefin për disa detyra minimale, më duket, është një ide e keqe. Sepse Ceph, natyrisht, është i mirë dhe në modë. Por nëse nuk e kuptoni vërtet atë që po bëni, atëherë sapo t'i vendosni diçka Ceph-it, mund ta hiqni shumë lehtë dhe thjesht kurrë më nga atje. Sepse, siç e dini, Ceph ruan të dhënat në grupin e tij në formë binare, dhe jo në formën e skedarëve të thjeshtë. Prandaj, nëse papritmas grupi Ceph prishet, atëherë ekziston një probabilitet i plotë dhe i lartë që nuk do t'i merrni më kurrë të dhënat tuaja nga atje.

Ne do të kemi një kurs për Ceph, ju mundeni njohuni me programin dhe paraqisni një aplikim.

Prandaj, është më mirë të bëni diçka të thjeshtë si një server NFS. Kubernetes mund të punojë me ta, ju mund të montoni një drejtori nën një server NFS - aplikacioni juaj është njësoj si një direktori lokale. Në të njëjtën kohë, natyrisht, ju duhet të kuptoni se, përsëri, duhet të bëni diçka me NFS-në tuaj, duhet të kuptoni se ndonjëherë mund të bëhet i paarritshëm dhe të merrni parasysh pyetjen se çfarë do të bëni në këtë rast. Ndoshta duhet të rezervohet diku në një makinë të veçantë.

Pika tjetër për të cilën fola është se çfarë të bëni nëse aplikacioni juaj gjeneron disa skedarë gjatë funksionimit. Për shembull, kur fillon, gjeneron një skedar statik, i cili bazohet në disa informacione që aplikacioni merr vetëm në momentin e nisjes. Çfarë momenti. Nëse nuk ka shumë të dhëna të tilla, atëherë nuk duhet të shqetësoheni fare, thjesht instaloni këtë aplikacion për veten tuaj dhe punoni. Pyetja e vetme këtu është se çfarë, shikoni. Shumë shpesh, të gjitha llojet e sistemeve të trashëgimisë, si WordPress dhe kështu me radhë, veçanërisht me disa lloj shtojcash të zgjuara të modifikuara, zhvillues të zgjuar PHP, ata shpesh dinë ta bëjnë atë në mënyrë që të gjenerojnë një lloj skedari për veten e tyre. Prandaj, njëri gjeneron një skedar, i dyti gjeneron një skedar të dytë. Ato janë të ndryshme. Balancimi ndodh në grupin Kubernetes të klientëve thjesht rastësisht. Prandaj, rezulton se ata nuk dinë të punojnë së bashku në shembull. Njëri jep një informacion, tjetri i jep përdoruesit një informacion tjetër. Kjo është diçka që duhet të shmangni. Kjo do të thotë, në Kubernetes, gjithçka që lëshoni është e garantuar të jetë në gjendje të funksionojë në shumë raste. Sepse Kubernetes është një gjë lëvizëse. Prandaj, ai mund të lëvizë çdo gjë, kur të dojë, pa pyetur fare askënd. Prandaj, duhet të mbështeteni në këtë. Çdo gjë e nisur në një rast do të dështojë herët a vonë. Sa më shumë rezervime të keni, aq më mirë. Por përsëri, unë them, nëse keni disa skedarë të tillë, atëherë mund t'i vendosni pikërisht poshtë jush, ato peshojnë pak. Nëse ka pak më shumë prej tyre, ndoshta nuk duhet t'i shtyni brenda në enë.

Unë do të këshilloja që ka një gjë kaq të mrekullueshme në Kubernetes, mund të përdorni volumin. Në veçanti, ka një vëllim të tipit bosh dir. Kjo do të thotë, është thjesht se Kubernetes do të krijojë automatikisht një drejtori në drejtoritë e tij të shërbimit në serverin ku keni filluar. Dhe ai do t'jua japë që ju ta përdorni. Ka vetëm një pikë të rëndësishme. Kjo do të thotë, të dhënat tuaja nuk do të ruhen brenda kontejnerit, por më tepër në hostin në të cilin po ekzekutoni. Për më tepër, Kubernetes mund të kontrollojë dire të tilla boshe nën konfigurimin normal dhe është në gjendje të kontrollojë madhësinë e tyre maksimale dhe të mos lejojë tejkalimin e saj. E vetmja gjë është që ajo që keni shkruar në dir bosh nuk humbet gjatë rinisjes së pod. Kjo do të thotë, nëse pod juaj bie gabimisht dhe ngrihet përsëri, informacioni në dir bosh nuk do të shkojë askund. Ai mund ta përdorë përsëri në një fillim të ri - dhe kjo është mirë. Nëse pod juaj largohet diku, atëherë natyrisht ai do të largohet pa të dhëna. Kjo do të thotë, sapo pod nga nyja ku është nisur me dir bosh zhduket, dir bosh fshihet.

Çfarë tjetër është e mirë për regjinë boshe? Për shembull, mund të përdoret si një cache. Le të imagjinojmë që aplikacioni ynë gjeneron diçka në fluturim, ua jep përdoruesve dhe e bën atë për një kohë të gjatë. Prandaj, aplikacioni p.sh., e gjeneron dhe ua jep përdoruesve, dhe njëkohësisht e ruan diku, në mënyrë që herën tjetër që përdoruesi të vijë për të njëjtën gjë, të jetë më i shpejtë për t'i dhënë të gjeneruar menjëherë. Direktori bosh mund t'i kërkohet Kubernetes për të krijuar në memorie. Dhe kështu, memoria juaj e fshehtë në përgjithësi mund të funksionojë me shpejtësi rrufe - për sa i përket shpejtësisë së hyrjes në disk. Kjo do të thotë, ju keni një dir bosh në memorie, në OS ruhet në memorie, por për ju, për përdoruesin brenda pod, duket thjesht si një direktori lokale. Nuk ju nevojitet aplikacioni për të mësuar në mënyrë specifike ndonjë magji. Ju thjesht merrni direkt dhe vendosni skedarin tuaj në një drejtori, por, në fakt, në memorie në OS. Ky është gjithashtu një veçori shumë e përshtatshme për sa i përket Kubernetes.

Çfarë problemesh ka Minio? Problemi kryesor me Minio është se që kjo gjë të funksionojë, duhet të funksionojë diku dhe duhet të ketë një lloj sistemi skedarësh, domethënë ruajtje. Dhe këtu ndeshemi me të njëjtat probleme që ka Ceph. Kjo do të thotë, Minio duhet të ruajë skedarët e tij diku. Është thjesht një ndërfaqe HTTP për skedarët tuaj. Për më tepër, funksionaliteti është dukshëm më i dobët se ai i S3 të Amazon. Më parë, nuk ishte në gjendje të autorizonte siç duhet përdoruesin. Tani, me sa di unë, tashmë mund të krijojë kova me autorizime të ndryshme, por përsëri, më duket se problemi kryesor është, si të thuash, sistemi themelor i ruajtjes së paku.

Si ndikon Empty dir në kujtesë në kufijtë? Nuk ndikon në kufijtë në asnjë mënyrë. Ajo qëndron në kujtesën e pritësit dhe jo në kujtesën e kontejnerit tuaj. Kjo do të thotë, kontejneri juaj nuk e sheh dir-in bosh në memorie si pjesë të kujtesës së tij të zënë. Pritësi e sheh këtë. Në përputhje me rrethanat, po, nga pikëpamja e kubernetes, kur të filloni ta përdorni këtë, do të ishte mirë të kuptoni se po i kushtoni një pjesë të kujtesës suaj regjisë së zbrazët. Dhe në përputhje me rrethanat, kuptoni se kujtesa mund të mbarojë jo vetëm për shkak të aplikacioneve, por edhe sepse dikush u shkruan këtyre regjistrave bosh.

retë

Dhe nëntema e fundit është ajo që është Cloudnative. Pse është e nevojshme? turbullira dhe kështu me radhë.

Kjo është, ato aplikacione që janë të afta dhe të shkruara për të punuar në një infrastrukturë moderne cloud. Por, në fakt, Cloudnative ka një tjetër aspekt të tillë. Që ky nuk është vetëm një aplikacion që merr parasysh të gjitha kërkesat e një infrastrukture moderne cloud, por di të punojë edhe me këtë infrastrukturë moderne cloud, përfitoni nga avantazhet dhe disavantazhet e faktit që funksionon në këto re. Mos e teproni dhe punoni në re, por përfitoni nga përfitimet e punës në re.

Kërkesat për zhvillimin e një aplikacioni në Kubernetes

Le të marrim vetëm Kubernetes si shembull. Aplikacioni juaj po ekzekutohet në Kubernetes. Aplikacioni juaj gjithmonë, ose më saktë administratorët e aplikacionit tuaj, mund të krijojnë gjithmonë një llogari shërbimi. Kjo do të thotë, një llogari për autorizim në vetë Kubernetes në serverin e tij. Shtoni disa të drejta që na duhen atje. Dhe ju mund të përdorni Kubernetes nga brenda aplikacionit tuaj. Çfarë mund të bëni në këtë mënyrë? Për shembull, nga aplikacioni, merrni të dhëna se ku ndodhen aplikacionet tuaja të tjera, instanca të tjera të ngjashme dhe së bashku grumbullohuni disi në krye të Kubernetes, nëse ka një nevojë të tillë.

Përsëri, fjalë për fjalë kemi pasur një rast kohët e fundit. Ne kemi një kontrollues që monitoron radhën. Dhe kur shfaqen disa detyra të reja në këtë radhë, ajo shkon në Kubernetes - dhe brenda Kubernetes krijon një pod të ri. I jep këtij pod një detyrë të re dhe brenda kornizës së këtij pod, pod kryen detyrën, i dërgon një përgjigje vetë kontrolluesit dhe kontrolluesi më pas bën diçka me këtë informacion. Për shembull, ai shton një bazë të dhënash. Kjo është, përsëri, ky është një plus i faktit që aplikacioni ynë funksionon në Kubernetes. Ne mund të përdorim vetë funksionalitetin e integruar Kubernetes në mënyrë që të zgjerojmë disi dhe ta bëjmë funksionalitetin e aplikacionit tonë më të përshtatshëm. Kjo do të thotë, mos fshihni një lloj magjie se si të nisni një aplikacion, si të nisni një punëtor. Në Kubernetes, ju thjesht dërgoni një kërkesë në aplikacion nëse aplikacioni është i shkruar në Python.

E njëjta gjë vlen nëse shkojmë përtej Kubernetes. Ne kemi Kubernetet tona që funksionojnë diku - është mirë nëse është në një lloj reje. Përsëri, ne mund të përdorim, dhe madje duhet, besoj, të përdorim aftësitë e vetë cloud ku po vrapojmë. Nga gjërat elementare që na ofron cloud. Balancimi, domethënë, ne mund të krijojmë balancues cloud dhe t'i përdorim ato. Ky është një avantazh i drejtpërdrejtë i asaj që ne mund të përdorim. Sepse balancimi i cloud, së pari, thjesht heq përgjegjësinë nga ne për mënyrën se si funksionon, si është konfiguruar. Plus, është shumë i përshtatshëm, sepse Kubernetes e rregullt mund të integrohen me retë.

E njëjta gjë vlen edhe për shkallëzimin. Kubernetes e rregullt mund të integrohen me ofruesit e cloud. Di të kuptojë se nëse grupit i mbarojnë nyjet, domethënë hapësira e nyjeve ka mbaruar, atëherë duhet të shtoni - vetë Kubernetes do të shtojë nyje të reja në grupin tuaj dhe do të fillojë të lëshojë pods mbi to. Kjo do të thotë, kur të vijë ngarkesa juaj, numri i vatrave fillon të rritet. Kur nyjet në grup mbarojnë për këto pods, Kubernetes lëshon nyje të reja dhe, në përputhje me rrethanat, numri i pods mund të rritet ende. Dhe është shumë i përshtatshëm. Kjo është një mundësi e drejtpërdrejtë për të shkallëzuar grupin në fluturim. Jo shumë shpejt, në kuptimin që nuk është një sekondë, është më shumë si një minutë për të shtuar nyje të reja.

Por nga përvoja ime, përsëri, është gjëja më interesante që kam parë ndonjëherë. Kur grupi Cloudnative u shkallëzua në bazë të kohës së ditës. Ishte një shërbim backend që përdorej nga njerëzit në zyrën e pasme. Kjo do të thotë, ata vijnë në punë në orën 9 të mëngjesit, fillojnë të regjistrohen në sistem, dhe në përputhje me rrethanat, grupi Cloudnative, ku po funksionon, fillon të fryhet, duke lëshuar pods të rinj në mënyrë që të gjithë ata që vijnë në punë të mund të punojnë me aplikacionin. Kur largohen nga puna në orën 8 ose 6, grupet Kubernetes vërejnë se askush nuk po e përdor më aplikacionin dhe fillojnë të tkurren. Kursimet deri në 30 përqind janë të garantuara. Në atë kohë funksiononte në Amazon; në atë kohë nuk kishte njeri në Rusi që mund ta bënte kaq mirë.

Unë do t'ju them drejtpërdrejt, kursimet janë 30 për qind thjesht sepse ne përdorim Kubernetes dhe përfitojmë nga aftësitë e cloud. Tani kjo mund të bëhet në Rusi. Unë nuk do t'i reklamoj askujt, sigurisht, por le të themi vetëm se ka ofrues që mund ta bëjnë këtë, ta ofrojnë menjëherë me një buton.

Është edhe një pikë e fundit që do të doja të tërhiqja vëmendjen tuaj. Në mënyrë që aplikacioni juaj, infrastruktura juaj të jetë Cloudnative, ka kuptim që më në fund të filloni të përshtatni qasjen e quajtur Infrastruktura si Kod. Kjo do të thotë se aplikacioni juaj, ose më mirë infrastruktura juaj, nevojitet pikërisht në të njëjtën mënyrë si kodi Përshkruani aplikacionin tuaj, logjikën e biznesit tuaj në formën e kodit. Dhe punoni me të si kod, d.m.th., provojeni, shpërndajeni, ruajeni në git, aplikoni CICD në të.

Dhe kjo është pikërisht ajo që ju lejon, së pari, të keni gjithmonë kontroll mbi infrastrukturën tuaj, të kuptoni gjithmonë se në çfarë gjendje është. Së dyti, shmangni veprimet manuale që shkaktojnë gabime. Së treti, shmangni thjesht atë që quhet qarkullim, kur vazhdimisht keni nevojë të kryeni të njëjtat detyra manuale. Së katërti, ju lejon të rikuperoni shumë më shpejt në rast të një dështimi. Në Rusi, sa herë që flas për këtë, ka gjithmonë një numër të madh njerëzish që thonë: "Po, është e qartë, por ju keni qasje, me pak fjalë, nuk ka nevojë të rregulloni asgjë." Por eshte e vertete. Nëse diçka është e prishur në infrastrukturën tuaj, atëherë nga pikëpamja e qasjes Cloudnative dhe nga këndvështrimi i Infrastrukturës si Kod, në vend që ta rregulloni atë, të shkoni te serveri, të kuptoni se çfarë është prishur dhe ta rregulloni atë, është më e lehtë. për të fshirë serverin dhe për ta krijuar përsëri. Dhe unë do ta restauroj gjithë këtë.

Të gjitha këto çështje diskutohen më në detaje në Kurse video Kubernetes: Junior, Basic, Mega. Duke ndjekur lidhjen mund të njiheni me programin dhe kushtet. Gjëja më e përshtatshme është që ju mund të zotëroni Kubernetes duke studiuar nga shtëpia ose puna për 1-2 orë në ditë.

Burimi: www.habr.com

Shto një koment