CPU ierobežojumi un agresīva droseles Kubernetes

PiezÄ«me. tulk.: Ŕī Eiropas ceļojumu apkopotāja Omio vēsture, kas atver acis, aizved lasÄ«tājus no pamata teorijas lÄ«dz aizraujoŔām praktiskām Kubernetes konfigurācijas sarežģītÄ«bām. Šādu gadÄ«jumu iepazÄ«Å”ana palÄ«dz ne tikai paplaÅ”ināt redzesloku, bet arÄ« novērst nenozÄ«mÄ«gas problēmas.

CPU ierobežojumi un agresīva droseles Kubernetes

Vai jums kādreiz ir gadÄ«jies, ka lietojumprogramma ir iestrēgusi, pārstāj reaģēt uz veselÄ«bas pārbaudēm un nevarat saprast, kāpēc? Viens no iespējamiem skaidrojumiem ir saistÄ«ts ar CPU resursu kvotu ierobežojumiem. Par to mēs runāsim Å”ajā rakstā.

TL; DR:
Ja izmantojat Linux kodola versiju ar CFS kvotas kļūdu, ļoti iesakām atspējot CPU ierobežojumus programmā Kubernetes (vai atspējot CFS kvotas programmā Kubelet). Kodolā tur ir nopietna un plaÅ”i pazÄ«stams kļūda, kas izraisa pārmērÄ«gu droseli un aizkavÄ“Å”anos
.

Omio pilsētā visu infrastruktÅ«ru pārvalda Kubernetes. Visas mÅ«su statusa un bezpavalstniecÄ«bas darba slodzes darbojas tikai Kubernetes (mēs izmantojam Google Kubernetes Engine). Pēdējo seÅ”u mēneÅ”u laikā mēs sākām novērot nejauÅ”us palēninājumus. Lietojumprogrammas sasalst vai pārstāj reaģēt uz veselÄ«bas pārbaudēm, zaudē savienojumu ar tÄ«klu utt. Šāda uzvedÄ«ba mÅ«s mulsināja ilgu laiku, un beidzot mēs nolēmām Å”o problēmu uztvert nopietni.

Raksta kopsavilkums:

  • Daži vārdi par konteineriem un Kubernetes;
  • Kā tiek Ä«stenoti CPU pieprasÄ«jumi un ierobežojumi;
  • Kā CPU ierobežojums darbojas daudzkodolu vidēs;
  • Kā izsekot CPU droseles;
  • Problēmas risinājums un nianses.

Daži vārdi par konteineriem un Kubernetes

Kubernetes bÅ«tÄ«bā ir mÅ«sdienu standarts infrastruktÅ«ras pasaulē. Tās galvenais uzdevums ir konteineru orÄ·estrÄ“Å”ana.

Konteineri

Agrāk mums bija jāizveido tādi artefakti kā Java JAR/WAR, Python Eggs vai izpildāmie faili, lai tie darbotos serveros. Taču, lai tās funkcionētu, bija jāveic papildu darbi: jāinstalē izpildlaika vide (Java/Python), jāievieto nepiecieÅ”amie faili pareizajās vietās, jānodroÅ”ina savietojamÄ«ba ar konkrētu operētājsistēmas versiju u.c. Citiem vārdiem sakot, rÅ«pÄ«ga uzmanÄ«ba bija jāpievērÅ” konfigurācijas pārvaldÄ«bai (kas bieži bija strÄ«du avots starp izstrādātājiem un sistēmas administratoriem).

Konteineri mainÄ«ja visu. Tagad artefakts ir konteinera attēls. To var attēlot kā sava veida paplaÅ”inātu izpildāmo failu, kurā ir ne tikai programma, bet arÄ« pilnvērtÄ«ga izpildes vide (Java/Python/...), kā arÄ« nepiecieÅ”amie faili/paketes, iepriekÅ” instalētas un gatavas darbam. palaist. Konteinerus var izvietot un palaist dažādos serveros bez papildu darbÄ«bām.

Turklāt konteineri darbojas savā smilÅ”u kastes vidē. Viņiem ir savs virtuālais tÄ«kla adapteris, sava failu sistēma ar ierobežotu piekļuvi, sava procesu hierarhija, savi CPU un atmiņas ierobežojumi utt. Tas viss tiek Ä«stenots, pateicoties Ä«paÅ”ai Linux kodola apakÅ”sistēmai - nosaukumu telpām.

Kubernetes

Kā minēts iepriekÅ”, Kubernetes ir konteineru orÄ·estrētājs. Tas darbojas Ŕādi: jÅ«s pieŔķirat tai maŔīnu kopu un pēc tam sakāt: "Sveika, Kubernetes, palaidÄ«sim desmit mana konteinera gadÄ«jumus ar 2 procesoriem un 3 GB atmiņu katrā, un turpiniet tos darboties!" Par pārējo parÅ«pēsies Kubernetes. Tas atradÄ«s brÄ«vu ietilpÄ«bu, palaidÄ«s konteinerus un vajadzÄ«bas gadÄ«jumā tos restartēs, izlaidÄ«s atjauninājumu, mainot versijas utt. BÅ«tÄ«bā Kubernetes ļauj abstrahēt aparatÅ«ras komponentu un padara dažādas sistēmas piemērotas lietojumprogrammu izvietoÅ”anai un palaiÅ”anai.

CPU ierobežojumi un agresīva droseles Kubernetes
Kubernetes no lajēja viedokļa

Kādi ir Kubernetes pieprasījumi un ierobežojumi

Labi, mēs esam pārklājuÅ”i konteinerus un Kubernetes. Mēs arÄ« zinām, ka vienā maŔīnā var atrasties vairāki konteineri.

Var vilkt analoÄ£iju ar komunālo dzÄ«vokli. PlaÅ”as telpas (maŔīnas/agregāti) tiek paņemtas un izÄ«rētas vairākiem Ä«rniekiem (konteineriem). Kubernetes darbojas kā mākleris. Rodas jautājums, kā atturēt Ä«rniekus no konfliktiem savā starpā? Ko darÄ«t, ja kāds no viņiem, teiksim, nolemj aizņemties vannas istabu uz pusi dienas?

Å eit parādās pieprasÄ«jumi un ierobežojumi. Procesors PieprasÄ«t nepiecieÅ”ams tikai plānoÅ”anas nolÅ«kiem. Tas ir kaut kas lÄ«dzÄ«gs konteinera ā€œvēlmju sarakstamā€, un to izmanto, lai atlasÄ«tu vispiemērotāko mezglu. Tajā paŔā laikā CPU Ierobežot var salÄ«dzināt ar nomas lÄ«gumu - tiklÄ«dz mēs izvēlamies konteinera vienÄ«bu, nevar pārsniedz noteiktos ierobežojumus. Un te arÄ« rodas problēma...

Kā Kubernetes tiek ieviesti pieprasījumi un ierobežojumi

Kubernetes izmanto kodolā iebÅ«vētu droseles mehānismu (izlaižot pulksteņa ciklus), lai ieviestu CPU ierobežojumus. Ja lietojumprogramma pārsniedz ierobežojumu, tiek iespējota drosele (t.i., tā saņem mazāk CPU ciklu). Atmiņas pieprasÄ«jumi un ierobežojumi tiek organizēti atŔķirÄ«gi, tāpēc tos ir vieglāk noteikt. Lai to izdarÄ«tu, vienkārÅ”i pārbaudiet podziņas pēdējo restartÄ“Å”anas statusu: vai tas ir ā€œOOMKilledā€. CPU ierobežoÅ”ana nav tik vienkārÅ”a, jo K8s padara metriku pieejamu tikai pēc lietojuma, nevis pēc cgrupām.

CPU pieprasījums

CPU ierobežojumi un agresīva droseles Kubernetes
Kā tiek īstenots CPU pieprasījums

VienkārŔības labad apskatÄ«sim procesu, kā piemēru izmantojot maŔīnu ar 4 kodolu centrālo procesoru.

K8s izmanto vadÄ«bas grupas mehānismu (cgroups), lai kontrolētu resursu (atmiņas un procesora) pieŔķirÅ”anu. Tam ir pieejams hierarhisks modelis: bērns manto vecāku grupas robežas. IzplatÄ«Å”anas informācija tiek saglabāta virtuālajā failu sistēmā (/sys/fs/cgroup). Procesora gadÄ«jumā tas ir /sys/fs/cgroup/cpu,cpuacct/*.

K8s izmanto failu cpu.share procesora resursu sadalei. MÅ«su gadÄ«jumā saknes cgrupa iegÅ«st 4096 CPU resursu daļas - 100% no pieejamās procesora jaudas (1 kodols = 1024; tā ir fiksēta vērtÄ«ba). Sakņu grupa sadala resursus proporcionāli atkarÄ«bā no reÄ£istrēto pēcnācēju daļām cpu.share, un viņi, savukārt, dara to paÅ”u ar saviem pēcnācējiem utt. Tipiskā Kubernetes mezglā saknes cgrupai ir trÄ«s bērni: system.slice, user.slice Šø kubepods. Pirmās divas apakÅ”grupas tiek izmantotas, lai sadalÄ«tu resursus starp kritiskajām sistēmas slodzēm un lietotāju programmām ārpus K8s. Pēdējais - kubepods ā€” izveidojis Kubernetes, lai sadalÄ«tu resursus starp podiem.

IepriekÅ” redzamā diagramma parāda, ka pirmā un otrā apakÅ”grupa saņēma katru 1024 akcijas, pieŔķirot kuberpod apakÅ”grupu 4096 akcijas Kā tas ir iespējams: galu galā saknes grupai ir piekļuve tikai 4096 akcijas, un viņas pēcnācēju daļu summa ievērojami pārsniedz Å”o skaitli (6144)? Lieta ir tāda, ka vērtÄ«bai ir loÄ£iska nozÄ«me, tāpēc Linux plānotājs (CFS) to izmanto, lai proporcionāli sadalÄ«tu CPU resursus. MÅ«su gadÄ«jumā saņem pirmās divas grupas 680 reālās akcijas (16,6% no 4096), un kubepod saņem atlikuÅ”o daļu 2736 akcijas DÄ«kstāves gadÄ«jumā pirmās divas grupas neizmantos pieŔķirtos resursus.

Par laimi, plānotājam ir mehānisms, kas ļauj izvairÄ«ties no neizmantoto CPU resursu izŔķērdÄ“Å”anas. Tas pārsÅ«ta ā€œdÄ«kstāvesā€ jaudu uz globālo kopu, no kuras tā tiek sadalÄ«ta grupām, kurām nepiecieÅ”ama papildu procesora jauda (pārsÅ«tÄ«Å”ana notiek pa partijām, lai izvairÄ«tos no noapaļoÅ”anas zudumiem). LÄ«dzÄ«ga metode tiek piemērota visiem pēcnācēju pēcnācējiem.

Å is mehānisms nodroÅ”ina taisnÄ«gu procesora jaudas sadali un nodroÅ”ina, ka neviens process ā€œnezogā€ resursus no citiem.

CPU ierobežojums

Neskatoties uz to, ka ierobežojumu un pieprasÄ«jumu konfigurācijas K8s izskatās lÄ«dzÄ«gi, to ievieÅ”ana ir radikāli atŔķirÄ«ga: Ŕī visvairāk maldinoÅ”s un vismazāk dokumentētā daļa.

K8s iesaistās CFS kvotu mehānisms ieviest ierobežojumus. To iestatÄ«jumi ir norādÄ«ti failos cfs_period_us Šø cfs_quota_us cgroup direktorijā (fails atrodas arÄ« tur cpu.share).

Pretēji cpu.share, kvota ir balstÄ«ta uz laika periods, nevis ar pieejamo procesora jaudu. cfs_period_us norāda perioda (epoha) ilgumu - tas vienmēr ir 100000 Ī¼s (100 ms). Ir iespēja mainÄ«t Å”o vērtÄ«bu K8s, taču pagaidām tā ir pieejama tikai alfa versijā. Plānotājs izmanto laikmetu, lai restartētu izmantotās kvotas. Otrais fails cfs_quota_us, norāda pieejamo laiku (kvotu) katrā laikmetā. Ņemiet vērā, ka tas ir norādÄ«ts arÄ« mikrosekundēs. Kvota var pārsniegt laikmeta garumu; citiem vārdiem sakot, tas var bÅ«t lielāks par 100 ms.

Apskatīsim divus scenārijus 16 kodolu iekārtās (visbiežāk Omio datoros):

CPU ierobežojumi un agresīva droseles Kubernetes
1. scenārijs: 2 pavedieni un 200 ms ierobežojums. Bez droseles

CPU ierobežojumi un agresīva droseles Kubernetes
2. scenārijs: 10 pavedieni un 200 ms ierobežojums. Droseļkontrole sākas pēc 20 ms, piekļuve procesora resursiem tiek atsākta pēc vēl 80 ms

Pieņemsim, ka esat iestatÄ«jis CPU ierobežojumu 2 kodoli; Kubernetes pārtulkos Å”o vērtÄ«bu uz 200 ms. Tas nozÄ«mē, ka konteiners var izmantot ne vairāk kā 200 ms CPU laika bez droseles.

Un Å”eit sākas jautrÄ«ba. Kā minēts iepriekÅ”, pieejamā kvota ir 200 ms. Ja strādājat paralēli desmit pavedieni 12 kodolu maŔīnā (skatiet 2. scenārija ilustrāciju), kamēr visi pārējie podi ir dÄ«kstāvē, kvota tiks izsmelta tikai 20 ms (kopÅ” 10 * 20 ms = 200 ms), un visi Ŕī aplikuma pavedieni uzkarās. Ā» (drosele) nākamajām 80 ms. Jau pieminētais plānotāja kļūda, kuras dēļ notiek pārmērÄ«ga drosele un konteiners pat nevar izpildÄ«t esoÅ”o kvotu.

Kā novērtēt droselÄ“Å”anu pākstÄ«s?

VienkārŔi piesakieties podā un izpildiet cat /sys/fs/cgroup/cpu/cpu.stat.

  • nr_periods ā€” kopējais plānotāja periodu skaits;
  • nr_throttled ā€” droseles periodu skaits kompozÄ«cijā nr_periods;
  • throttled_time ā€” kumulatÄ«vais droseles laiks nanosekundēs.

CPU ierobežojumi un agresīva droseles Kubernetes

Kas Ä«sti notiek?

Rezultātā mēs iegÅ«stam augstu droseli visās lietojumprogrammās. Dažreiz viņŔ ir iekŔā pusotru reizi spēcÄ«gāks nekā aprēķināts!

Tas noved pie dažādām kļūdām ā€“ gatavÄ«bas pārbaudes kļūmēm, konteineru sasalÅ”anas, tÄ«kla savienojuma pārtraukumiem, taimautiem servisa zvanu ietvaros. Tas galu galā palielina latentumu un lielāku kļūdu lÄ«meni.

Lēmums un sekas

Å eit viss ir vienkārÅ”i. Mēs atteicāmies no CPU ierobežojumiem un sākām atjaunināt OS kodolu klasteros uz jaunāko versiju, kurā kļūda tika novērsta. Kļūdu skaits (HTTP 5xx) mÅ«su pakalpojumos nekavējoties ievērojami samazinājās:

HTTP 5xx kļūdas

CPU ierobežojumi un agresīva droseles Kubernetes
HTTP 5xx kļūdas vienam kritiskam pakalpojumam

Reakcijas laiks p95

CPU ierobežojumi un agresīva droseles Kubernetes
Kritiskā pakalpojuma pieprasÄ«juma latentums, 95. procentile

Ekspluatācijas izmaksas

CPU ierobežojumi un agresīva droseles Kubernetes
Iztērēto gadījumu stundu skaits

Kāda ir nozveja?

Kā teikts raksta sākumā:

Var vilkt analoģiju ar komunālo dzīvokli... Kubernetes darbojas kā mākleris. Bet kā atturēt īrniekus no konfliktiem savā starpā? Ko darīt, ja kāds no viņiem, teiksim, nolemj aizņemties vannas istabu uz pusi dienas?

LÅ«k, nozveja. Viens neuzmanÄ«gs konteiners var apēst visus maŔīnā pieejamos CPU resursus. Ja jums ir viedā lietojumprogrammu steks (piemēram, JVM, Go, Node VM ir pareizi konfigurēti), tad tā nav problēma: jÅ«s varat strādāt Ŕādos apstākļos ilgu laiku. Bet, ja lietojumprogrammas ir slikti optimizētas vai nav optimizētas vispār (FROM java:latest), situācija var kļūt nekontrolējama. Uzņēmumā Omio mums ir automatizēti bāzes Docker faili ar atbilstoÅ”iem noklusējuma iestatÄ«jumiem galvenajai valodu steksai, tāpēc Ŕī problēma nepastāvēja.

Mēs iesakām pārraudzÄ«t rādÄ«tājus LIETOÅ ANAS (lietoÅ”ana, piesātinājums un kļūdas), API aizkaves un kļūdu lÄ«menis. Pārliecinieties, ka rezultāti atbilst cerÄ«bām.

atsauces

Å is ir mÅ«su stāsts. SekojoÅ”ie materiāli ļoti palÄ«dzēja saprast, kas notiek:

Kubernetes kļūdu ziņojumi:

Vai esat saskāries ar lÄ«dzÄ«gām problēmām savā praksē vai jums ir pieredze saistÄ«bā ar droseles izmantoÅ”anu konteinerizētās ražoÅ”anas vidēs? Dalies ar savu stāstu komentāros!

PS no tulka

Lasi arī mūsu emuārā:

Avots: www.habr.com

Pievieno komentāru