paint-brush
Si të optimizoni Kubernetes për imazhe të mëdha Docker nga@kksudo
132 lexime

Si të optimizoni Kubernetes për imazhe të mëdha Docker

nga Kazakov Kirill10m2024/09/30
Read on Terminal Reader

Shume gjate; Te lexosh

🚀 Magjistarët e Kubernetes, a jeni lodhur duke pritur me orë të tëra që nyjet tuaja të ngrohen? Imagjinoni ta shkurtoni atë kohë në sekonda! Ky artikull që ndryshon lojën zbulon se si të karikoni me turbo procesin e vendosjes së Kubernetes, edhe me imazhe masive 3 GB dhe 1000 pods. Zbuloni salcën sekrete që e transformon performancën e grupit tuaj nga e ngadaltë në supersonike. Mos lejoni që ngrohjet e ngadalta t'ju pengojnë – mësoni se si të revolucionarizoni rrjedhën tuaj të punës Kubernetes sot!
featured image - Si të optimizoni Kubernetes për imazhe të mëdha Docker
Kazakov Kirill HackerNoon profile picture
0-item

Një pasqyrë e shkurtër e problemit

Një ditë, gjatë një përditësimi të planifikuar të grupit k8s, zbuluam se pothuajse të gjitha POD-të tona (afërsisht 500 nga 1000) në nyjet e reja nuk mund të fillonin dhe minutat u kthyen shpejt në orë. Jemi në kërkim aktiv për shkakun kryesor, por pas tre orësh, PODS ishin ende në statusin ContainerCreating .


Kubernetes ngeci në ContainerCreating

Fatmirësisht, ky nuk ishte mjedisi nxitës dhe dritarja e mirëmbajtjes ishte planifikuar për fundjavë. Kishim kohë për ta hetuar këtë çështje pa asnjë presion. Ku duhet të filloni kërkimin tuaj për shkakun kryesor? Dëshironi të mësoni më shumë rreth zgjidhjes që gjetëm? Lidheni dhe kënaquni!

Më shumë detaje rreth problemit

Problemi ishte se ne kishim një numër të madh imazhesh doker që duhej të tërhiqeshin dhe të fillonin në secilën nyje në grup në të njëjtën kohë. Kjo ndodhi sepse tërheqjet e shumta të njëkohshme të imazhit të dokerit në një nyje të vetme mund të çojnë në përdorim të lartë të diskut dhe kohë të zgjatura të fillimit të ftohtë.


Herë pas here, procesi i CD-së zgjat deri në 3 orë për të tërhequr imazhet. Sidoqoftë, këtë herë ishte plotësisht i mbërthyer, sepse sasia e PODS gjatë azhurnimit të EKS (në linjë, kur zëvendësojmë të gjitha nyjet në grup) ishte shumë e lartë.


  • Të gjitha aplikacionet tona jetojnë në k8s (bazuar në ). Për të kursyer në kostot tona për DEV env, ne përdorim rastet e rastit.
  • Ne përdorim imazhin për nyjet.
  • Ne kemi një numër të madh të degëve të veçorive (FB) në mjedisin e zhvillimit që janë vendosur vazhdimisht në grupin tonë Kubernetes. Çdo FB ka grupin e vet të aplikacioneve dhe çdo aplikacion ka grupin e vet të varësive (brenda një imazhi).

  • Në projektin tonë, pothuajse 200 aplikacione dhe ky numër po rritet. Çdo aplikacion përdor një nga 7 imazhet bazë të dokerit me një madhësi prej ~2 GB. Madhësia maksimale totale e imazhit të arkivuar (në ) është rreth 3 GB.
  • Të gjitha imazhet ruhen në Regjistrin e Elastic Container Amazon (ECR).
  • Ne përdorim tipin e paracaktuar të volumit gp3 EBS për nyjet.


Problemet me të cilat përballen

  • Koha e zgjatur e fillimit të ftohtë: Fillimi i një pod të ri me një imazh të ri mund të zgjasë më shumë se 1 orë, veçanërisht kur disa imazhe tërhiqen njëkohësisht në një nyje të vetme.

  • Gabime ErrImagePull: ErrImagePull e shpeshta ose ngec me gjendjet ContainerCreating , duke treguar probleme me tërheqjen e imazhit.

  • Përdorimi i lartë i diskut: Përdorimi i diskut mbetet afër 100% gjatë procesit të tërheqjes së imazhit, kryesisht për shkak të hyrjes/daljes intensive të diskut që kërkohet për dekompresim (p.sh., "unpigz").

  • Problemet e sistemit DaemonSet: Disa DaemonSet të sistemit (si aws-node ose ebs-csi-node ) kaluan në gjendjen "jo gati" për shkak të presionit të diskut, duke ndikuar në gatishmërinë e nyjeve.

  • Nuk ka cache imazhesh në nyje: Për shkak se ne përdorim raste të veçanta, nuk mund të përdorim diskun lokal për të ruajtur imazhet.


Kjo rezulton në shumë vendosje të ngecura në degët e veçorive, veçanërisht sepse FB-të e ndryshme kanë grupe të ndryshme imazhesh bazë.

Pas një hetimi të shpejtë, ne zbuluam se çështja kryesore ishte presioni i diskut mbi nyjet nga procesi unpigz . Ky proces është përgjegjës për dekompresimin e imazheve të dokerit. Nuk i ndryshuam cilësimet e paracaktuara për llojin e volumit gp3 EBS, sepse nuk janë të përshtatshme për rastin tonë.


Rregullim i shpejtë për të rikuperuar grupin

Si hap i parë, ne vendosëm të reduktojmë numrin e POD-ve në nyje.
  1. Ne i zhvendosim nyjet e reja në gjendjen "Cordon".
  2. Hiqni të gjitha PODS të mbërthyer për të reduktuar presionin e diskut
  3. Drejtoni një nga një POD-të për të ngrohur nyjet
  4. Pas kësaj, ne i zhvendosim nyjet e ngrohura në gjendjen normale ("unCordon")
  5. U hoqën të gjitha nyjet në gjendje të mbërthyer
  6. Të gjitha PODS filluan me sukses duke përdorur cache-in e imazhit Docker


Një dizajn origjinal CI/CD

Ideja kryesore e zgjidhjes është të ngrohni nyjet përpara se procesi i CD-së të fillojë nga pjesa më e madhe e imazhit të dokerit (shtresa e varësisë së JS), e cila përdoret si imazhi rrënjësor për të gjitha aplikacionet tona. Kemi të paktën 7 lloje të imazheve rrënjësore me varësi JS, të cilat lidhen me llojin e aplikacionit. Pra, le të analizojmë dizajnin origjinal CI/CD.


Në tubacionin tonë CI/CD, ne kemi 3 shtylla: Një tubacion origjinal CI/CD

Një tubacion origjinal CI/CD:

  1. Në hapin Init it: ne përgatisim mjedisin/ndryshoret, përcaktojmë grupin e imazheve për t'u rindërtuar, etj...

  2. Në hapin Build : ne ndërtojmë imazhet dhe i shtyjmë në ECR

  3. Në hapin Deploy : ne vendosim imazhet në k8 (përditësimet, etj...)


Më shumë detaje rreth modelit origjinal CICD:

  • Degët tona të veçorive (FB) u shkëputën nga dega main . Në procesin CI, ne gjithmonë analizojmë grupin e imazheve që janë ndryshuar në FB dhe i rindërtojmë ato. Dega main është gjithmonë e qëndrueshme, pasi përkufizimi, duhet të ketë gjithmonë versionin më të fundit të imazheve bazë.
  • Ne ndërtojmë veçmas imazhet e dokerit të varësisë JS (për secilin mjedis) dhe e shtyjmë atë në ECR për ta ripërdorur atë si imazhin rrënjë (bazë) në Dockerfile. Ne kemi rreth 5–10 lloje të imazhit të dokerit të varësive JS.
  • FB vendoset në grupin k8s në hapësirën e veçantë të emrave, por në nyjet e zakonshme për FB. FB mund të ketë ~ 200 aplikacione, me madhësi imazhi deri në 3 GB.
  • Kemi sistemin e shkallëzimit automatik të grupimit, i cili shkallëzon nyjet në grup në bazë të ngarkesës ose PODS në pritje me përzgjedhësin dhe tolerancën përkatëse të nyjeve.
  • Ne përdorim instancat e pikave për nyjet.

Zbatimi i procesit të ngrohjes

Ekzistojnë kërkesa për procesin e ngrohjes. E detyrueshme:
  1. Zgjidhja e problemit : Adreson dhe zgjidh çështjet ContainerCreating .
  2. Performanca e përmirësuar : Redukton ndjeshëm kohën e nisjes duke përdorur imazhet bazë të ngrohura paraprakisht (varësitë JS).
Është mirë të kemi përmirësime:
  1. Fleksibiliteti : Lejon ndryshime të lehta në llojin e nyjës dhe jetëgjatësinë e saj (p.sh. SLA e lartë ose kohë e zgjatur për të jetuar).
  2. Transparenca : Ofron metrika të qarta mbi përdorimin dhe performancën.
  3. Efikasiteti i kostos : Kursen kostot duke fshirë VNG menjëherë pasi të fshihet dega e veçorive përkatëse.
  4. Izolimi : Kjo qasje siguron që mjediset e tjera të mos preken.

Zgjidhje

Pas analizimit të kërkesave dhe kufizimeve, vendosëm të zbatonim një proces nxehjeje që do të ngrohte paraprakisht nyjet me imazhet bazë të memories JS. Ky proces do të aktivizohej përpara se të fillojë procesi i CD-së, duke siguruar që nyjet të jenë gati për vendosjen e FB dhe ne kemi një shans maksimal për të goditur cache.


Këtë përmirësim e ndajmë në hapa të mëdhenj të pemës:
  1. Krijoni grupin e nyjeve (Virtual Node Group) për çdo FB

  2. Shtoni imazhe bazë në skriptin cloud-init për nyjet e reja

  3. Shtoni një hap të paravendosjes për të ekzekutuar DaemonSet me seksionin initContainers për të shkarkuar imazhet e nevojshme të dokerit në nyjet përpara se të fillojë procesi i CD-së.


Një tubacion i përditësuar CI/CD do të duket kështu: Një tubacion i përditësuar CI/CD


Një tubacion i përditësuar CI/CD:

  1. Hapi fillestar
    1.1. (hap i ri) Init disploy : Nëse është fillimi i parë i FB-së, atëherë krijoni një grup të ri personal të rasteve të nyjeve (sipas termave tanë është Virtual Node Group ose VNG) dhe shkarkoni të gjitha imazhet bazë JS (5–10 imazhe ) nga dega kryesore. Eshte e drejte ta bejme, se e kemi pirun FB-ne nga dega kryesore. Një pikë e rëndësishme, nuk është një operacion bllokues.
  2. Ndërtimi i hapit
  3. Hapi para vendosjes Shkarkoni imazhe bazë JS të freskëta të pjekura me etiketën specifike FB nga ECR.
    3.1.(hap i ri) Pika të rëndësishme : Është një operacion bllokimi, sepse duhet të ulim presionin e diskut. Një nga një, ne shkarkojmë imazhet bazë për secilën nyje të lidhur.
    Btw, faleminderit për hapin " init deploy" , ne tashmë kemi imazhet bazë docker nga dega kryesore, që do të na japë një shans të madh për të goditur cache në fillimin e parë.
  4. **Shpërndani
    **Nuk ka ndryshime në këtë hap. Por falë hapit të mëparshëm, ne tashmë i kemi të gjitha shtresat e rënda të imazhit docker në nyjet e nevojshme.

Filloni hapin e vendosjes

Krijo një grup të ri nyjesh për çdo FB nëpërmjet thirrjes API (në sistemin e shkallëzimit automatik të palës së tretë) nga tubacioni ynë CI.


Çështjet e zgjidhura:

  1. Izolimi : Çdo FB ka grupin e vet të nyjeve, duke siguruar që mjedisi të mos ndikohet nga FB të tjera.

  2. Fleksibiliteti : Ne mund të ndryshojmë lehtësisht llojin e nyjës dhe jetëgjatësinë e tij.

  3. Efikasiteti i kostos : Ne mund t'i fshijmë nyjet menjëherë pasi të fshihet FB.

  4. Transparenca : Ne mund të gjurmojmë lehtësisht përdorimin dhe performancën e nyjeve (secila nyje ka një etiketë të lidhur me FB).

  5. Përdorimi efektiv i instancave të pikave : Shembulli i spotit fillon me imazhe bazë të paracaktuara, që do të thotë, pasi të fillojë nyja e spotit, tashmë janë imazhet bazë në nyje (nga dega kryesore).


Shkarkoni të gjitha imazhet e bazës JS nga dega kryesore në nyjet e reja nëpërmjet skriptit cloud-init .


Ndërsa imazhet po shkarkohen në sfond, procesi i CD-së mund të vazhdojë të krijojë imazhe të reja pa asnjë problem. Për më tepër, nyjet e ardhshme (të cilat do të krijohen nga sistemi i shkallëzimit automatik) nga ky grup do të krijohen me të dhënat e përditësuara cloud-init , të cilat tashmë kanë udhëzime për të shkarkuar imazhe përpara fillimit.


Çështjet e zgjidhura:
  1. Zgjidhja e problemit : Presioni i diskut është zhdukur, sepse ne përditësuam skriptin cloud-init duke shtuar shkarkimin e imazheve bazë nga dega kryesore. Kjo na lejon të godasim cache në fillimin e parë të FB.

  2. Përdorimi efektiv i rasteve spot : Shembulli i spotit po fillon me të dhënat e përditësuara cloud-init . Do të thotë, që pasi të fillojë nyja e pikës, tashmë ka imazhet bazë në nyje (nga dega kryesore).

  3. Performanca e përmirësuar : Procesi i CD-së mund të vazhdojë të krijojë imazhe të reja pa asnjë problem.


Ky veprim shtoi ~17 sekonda (thirrje API) në tubacionin tonë CI/CD. Ky veprim ka kuptim vetëm herën e parë kur nisim FB-në. Herën tjetër, ne vendosim aplikacionet tona në nyjet tashmë ekzistuese, të cilat tashmë kanë imazhet bazë, të cilat i kemi dorëzuar në vendosjen e mëparshme.

Hapi para vendosjes

Ne kemi nevojë për këtë hap, sepse imazhet në FB janë të ndryshme nga imazhet e degës kryesore. Ne duhet të shkarkojmë imazhet bazë të FB në nyjet përpara se të fillojë procesi i CD-së. Kjo do të ndihmojë për të zbutur kohët e zgjatura të fillimit të ftohtë dhe përdorimin e lartë të diskut që mund të ndodhë kur disa imazhe të rënda tërhiqen njëkohësisht.


Objektivat e hapit të paravendosjes

  1. Parandalimi i presionit të diskut : Shkarkoni në mënyrë sekuenciale imazhet më të rënda të docker. Pas hapit init-deploy, ne tashmë kemi imazhet bazë në nyjet, që do të thotë se kemi një shans të madh për të goditur cache.

  2. Përmirësoni efikasitetin e vendosjes : Sigurohuni që nyjet të ngrohen paraprakisht me imazhe thelbësore të dokerit, duke çuar në kohë më të shpejta (pothuajse menjëherë) të fillimit të POD.

  3. Rritja e stabilitetit : Minimizoni shanset për të hasur gabime ErrImagePull / ContainerCreating dhe sigurohuni që grupet e demonëve të sistemit të mbeten në një gjendje "gati".


Sipas këtij hapi, ne i shtojmë 10-15 minuta procesit të CD-së. Detajet e hapit para vendosjes:
  • Në CD krijojmë një DaemonSet me seksionin initContainers .
  • Seksioni initContainers ekzekutohet përpara se të nisë kontejneri kryesor, duke siguruar që imazhet e nevojshme të shkarkohen përpara se të fillojë kontejneri kryesor.
  • Në CD ne po kontrollojmë vazhdimisht statusin e daemonSet. Nëse daemonSet është në një gjendje "gati", ne vazhdojmë me vendosjen. Përndryshe, presim që daemonSet të jetë gati.

Krahasimi

Krahasimi i hapave origjinalë dhe të përditësuar me procesin e paranxehjes.
Hapi Filloni hapin e vendosjes Hapi para vendosjes Vendosni Koha totale Ndryshim
Pa ngrohje paraprake 0 0 11m 21s 11m 21s 0
Me ngrohje paraprake 8 sekonda 58 sekonda 25 sekonda 1m 31s -9m 50s


Gjëja kryesore, koha "Deploy" ndryshoi (nga komanda e parë e aplikimit në gjendjen e funksionimit të pods) nga 11m 21s në 25 sekonda. Koha totale ndryshoi nga 11m 21s në 1m 31s.

Një pikë e rëndësishme, nëse nuk ka imazhe bazë nga dega kryesore, atëherë koha "Deploy" do të jetë e njëjtë me kohën origjinale ose pak më shumë. Por gjithsesi, ne zgjidhëm një problem me presionin e diskut dhe kohën e fillimit të ftohtë.


konkluzioni Koha e tërheqjes

Çështja kryesore ContainerCreating u zgjidh nga procesi i ngrohjes. Si përfitim, ne reduktuam ndjeshëm kohën e fillimit të ftohtë të POD-ve.
Presioni i diskut ishte zhdukur, sepse ne kemi tashmë imazhet bazë në nyjet. DaemonSet-et e sistemit janë në një gjendje "të gatshme" dhe "të shëndetshme" (sepse nuk ka presion në disk), dhe nuk kemi hasur në asnjë gabim ErrImagePull në lidhje me këtë problem.


Zgjidhjet dhe lidhjet e mundshme

  • Përdorni rastet për nyjet në vend të
    Ne nuk mund ta përdorim këtë mënyrë, sepse është jashtë fushëveprimit të buxhetit tonë për mjediset joprodhuese.

  • Ne nuk mund ta përdorim këtë mënyrë, sepse kjo veçori është gjithashtu jashtë për shtrirjen e buxhetit tonë për mjediset jo-prodhuese. Për më tepër, AWS ka e IOPS për llogarinë tuaj për rajon.

  • Në fakt ne nuk mund të lëvizim në këtë mënyrë, sepse është një ndikim shumë i lartë në prodhim dhe mjedise të tjera, por është gjithashtu një zgjidhje e mirë për çështjen tonë.

PS: Do të doja t'i shprehja një thirrje ekipit të madh teknik në ( ) për punën e palodhur dhe qasjen vërtet krijuese për çdo problem me të cilin përballen me. Në veçanti, një thirrje për Ronny Sharaby, drejtuesi i shkëlqyer që është përgjegjës për punën e madhe që po bën ekipi. Mezi pres të shoh gjithnjë e më shumë shembuj të shkëlqyer se si krijimtaria juaj ndikon në produktin Justt.


바카라사이트 바카라사이트 온라인바카라