CPU takmörk og árásargjarn inngjöf í Kubernetes

Athugið. þýð.: Þessi augnayndi saga Omio – evrópsks ferðasafnara – tekur lesendur frá grunnkenningum að heillandi hagnýtu flækjum Kubernetes uppsetningar. Þekking á slíkum tilfellum hjálpar ekki aðeins að víkka sjóndeildarhringinn heldur einnig koma í veg fyrir óléttvæg vandamál.

CPU takmörk og árásargjarn inngjöf í Kubernetes

Hefur þú einhvern tíma lent í því að umsókn festist á sínum stað, hættir að bregðast við heilbrigðiseftirliti og getur ekki fundið út hvers vegna? Ein möguleg skýring er tengd takmörkunum á örgjörvaauðlindakvóta. Þetta er það sem við munum tala um í þessari grein.

TL; DR:
Við mælum eindregið með því að slökkva á CPU takmörkunum í Kubernetes (eða slökkva á CFS kvóta í Kubelet) ef þú ert að nota útgáfu af Linux kjarnanum með CFS kvóta villu. Í kjarnanum það er alvarleg og vel þekkt galla sem leiðir til of mikillar inngjafar og tafa
.

Í Omio öllu innviði er stjórnað af Kubernetes. Allt okkar opinbera og ríkisfangslausa vinnuálag keyrir eingöngu á Kubernetes (við notum Google Kubernetes Engine). Á síðustu sex mánuðum fórum við að fylgjast með tilviljunarkenndum hægagangi. Forrit frýs eða hætta að svara heilsufarsskoðunum, missa tengingu við netið o.s.frv. Þessi hegðun vakti mikla athygli hjá okkur í langan tíma og loks ákváðum við að taka vandann alvarlega.

Samantekt greinarinnar:

  • Nokkur orð um gáma og Kubernetes;
  • Hvernig CPU beiðnir og takmarkanir eru útfærðar;
  • Hvernig CPU takmörk virka í fjölkjarna umhverfi;
  • Hvernig á að fylgjast með inngjöf CPU;
  • Vandamálslausn og blæbrigði.

Nokkur orð um gáma og Kubernetes

Kubernetes er í raun nútíma staðall í innviðaheiminum. Meginverkefni þess er gámahljómsveit.

Ílát

Í fortíðinni þurftum við að búa til gripi eins og Java JARs/WARs, Python Eggs eða executables til að keyra á netþjónum. Hins vegar, til að láta þær virka, þurfti að vinna aukavinnu: setja upp keyrsluumhverfið (Java/Python), setja nauðsynlegar skrár á rétta staði, tryggja samhæfni við ákveðna útgáfu af stýrikerfinu o.s.frv. Með öðrum orðum þurfti að huga vel að stillingastjórnun (sem var oft uppspretta deilna milli þróunaraðila og kerfisstjóra).

Gámar breyttu öllu. Nú er gripurinn gámamynd. Það er hægt að tákna það sem eins konar útbreidda keyrsluskrá sem inniheldur ekki aðeins forritið, heldur einnig fullbúið framkvæmdarumhverfi (Java/Python/...), auk nauðsynlegra skráa/pakka, foruppsettar og tilbúnar til að hlaupa. Hægt er að dreifa gámum og keyra á mismunandi netþjónum án frekari skrefa.

Að auki starfa gámar í sínu eigin sandkassaumhverfi. Þeir hafa sitt eigið sýndarnet millistykki, eigið skráarkerfi með takmarkaðan aðgang, eigið stigveldi ferla, eigin takmarkanir á örgjörva og minni o.s.frv. Allt þetta er útfært þökk sé sérstöku undirkerfi Linux kjarnans - nafnarými.

Kubernetes

Eins og fyrr segir er Kubernetes gámasveitarstjóri. Það virkar svona: þú gefur honum fjölda véla og segir síðan: „Hey, Kubernetes, við skulum ræsa tíu tilvik af ílátinu mínu með 2 örgjörvum og 3 GB af minni hvorum, og halda þeim gangandi! Kubernetes sér um afganginn. Það mun finna lausa afkastagetu, ræsa gáma og endurræsa þá ef þörf krefur, rúlla út uppfærslu þegar skipt er um útgáfur o.s.frv. Í meginatriðum gerir Kubernetes þér kleift að fjarlægja vélbúnaðarhlutann og gerir fjölbreytt úrval kerfa hentug til að dreifa og keyra forrit.

CPU takmörk og árásargjarn inngjöf í Kubernetes
Kubernetes frá sjónarhóli leikmannsins

Hvað eru beiðnir og takmörk í Kubernetes

Allt í lagi, við höfum fjallað um gáma og Kubernetes. Við vitum líka að margir gámar geta verið á sömu vélinni.

Hægt er að draga upp hliðstæðu með sameiginlegri íbúð. Rúmgott húsnæði (vélar/einingar) er tekið og leigt nokkrum leigjendum (gáma). Kubernetes starfar sem fasteignasali. Spurningin vaknar, hvernig á að halda leigjendum frá árekstrum hver við annan? Hvað ef einhver þeirra, segjum, ákveður að fá lánað baðherbergið hálfan daginn?

Þetta er þar sem beiðnir og takmörk koma við sögu. örgjörvi Beiðni þarf eingöngu í skipulagsskyni. Þetta er eitthvað eins og „óskalisti“ yfir ílátið og það er notað til að velja heppilegasta hnútinn. Á sama tíma CPU Takmarka má líkja við leigusamning - um leið og við veljum einingu fyrir gáminn, þá getur ekki fara út fyrir sett mörk. Og þetta er þar sem vandamálið kemur upp...

Hvernig beiðnir og takmarkanir eru útfærðar í Kubernetes

Kubernetes notar inngjöfarkerfi (sleppa klukkulotum) sem er innbyggt í kjarnann til að innleiða CPU takmörk. Ef forrit fer yfir mörkin er inngjöf virkjuð (þ.e. það fær færri örgjörvalotur). Beiðnir og takmarkanir fyrir minni eru skipulagðar á annan hátt, þannig að auðveldara er að greina þær. Til að gera þetta skaltu bara athuga síðustu endurræsingarstöðu belgsins: hvort það sé „OOMKilled“. Inngjöf örgjörva er ekki svo einföld, þar sem K8s gerir aðeins mælikvarða tiltæka eftir notkun, ekki með cgroups.

CPU beiðni

CPU takmörk og árásargjarn inngjöf í Kubernetes
Hvernig CPU beiðni er útfærð

Til einföldunar skulum við líta á ferlið með því að nota vél með 4 kjarna örgjörva sem dæmi.

K8s notar stjórnhópakerfi (cgroups) til að stjórna úthlutun auðlinda (minni og örgjörva). Stigveldislíkan er til fyrir það: barnið erfir mörk foreldrahópsins. Dreifingarupplýsingarnar eru geymdar í sýndarskráakerfi (/sys/fs/cgroup). Ef um er að ræða örgjörva er þetta /sys/fs/cgroup/cpu,cpuacct/*.

K8s notar skrá cpu.share að úthluta örgjörvaauðlindum. Í okkar tilviki fær rót cgroup 4096 hlutdeild CPU auðlinda - 100% af tiltæku örgjörvaafli (1 kjarni = 1024; þetta er fast gildi). Rótarhópurinn dreifir auðlindum hlutfallslega eftir hlutdeild afkomenda sem skráð eru í cpu.share, og þeir aftur á móti gera það sama við afkomendur sína o.s.frv. Á dæmigerðum Kubernetes hnút hefur rót cgroup þrjú börn: system.slice, user.slice и kubepods. Fyrstu tveir undirhóparnir eru notaðir til að dreifa tilföngum milli mikilvægra kerfisálags og notendaforrita utan K8s. Síðasta - kubepods — búið til af Kubernetes til að dreifa auðlindum á milli belg.

Skýringarmyndin hér að ofan sýnir að fyrsti og annar undirhópur fengu hvern 1024 hlutabréf, með kuberpod undirhópnum úthlutað 4096 hlutabréf Hvernig er þetta mögulegt: Eftir allt saman hefur rótarhópurinn aðeins aðgang að 4096 hlutabréf, og summan af hlutabréfum afkomenda hennar fer verulega yfir þessa tölu (6144)? Aðalatriðið er að gildið er rökrétt, þannig að Linux tímaáætlunin (CFS) notar það til að úthluta örgjörvaauðlindum hlutfallslega. Í okkar tilviki fá fyrstu tveir hóparnir 680 raunhlutir (16,6% af 4096), og fær kubepod afganginn 2736 hlutabréf Ef um stöðvun er að ræða munu fyrstu tveir hóparnir ekki nota úthlutað fjármagn.

Sem betur fer hefur tímaáætlunarbúnaðurinn kerfi til að forðast að sóa ónotuðum CPU auðlindum. Það flytur „aðgerðalaus“ afkastagetu til alþjóðlegs laugar, þaðan sem henni er dreift til hópa sem þurfa aukið örgjörvaafl (flutningurinn á sér stað í lotum til að forðast námundunartap). Svipuð aðferð er beitt fyrir alla afkomendur afkomenda.

Þetta fyrirkomulag tryggir sanngjarna dreifingu á örgjörvaafli og tryggir að enginn vinnsla „steli“ auðlindum frá öðrum.

CPU takmörk

Þrátt fyrir þá staðreynd að stillingar takmarkana og beiðna í K8s líta svipaðar út, er útfærsla þeirra gjörólík: þetta mest villandi og minnst skjalfesta hluti.

K8s tekur þátt CFS kvótakerfi að innleiða takmarkanir. Stillingar þeirra eru tilgreindar í skrám cfs_period_us и cfs_quota_us í cgroup möppunni (skráin er líka staðsett þar cpu.share).

Ólíkt cpu.share, kvótinn miðast við Tímabil, og ekki á tiltækum örgjörvaafli. cfs_period_us tilgreinir lengd tímabilsins (tímabilsins) - það er alltaf 100000 μs (100 ms). Það er möguleiki að breyta þessu gildi í K8s, en það er aðeins fáanlegt í alfa eins og er. Tímaáætlunin notar tímabilið til að endurræsa notaða kvóta. Önnur skrá cfs_quota_us, tilgreinir lausan tíma (kvóta) á hverju tímabili. Athugaðu að það er einnig tilgreint í míkrósekúndum. Kvótinn getur farið yfir lengd tímabilsins; með öðrum orðum, það getur verið meira en 100 ms.

Við skulum skoða tvær aðstæður á 16 kjarna vélum (algengasta tegund tölvu sem við höfum hjá Omio):

CPU takmörk og árásargjarn inngjöf í Kubernetes
Atburðarás 1: 2 þræðir og 200 ms takmörk. Engin inngjöf

CPU takmörk og árásargjarn inngjöf í Kubernetes
Sviðsmynd 2: 10 þræðir og 200 ms hámark. Inngjöf hefst eftir 20 ms, aðgangur að örgjörvaauðlindum er hafin aftur eftir 80 ms í viðbót

Segjum að þú stillir CPU takmörk á 2 kjarna; Kubernetes mun þýða þetta gildi í 200 ms. Þetta þýðir að gámurinn getur notað að hámarki 200ms af örgjörvatíma án inngjafar.

Og þetta er þar sem gamanið byrjar. Eins og fyrr segir er laus kvóti 200 ms. Ef þú ert að vinna samhliða tíu þræðir á 12 kjarna vél (sjá mynd fyrir atburðarás 2), meðan allir aðrir belg eru aðgerðalausir, mun kvótinn klárast á aðeins 20 ms (þar sem 10 * 20 ms = 200 ms), og allir þræðir þessa belgs munu hanga » (inngjöf) fyrir næstu 80 ms. Það sem þegar er nefnt tímaáætlunarvilla, þar sem of mikil inngjöf á sér stað og gámurinn getur ekki einu sinni uppfyllt núverandi kvóta.

Hvernig á að meta inngjöf í belg?

Skráðu þig bara inn á podinn og keyrðu cat /sys/fs/cgroup/cpu/cpu.stat.

  • nr_periods — heildarfjöldi tímaáætlunartímabila;
  • nr_throttled — fjöldi rýmdra tímabila í samsetningunni nr_periods;
  • throttled_time — uppsafnaður tími í nanósekúndum.

CPU takmörk og árásargjarn inngjöf í Kubernetes

Hvað er eiginlega í gangi?

Fyrir vikið fáum við mikla inngjöf í öllum forritum. Stundum er hann inni einu og hálfu sinni sterkari en reiknað var með!

Þetta leiðir til margvíslegra villna - bilana í viðbúnaðarskoðun, gámum frýs, nettengingar rofnar, tímaleysis í þjónustusímtölum. Þetta leiðir að lokum í aukinni leynd og hærri villutíðni.

Ákvörðun og afleiðingar

Hér er allt einfalt. Við hættum CPU takmörkunum og byrjuðum að uppfæra OS kjarnann í klösum í nýjustu útgáfuna, þar sem villan var lagfærð. Fjöldi villna (HTTP 5xx) í þjónustu okkar fækkaði strax verulega:

HTTP 5xx villur

CPU takmörk og árásargjarn inngjöf í Kubernetes
HTTP 5xx villur fyrir eina mikilvæga þjónustu

Svartími p95

CPU takmörk og árásargjarn inngjöf í Kubernetes
Mikilvægar biðtími þjónustubeiðna, 95. hundraðshluti

Rekstrarkostnaður

CPU takmörk og árásargjarn inngjöf í Kubernetes
Fjöldi tilvikstunda sem varið er

Hver er aflinn?

Eins og segir í upphafi greinarinnar:

Hægt er að draga upp hliðstæðu með sameiginlegri íbúð... Kubernetes starfar sem fasteignasali. En hvernig á að halda leigjendum frá árekstrum hver við annan? Hvað ef einn þeirra, segjum, ákveður að fá lánað baðherbergið hálfan daginn?

Hér er gripurinn. Einn kærulaus ílát getur étið upp allar tiltækar örgjörvaauðlindir á vél. Ef þú ert með snjallforritastafla (til dæmis JVM, Go, Node VM eru rétt stilltir), þá er þetta ekki vandamál: þú getur unnið við slíkar aðstæður í langan tíma. En ef forrit eru illa fínstillt eða alls ekki fínstillt (FROM java:latest), ástandið gæti farið úr böndunum. Hjá Omio höfum við sjálfvirkar grunn Dockerfiles með fullnægjandi sjálfgefnum stillingum fyrir helstu tungumálabunkann, svo þetta mál var ekki til.

Við mælum með að fylgjast með mælingum NOTA (notkun, mettun og villur), API tafir og villuhlutfall. Tryggja að árangur standist væntingar.

tilvísanir

Þetta er okkar saga. Eftirfarandi efni hjálpuðu mjög til að skilja hvað var að gerast:

Kubernetes villuskýrslur:

Hefur þú lent í svipuðum vandamálum á æfingum þínum eða hefur þú reynslu í tengslum við inngjöf í gámaframleiðsluumhverfi? Deildu sögunni þinni í athugasemdum!

PS frá þýðanda

Lestu líka á blogginu okkar:

Heimild: www.habr.com

Bæta við athugasemd