paint-brush
Ako optimalizovať Kubernetes pre veľké obrázky Dockerpodľa@kksudo
Nová história

Ako optimalizovať Kubernetes pre veľké obrázky Docker

podľa Kazakov Kirill10m2024/09/30
Read on Terminal Reader

Príliš dlho; Čítať

🚀 Čarodejníci Kubernetes, už vás nebaví hodiny čakať, kým sa vaše uzly zahrejú? Predstavte si, že by ste ten čas skrátili na pár sekúnd! Tento článok, ktorý mení hru, odhaľuje, ako prebiť váš proces nasadenia Kubernetes, dokonca aj s obrovskými 3 GB obrázkami a 1 000 modulmi. Objavte tajnú omáčku, ktorá premení výkon vášho klastra z pomalého na nadzvukový. Nenechajte sa brzdiť pomalým zahrievaním – naučte sa, ako zmeniť svoj pracovný postup Kubernetes ešte dnes!
featured image - Ako optimalizovať Kubernetes pre veľké obrázky Docker
Kazakov Kirill HackerNoon profile picture
0-item

Stručný prehľad problému

Jedného dňa sme počas plánovanej aktualizácie klastra k8s zistili, že takmer všetky naše PODy (približne 500 z 1 000) na nových uzloch sa nedali spustiť a minúty sa rýchlo zmenili na hodiny. Aktívne pátrame po hlavnej príčine, ale po troch hodinách boli PODS stále v stave ContainerCreating .


Kubernetes sa zasekol na ContainerCreating

Našťastie to nebolo produkčné prostredie a obdobie údržby bolo naplánované na víkend. Mali sme čas na prešetrenie problému bez akéhokoľvek tlaku.

Kde by ste mali začať hľadať hlavnú príčinu? Chceli by ste sa dozvedieť viac o riešení, ktoré sme našli? Pripútajte sa a užívajte si!

Viac podrobností o probléme

Problém bol v tom, že sme mali veľké množstvo obrázkov dockerov, ktoré bolo potrebné stiahnuť a spustiť na každom uzle v klastri súčasne. Dôvodom bolo, že viacero súbežných stiahnutí obrazu dokovacieho zariadenia na jednom uzle môže viesť k vysokému využitiu disku a predĺženiu doby studeného štartu.


Procesu CD trvá z času na čas až 3 hodiny, kým sa stiahnu obrázky. Tentoraz sa to však úplne zaseklo, pretože množstvo PODS počas upgradu EKS (inline, keď vymeníme všetky uzly v klastri) bolo príliš vysoké.


  • Všetky naše aplikácie fungujú v k8s (založené na EKS ). Aby sme ušetrili naše náklady na DEV env, používame spotové inštancie.

  • Pre uzly používame obraz AmazonLinux2 .

  • Vo vývojovom prostredí máme veľké množstvo funkčných pobočiek (FB), ktoré sú neustále nasadzované do nášho klastra Kubernetes. Každý FB má svoju vlastnú sadu aplikácií a každá aplikácia má svoju vlastnú sadu závislostí (vo vnútri obrázka).

  • V našom projekte je takmer 200 aplikácií a toto číslo rastie. Každá aplikácia používa jeden zo 7 základných obrázkov doku s veľkosťou ~2 GB. Maximálna celková veľkosť archivovaného obrázka (v pokladnici ) je približne 3 GB.

  • Všetky obrázky sú uložené v registri Amazon Elastic Container Registry (ECR).

  • Pre uzly používame predvolený typ zväzku gp3 EBS.


Problémy

  • Predĺžený čas studeného štartu: Spustenie nového modulu s novým obrázkom môže trvať viac ako 1 hodinu, najmä ak sa na jednom uzle vytiahne viacero obrázkov súčasne.

  • Chyby ErrImagePull: Časté ErrImagePull alebo uviaznutie v stave ContainerCreating , čo naznačuje problémy s načítaním obrázka.

  • Vysoké využitie disku: Využitie disku zostáva počas procesu sťahovania obrazu takmer 100 %, predovšetkým kvôli intenzívnym vstupom/výstupom disku potrebným na dekompresiu (napr. „unpigz“).

  • Problémy s DaemonSet systému: Niektoré systémové DaemonSets (ako aws-node alebo ebs-csi-node ) sa presunuli do stavu „nepripravený“ kvôli tlaku disku, čo má vplyv na pripravenosť uzla.

  • Žiadna vyrovnávacia pamäť obrázkov na uzloch: Pretože používame bodové inštancie, nemôžeme použiť lokálny disk na ukladanie obrázkov do vyrovnávacej pamäte.


To vedie k mnohým zastaveným nasadeniam na vetvách funkcií, najmä preto, že rôzne FB majú rozdielne sady základných obrázkov.

Po rýchlom skúmaní sme zistili, že hlavným problémom bol tlak disku na uzly procesom unpigz . Tento proces je zodpovedný za dekompresiu obrázkov doku. Predvolené nastavenia pre typ hlasitosti gp3 EBS sme nemenili, pretože to nie je vhodné pre náš prípad.


Rýchla oprava na obnovenie klastra

Ako prvý krok sme sa rozhodli znížiť počet PODov na uzloch.

  1. Nové uzly presunieme do stavu „Cordon“.
  2. Odstráňte všetky zaseknuté PODS, aby ste znížili tlak disku
  3. Spúšťajte jeden po druhom PODy, aby ste zahriali uzly
  4. Potom presunieme zahriate uzly do normálneho stavu („unCordon“)
  5. Odstránili sa všetky uzly v zaseknutom stave
  6. Všetky PODS sa úspešne spustili pomocou vyrovnávacej pamäte obrázkov Docker


Originálny dizajn CI/CD

Hlavnou myšlienkou riešenia je zahriať uzly pred spustením procesu CD najväčšou časťou obrazu dockeru (vrstva závislostí JS), ktorá sa používa ako koreňový obraz pre všetky naše aplikácie. Máme aspoň 7 typov koreňových obrázkov so závislosťami JS, ktoré súvisia s typom aplikácie. Poďme teda analyzovať pôvodný dizajn CI/CD.


V našom potrubí CI/CD máme 3 piliere: Originálny CI/CD kanál

Originálny kanál CI/CD:

  1. V kroku Init it: pripravíme prostredie/premenné, definujeme sadu obrázkov na prebudovanie atď...

  2. V kroku Build : vytvoríme obrázky a pošleme ich do pokladne

  3. V kroku Deploy : nasadíme obrázky do k8 (aktualizácia nasadení atď.)


Viac podrobností o pôvodnom dizajne CICD:

  • Naše hlavné pobočky (FB) sa rozdelili z main pobočky. V procese CI vždy analyzujeme množinu obrázkov, ktoré boli zmenené na FB a prestavujeme ich. main vetva je vždy stabilná, pretože definícia by mala byť vždy najnovšia verzia základných obrázkov.
  • Samostatne vytvárame obrázky dokovacích staníc závislostí JS (pre každé prostredie) a posielame ich do ECR, aby sme ich znova použili ako koreňový (základný) obrázok v súbore Dockerfile. Máme približne 5 až 10 typov dokovacieho obrazu závislostí JS.
  • FB je nasadený do klastra k8s do samostatného menného priestoru, ale do spoločných uzlov pre FB. FB môže mať ~200 aplikácií s veľkosťou obrázka do 3 GB.
  • Máme klastrový autoscaling systém, ktorý škáluje uzly v klastri na základe zaťaženia alebo čakajúcich PODS s príslušným nodeSelector a toleranciou.
  • Pre uzly používame bodové inštancie.

Realizácia procesu zahrievania

Existujú požiadavky na proces zahrievania.

Povinné:

  1. Riešenie problémov : Rieši a rieši problémy ContainerCreating .
  2. Vylepšený výkon : Výrazne znižuje čas spustenia pomocou predhriatych základných obrazov (závislosti JS).

Je pekné mať vylepšenia:

  1. Flexibilita : Umožňuje jednoduché zmeny typu uzla a jeho životnosti (napr. vysoká SLA alebo predĺžená doba životnosti).
  2. Transparentnosť : Poskytuje jasné metriky používania a výkonu.
  3. Efektivita nákladov : Šetrí náklady odstránením VNG ihneď po odstránení súvisiacej vetvy funkcií.
  4. Izolácia : Tento prístup zaisťuje, že iné prostredia nebudú ovplyvnené.

Riešenie

Po analýze požiadaviek a obmedzení sme sa rozhodli implementovať proces zahrievania, ktorý by predhrieval uzly so základnými obrázkami vyrovnávacej pamäte JS. Tento proces by sa spustil pred spustením procesu CD, čím sa zabezpečí, že uzly sú pripravené na nasadenie FB a máme maximálnu šancu zasiahnuť do vyrovnávacej pamäte.


Toto zlepšenie sme rozdelili do troch veľkých krokov:

  1. Vytvorte množinu uzlov (skupinu virtuálnych uzlov) pre každý FB

  2. Pridajte základné obrázky do skriptu cloud-init pre nové uzly

  3. Pridajte krok pred nasadením na spustenie DaemonSet so sekciou initContainers , aby ste si stiahli potrebné obrazy dokovacích staníc do uzlov pred spustením procesu CD.


Aktualizovaný kanál CI/CD by vyzeral takto: Aktualizovaný kanál CI/CD


Aktualizovaný kanál CI/CD:

  1. Úvodný krok
    1.1. (nový krok) Init deploy : Ak ide o prvé spustenie FB, potom vytvorte novú osobnú sadu inštancií uzla (v našich podmienkach je to skupina Virtual Node Group alebo VNG) a stiahnite si všetky základné obrázky JS (5–10 obrázkov ) z hlavnej pobočky. Je to dosť fér, pretože sme FB forkovali z hlavnej pobočky. Dôležitý bod, nie je to blokovacia operácia.
  2. Stavať krok
  3. Krok pred nasadením Stiahnite si čerstvo upečené základné obrázky JS so špecifickým FB tagom z ECR.
    3.1.(nový krok) Dôležité body : Je to blokovacia operácia, pretože by sme mali znížiť tlak disku. Jeden po druhom stiahneme základné obrázky pre každý súvisiaci uzol.
    Btw, vďaka za krok „ init deploy“ , už máme základné obrázky dockerov z hlavnej vetvy, čo nám dáva veľkú šancu zasiahnuť do vyrovnávacej pamäte pri prvom spustení.
  4. **Nasadenie
    **V tomto kroku nie sú žiadne zmeny. Ale vďaka predchádzajúcemu kroku už máme všetky ťažké vrstvy obrázkov dockerov na potrebných uzloch.

Krok nasadenia

Vytvorte novú množinu uzlov pre každý FB prostredníctvom volania API (do systému automatického škálovania tretej strany) z nášho kanála CI.


Vyriešené problémy:

  1. Izolácia : Každý FB má svoj vlastný súbor uzlov, ktorý zabezpečuje, že prostredie nie je ovplyvnené inými FB.

  2. Flexibilita : Môžeme ľahko zmeniť typ uzla a jeho životnosť.

  3. Efektivita nákladov : Uzly môžeme vymazať ihneď po vymazaní FB.

  4. Transparentnosť : Môžeme ľahko sledovať využitie a výkon uzlov (každý uzol má značku súvisiacu s FB).

  5. Efektívne využitie inštancií spotu : Inštancia spotu začína s už preddefinovanými základnými obrázkami, to znamená, že po spustení bodového uzla sú na uzle už základné obrázky (z hlavnej vetvy).


Stiahnite si všetky základné obrázky JS z hlavnej vetvy do nových uzlov pomocou cloud-init skriptu.


Zatiaľ čo sa obrázky sťahujú na pozadí, proces CD môže pokračovať v vytváraní nových obrázkov bez akýchkoľvek problémov. Okrem toho budú ďalšie uzly (ktoré budú vytvorené systémom automatického škálovania) z tejto skupiny vytvorené s aktualizovanými údajmi cloud-init , ktoré už majú pokyny na stiahnutie obrázkov pred spustením.


Vyriešené problémy:

  1. Riešenie problému : Tlak na disk je preč, pretože sme aktualizovali skript cloud-init pridaním sťahovania základných obrázkov z hlavnej pobočky. To nám umožňuje trafiť cache pri prvom spustení FB.

  2. Efektívne využitie inštancií spotu : Inštancia spotu začína s aktualizovanými údajmi cloud-init . To znamená, že po spustení bodového uzla sú na uzle už základné obrázky (z hlavnej vetvy).

  3. Vylepšený výkon : Proces CD môže pokračovať v vytváraní nových obrazov bez akýchkoľvek problémov.


Táto akcia pridala ~17 sekúnd (volanie API) do nášho kanála CI/CD.

Táto akcia dáva zmysel len prvýkrát, keď spustíme FB. Nabudúce nasadíme naše aplikácie do už existujúcich uzlov, ktoré už majú základné obrázky, ktoré sme dodali pri predchádzajúcom nasadení.

Krok pred nasadením

Tento krok potrebujeme, pretože obrázky FB sa líšia od obrázkov hlavnej pobočky. Pred spustením procesu CD musíme stiahnuť základné obrázky FB do uzlov. Pomôže to zmierniť predĺžené časy studeného štartu a vysoké využitie disku, ktoré môže nastať, keď sa súčasne stiahne viacero ťažkých obrazov.


Ciele kroku pred nasadením

  1. Zabráňte tlaku disku : Postupne sťahujte najťažšie obrázky dokovacieho zariadenia. Po kroku init-deploy už máme základné obrázky na uzloch, čo znamená, že máme veľkú šancu na nájdenie cache.

  2. Zlepšite efektivitu nasadenia : Zaistite, aby boli uzly predhriate základnými obrázkami dokovacieho zariadenia, čo vedie k rýchlejšiemu (takmer okamžite) spusteniu zariadenia POD.

  3. Vylepšenie stability : Minimalizujte pravdepodobnosť výskytu chýb ErrImagePull / ContainerCreating a zabezpečte, aby sady systémových démonov zostali v stave „pripravenosti“.


V rámci tohto kroku pridáme k procesu CD 10–15 minút.

Podrobnosti o kroku pred nasadením:

  • Na CD vytvoríme DaemonSet so sekciou initContainers .
  • Sekcia initContainers sa spustí pred spustením hlavného kontajnera, čím sa zabezpečí, že sa potrebné obrázky stiahnu pred spustením hlavného kontajnera.
  • Na CD priebežne kontrolujeme stav daemonSet. Ak je daemonSet v stave „pripravený“, pokračujeme v nasadení. V opačnom prípade počkáme, kým bude sada démonov pripravená.

Porovnanie

Porovnanie pôvodných a aktualizovaných krokov s procesom predhrievania.

Krok

Krok nasadenia

Krok pred nasadením

Nasadiť

Celkový čas

Dif

Bez predohrevu

0

0

11 m 21 s

11 m 21 s

0

S predhrievaním

8 sekúnd

58 sekúnd

25 sekúnd

1 m 31 s

-9m 50s


Hlavná vec je, že čas „Deploy“ sa zmenil (z prvého príkazu na použitie do stavu Spustenia modulov) z 11 m 21 s na 25 sekúnd. Celkový čas sa zmenil z 11m 21s na 1m 31s.

Dôležitý bod, ak neexistujú žiadne základné obrázky z hlavnej vetvy, čas „nasadenia“ bude rovnaký ako pôvodný čas alebo o niečo viac. Ale aj tak sme vyriešili problém s tlakom disku a časom studeného štartu.


Záver Čas ťahania

Hlavný problém ContainerCreating bol vyriešený procesom zahrievania. Ako výhodu sme výrazne skrátili čas studeného štartu PODov.
Tlak disku bol preč, pretože už máme základné obrázky na uzloch. Systémové sady démonov sú v „pripravenom“ a „zdravom“ stave (pretože nie je žiadny tlak na disk) a nezaznamenali sme žiadne chyby ErrImagePull súvisiace s týmto problémom.


Možné riešenia a odkazy


PS: Chcel by som poďakovať skvelému technickému tímu v Justt ( https://www.linkedin.com/company/justt-ai ) za neúnavnú prácu a skutočne kreatívny prístup k akémukoľvek problému, ktorému čelia s Najmä pokrik Ronnymu Sharabymu, vynikajúcemu lídrovi, ktorý je zodpovedný za skvelú prácu, ktorú tím odvádza. Teším sa na ďalšie a ďalšie skvelé príklady toho, ako vaša kreativita ovplyvňuje produkt Justt.