Kubernetes: Zrýchlite svoje služby odstránením limitov CPU

V roku 2016 sme v Buffer prešiel na Kubernetesa teraz asi 60 uzlov (na AWS) a 1500 kontajnerov pracuje na našom klastri k8s, ktorý spravuje kopnúť. K mikroslužbám sme však prešli metódou pokus-omyl a aj po niekoľkých rokoch práce s k8 sa stále stretávame s novými problémami. V tomto príspevku budeme hovoriť o obmedzenia procesora: prečo sme si mysleli, že sú to dobré praktiky a prečo nakoniec neboli také dobré.

Obmedzenia procesora a škrtenie

Rovnako ako mnoho iných používateľov Kubernetes, Google dôrazne odporúča nastaviť limity CPU. Bez takéhoto nastavenia môžu kontajnery v uzle zaberať celý výkon procesora, čo následne spôsobuje dôležité procesy Kubernetes (napr. kubelet) prestane reagovať na požiadavky. Preto je nastavenie limitov CPU dobrým spôsobom, ako chrániť vaše uzly.

Limity procesora nastavujú kontajner na maximálny čas procesora, ktorý môže použiť na určité obdobie (predvolená hodnota je 100 ms) a kontajner tento limit nikdy neprekročí. V Kubernetes pre škrtenie kontajnera a zabrániť jeho prekročeniu limitu, použije sa špeciálny nástroj Kvóta CFS, ale tieto umelé limity CPU nakoniec zhoršia výkon a zvýšia čas odozvy vašich kontajnerov.

Čo sa môže stať, ak nenastavíme limity na procesor?

Žiaľ, tomuto problému sme museli čeliť aj my sami. Každý uzol má proces zodpovedný za správu kontajnerov kubeleta prestal reagovať na žiadosti. Uzol, keď sa to stane, prejde do stavu NotReadya kontajnery z neho budú presmerované niekam inam a budú vytvárať rovnaké problémy na nových uzloch. Nie je to prinajmenšom ideálny scenár.

Prejavenie problému škrtenia a odozvy

Kľúčovou metrikou pre sledovanie kontajnerov je trottling, ukazuje, koľkokrát bol váš kontajner priškrtený. So záujmom sme si všimli prítomnosť throttlingu v niektorých kontajneroch bez ohľadu na to, či bola záťaž procesora extrémna alebo nie. Ako príklad sa pozrime na jedno z našich hlavných rozhraní API:

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU

Ako môžete vidieť nižšie, limit sme nastavili na 800m (0.8 alebo 80 % jadra) a špičkové hodnoty pri najlepšom dosahu 200m (20% jadro). Zdalo by sa, že pred obmedzením služby máme stále dostatok výkonu procesora, ale...

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU
Možno ste si všimli, že aj keď je zaťaženie procesora pod stanovenými limitmi – výrazne pod – stále dochádza k škrteniu.

Vzhľadom na to sme čoskoro objavili niekoľko zdrojov (problém na githube, prezentácia na zadano, príspevok na omio) o poklese výkonu a času odozvy služieb v dôsledku škrtenia.

Prečo vidíme škrtenie pri nízkom zaťažení procesora? Krátka verzia znie: „v jadre Linuxu je chyba, ktorá spôsobuje zbytočné obmedzovanie kontajnerov so špecifikovanými limitmi procesora.“ Ak vás zaujíma povaha problému, môžete si prečítať prezentáciu (video и text možnosti) od Davea Chiluka.

Odstránenie obmedzení CPU (s mimoriadnou opatrnosťou)

Po dlhých diskusiách sme sa rozhodli odstrániť obmedzenia týkajúce sa procesora zo všetkých služieb, ktoré priamo alebo nepriamo ovplyvňovali kritické funkcie pre našich používateľov.

Rozhodnutie nebolo jednoduché, pretože si vysoko ceníme stabilitu nášho klastra. V minulosti sme už experimentovali s nestabilitou nášho klastra a vtedy služby spotrebovali príliš veľa zdrojov a spomalili prácu celého ich uzla. Teraz bolo všetko trochu inak: mali sme jasnú predstavu o tom, čo očakávame od našich klastrov, ako aj dobrú stratégiu implementácie plánovaných zmien.

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU
Obchodná korešpondencia o naliehavej otázke.

Ako chrániť svoje uzly pri zrušení obmedzení?

Izolácia „neobmedzených“ služieb:

V minulosti sme už videli, ako sa niektoré uzly dostali do stavu notReady, predovšetkým kvôli službám, ktoré spotrebovali príliš veľa zdrojov.

Rozhodli sme sa umiestniť takéto služby do samostatných („označených“) uzlov, aby nezasahovali do „súvisiacich“ služieb. V dôsledku toho sme označením niektorých uzlov a pridaním parametra tolerancie k „nesúvisiacim“ službám dosiahli väčšiu kontrolu nad klastrom a bolo pre nás jednoduchšie identifikovať problémy s uzlami. Ak chcete vykonať podobné procesy sami, môžete sa s nimi zoznámiť dokumentáciu.

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU

Priradenie správnej požiadavky na procesor a pamäť:

Náš najväčší strach bol, že proces spotrebuje príliš veľa zdrojov a uzol prestane reagovať na požiadavky. Keďže sme teraz (vďaka Datadogu) mohli prehľadne monitorovať všetky služby na našom klastri, analyzoval som niekoľko mesiacov fungovania tých, ktoré sme plánovali označiť ako „nesúvisiace“. Jednoducho nastavím maximálne využitie CPU s rezervou 20% a tým pridelím miesto v uzle pre prípad, že by sa k8s pokúsil uzlu priradiť iné služby.

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU

Ako môžete vidieť na grafe, maximálne zaťaženie procesora dosiahlo 242m jadrá CPU (0.242 jadier procesora). Pre požiadavku procesora stačí zobrať číslo o niečo väčšie ako je táto hodnota. Upozorňujeme, že keďže sú služby zamerané na používateľa, hodnoty maximálneho zaťaženia sa zhodujú s návštevnosťou.

Urobte to isté s využitím pamäte a dopytmi a voila - všetko je nastavené! Pre väčšiu bezpečnosť môžete pridať horizontálne automatické škálovanie pod. Preto zakaždým, keď je zaťaženie zdrojov vysoké, automatické škálovanie vytvorí nové moduly a kubernetes ich rozdelí do uzlov s voľným priestorom. V prípade, že v samotnom klastri nezostane miesto, môžete si nastaviť upozornenie alebo nakonfigurovať pridávanie nových uzlov prostredníctvom ich automatického škálovania.

Z mínusov stojí za zmienku, že sme prehrali v „hustota nádoby“, t.j. počet kontajnerov bežiacich na jednom uzle. Môžeme mať tiež veľa „relaxácií“ pri nízkej hustote prevádzky a je tu tiež šanca, že dosiahnete vysoké zaťaženie procesora, ale s tým druhým by mali pomôcť uzly automatického škálovania.

výsledky

Som rád, že môžem zverejniť tieto vynikajúce výsledky z experimentov za posledných niekoľko týždňov; už sme zaznamenali výrazné zlepšenia odozvy vo všetkých upravených službách:

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU

Najlepšie výsledky sme dosiahli na našej domovskej stránke (buffer.com), tam sa služba zrýchlila dvadsaťdvakrát!

Kubernetes: Zrýchlite svoje služby odstránením limitov CPU

Je chyba linuxového jadra opravená?

Áno, Chyba už bola opravená a oprava bola pridaná do jadra distribúcie verzie 4.19 a vyššej.

Avšak pri čítaní problémy kubernetes na github na druhý september 2020 stále sa stretávame so zmienkami o niektorých linuxových projektoch s podobnou chybou. Domnievam sa, že niektoré linuxové distribúcie stále majú túto chybu a práve pracujú na jej odstránení.

Ak je vaša verzia distribúcie nižšia ako 4.19, odporúčam aktualizáciu na najnovšiu, ale v každom prípade by ste sa mali pokúsiť odstrániť obmedzenia procesora a zistiť, či škrtenie pretrváva. Nižšie si môžete pozrieť čiastočný zoznam služieb správy Kubernetes a distribúcií Linuxu:

  • Debian: oprava integrovaná do najnovšej verzie distribúcie, bustersa vyzerá celkom sviežo (Augusta 2020). Niektoré predchádzajúce verzie môžu byť tiež opravené.
  • Ubuntu: oprava integrovaná do najnovšej verzie Ubuntu Focal Fossa 20.04
  • EKS má ešte opravu v decembri 2019. Ak je vaša verzia nižšia ako táto, mali by ste aktualizovať AMI.
  • kopy: Od júna 2020 у kops 1.18+ Hlavným hostiteľským obrazom bude Ubuntu 20.04. Ak je vaša verzia kops staršia, možno budete musieť počkať na opravu. My sami teraz čakáme.
  • GKE (Google Cloud): Oprava integrovaná v januári 2020, sú však problémy s škrtením sa stále dodržiavajú.

Čo robiť, ak oprava vyriešila problém s škrtením?

Nie som si istý, či je problém úplne vyriešený. Keď sa dostaneme k verzii jadra s opravou, otestujem klaster a aktualizujem príspevok. Ak už niekto aktualizoval, rád by som si prečítal vaše výsledky.

Záver

  • Ak pracujete s kontajnermi Docker pod Linuxom (bez ohľadu na Kubernetes, Mesos, Swarm alebo iné), vaše kontajnery môžu stratiť výkon v dôsledku obmedzovania;
  • Skúste aktualizovať na najnovšiu verziu svojej distribúcie v nádeji, že chyba už bola opravená;
  • Odstránenie limitov procesora problém vyrieši, ide však o nebezpečnú techniku, ktorá by sa mala používať s mimoriadnou opatrnosťou (je lepšie najskôr aktualizovať jadro a porovnať výsledky);
  • Ak ste odstránili limity procesora, pozorne sledujte využitie procesora a pamäte a uistite sa, že zdroje procesora prekračujú vašu spotrebu;
  • Bezpečnou možnosťou by bolo automatické škálovanie modulov na vytvorenie nových modulov v prípade vysokej hardvérovej záťaže, aby ich kubernetes priradil k voľným uzlom.

Dúfam, že vám tento príspevok pomôže zlepšiť výkon vašich kontajnerových systémov.

PS Tu autor korešponduje s čitateľmi a komentátormi (v angličtine).


Zdroj: hab.com

Pridať komentár