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.
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.
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
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):
1. scenÄrijs: 2 pavedieni un 200 ms ierobežojums. Bez droseles
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.
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:
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:
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!