Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

La 27-an de aprilo ĉe la konferenco Striko 2019, kiel parto de la sekcio "DevOps", la raporto "Autoscaling kaj administrado de rimedoj en Kubernetes" estis donita. Ĝi parolas pri kiel vi povas uzi K8s por certigi altan haveblecon de viaj aplikoj kaj certigi maksimuman rendimenton.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Laŭ tradicio, ni ĝojas prezenti video de la raporto (44 minutoj, multe pli informa ol la artikolo) kaj la ĉefa resumo en tekstformo. Iru!

Ni analizu la temon de la raporto vorto post vorto kaj komencu de la fino.

Kubernetoj

Ni diru, ke ni havas Docker-ujojn sur nia gastiganto. Por kio? Por certigi ripeteblon kaj izolitecon, kiu siavice permesas simplan kaj bonan disfaldon, CI/CD. Ni havas multajn tiajn veturilojn kun ujoj.

Kion provizas Kubernetes en ĉi tiu kazo?

  1. Ni ĉesas pensi pri ĉi tiuj maŝinoj kaj komencas labori kun la "nubo" areto da ujoj aŭ balgoj (grupoj de ujoj).
  2. Plie, ni eĉ ne pensas pri individuaj podoj, sed administras pliоpli grandaj grupoj. Tia altnivelaj primitivuloj permesu al ni diri, ke ekzistas ŝablono por funkcii certan laborŝarĝon, kaj jen la bezonata nombro da okazoj por ruli ĝin. Se ni poste ŝanĝas la ŝablonon, ĉiuj okazoj ŝanĝiĝos.
  3. Kun la helpo de deklara API Anstataŭ efektivigi sekvencon de specifaj komandoj, ni priskribas la "strukturon de la mondo" (en YAML), kiu estas kreita de Kubernetes. Kaj denove: kiam la priskribo ŝanĝiĝas, ĝia reala ekrano ankaŭ ŝanĝiĝos.

Administrado de rimedoj

CPU

Ni rulu nginx, php-fpm kaj mysql sur la servilo. Ĉi tiuj servoj efektive havos eĉ pli da procezoj funkcianta, ĉiu el kiuj postulas komputigajn rimedojn:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)
(la nombroj sur la glito estas "papagoj", la abstrakta bezono de ĉiu procezo por komputika potenco)

Por faciligi labori kun ĉi tio, estas logike kombini procezojn en grupojn (ekzemple, ĉiuj nginx-procezoj en unu grupon "nginx"). Simpla kaj evidenta maniero fari tion estas meti ĉiun grupon en ujo:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Por daŭrigi, vi devas memori kio estas ujo (en Linukso). Ilia apero estis ebligita danke al tri ĉefaj funkcioj en la kerno, efektivigitaj antaŭ sufiĉe longa tempo: Kapabloj, nomspacoj и grupoj. Kaj pluevoluigo estis faciligita de aliaj teknologioj (inkluzive de oportunaj "ŝeloj" kiel Docker):

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

En la kunteksto de la raporto, ni nur interesiĝas grupoj, ĉar kontrolgrupoj estas la parto de la funkcieco de ujoj (Docker, ktp.) kiu efektivigas rimedadministradon. Procezoj kombinitaj en grupojn, kiel ni volis, estas kontrolgrupoj.

Ni revenu al la CPU-postuloj por ĉi tiuj procezoj, kaj nun por grupoj de procezoj:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)
(Mi ripetas, ke ĉiuj nombroj estas abstrakta esprimo de la bezono de rimedoj)

Samtempe, la CPU mem havas certan finian rimedon (en la ekzemplo tio estas 1000), kiun al ĉiuj eble mankas (la sumo de la bezonoj de ĉiuj grupoj estas 150+850+460=1460). Kio okazos en ĉi tiu kazo?

La kerno komencas distribui rimedojn kaj faras ĝin "juste", donante la saman kvanton da rimedoj al ĉiu grupo. Sed en la unua kazo, estas pli da ili ol bezonate (333>150), do la troo (333-150=183) restas en rezervo, kiu ankaŭ estas egale distribuita inter du aliaj ujoj:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Rezulte: la unua ujo havis sufiĉe da rimedoj, la dua - ĝi ne havis sufiĉe da rimedoj, la tria - ĝi ne havis sufiĉe da rimedoj. Ĉi tio estas la rezulto de agoj "honesta" planilo en Linukso - CFS. Ĝia funkciado povas esti ĝustigita uzante la taskon pezoj ĉiu el la ujoj. Ekzemple, tiel:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ni rigardu la kazon de manko de rimedoj en la dua ujo (php-fpm). Ĉiuj ujresursoj estas distribuitaj egale inter procezoj. Kiel rezulto, la majstra procezo funkcias bone, sed ĉiuj laboristoj malrapidiĝas, ricevante malpli ol duonon de tio, kion ili bezonas:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Jen kiel funkcias la CFS-horplanilo. Ni plu nomos la pezojn, kiujn ni atribuas al ujoj petoj. Kial ĉi tio estas tiel - vidu plu.

Ni rigardu la tutan situacion de la alia flanko. Kiel vi scias, ĉiuj vojoj kondukas al Romo, kaj en la kazo de komputilo, al la CPU. Unu CPU, multaj taskoj - vi bezonas semaforon. La plej simpla maniero administri rimedojn estas "trafika lumo": ili donis al unu procezo fiksan alirtempon al la CPU, tiam la sekva, ktp.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ĉi tiu aliro nomiĝas malmolaj kvotoj (malfacile limigo). Ni memoru ĝin simple kiel limoj. Tamen, se vi distribuas limojn al ĉiuj ujoj, aperas problemo: mysql veturis laŭ la vojo kaj iam ĝia bezono de CPU finiĝis, sed ĉiuj aliaj procezoj estas devigitaj atendi ĝis la CPU. senlabore.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ni revenu al la Linukso-kerno kaj ĝia interago kun la CPU - la ĝenerala bildo estas jena:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

cgroup havas du agordojn - esence ĉi tiuj estas du simplaj "tordaĵoj" kiuj permesas vin determini:

  1. pezo por ujo (petoj) estas dividas;
  2. procento de la tuta CPU-tempo por labori pri kontenaj taskoj (limoj) estas kotizo.

Kiel mezuri CPU?

Estas malsamaj manieroj:

  1. Kio papagoj, neniu scias - oni devas ĉiufoje negoci.
  2. Intereso pli klara, sed relativa: 50% de servilo kun 4 kernoj kaj kun 20 kernoj estas tute malsamaj aferoj.
  3. Vi povas uzi tiujn jam menciitajn pezoj, kiun Linukso konas, sed ili ankaŭ estas relativaj.
  4. La plej taŭga opcio estas mezuri komputikajn rimedojn en sekundoj. Tiuj. en sekundoj da procesora tempo rilate al sekundoj da reala tempo: 1 sekundo da procesorotempo estis donita po 1 reala sekundo - tio estas unu tuta CPU-kerno.

Por eĉ pli facile paroli, ili komencis mezuri rekte en kernoj, signifante per ili la saman CPU-tempon rilate al la reala. Ĉar Linukso komprenas pezojn, sed ne tiom da CPU-tempo/kernoj, necesas mekanismo por traduki de unu al la alia.

Ni konsideru simplan ekzemplon kun servilo kun 3 CPU-kernoj, kie tri podoj ricevos pezojn (500, 1000 kaj 1500) kiuj estas facile konvertitaj al la respondaj partoj de la kernoj asignitaj al ili (0,5, 1 kaj 1,5).

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Se vi prenas duan servilon, kie estos duoble pli da kernoj (6), kaj metas la samajn podojn tie, la distribuo de kernoj povas esti facile kalkulita per simple multipliko de 2 (1, 2 kaj 3, respektive). Sed grava momento okazas, kiam en ĉi tiu servilo aperas kvara pod, kies pezo, por oportuno, estos 3000. Ĝi forprenas parton de la CPU-resursoj (duono de la kernoj), kaj por la ceteraj podoj ili estas rekalkulitaj (duonigitaj):

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Kubernetes kaj CPU-resursoj

En Kubernetes, CPU-resursoj estas kutime mezuritaj en miliadrax, t.e. 0,001 kernoj estas prenitaj kiel la baza pezo. (La sama afero en Linukso/cgroups-terminologio nomiĝas CPU-akcio, kvankam, pli precize, 1000 milikoroj = 1024 CPU-akcioj.) K8s certigas, ke ĝi ne metas pli da podoj sur la servilo ol ekzistas CPU-resursoj por la sumo de la pezoj de ĉiuj podoj.

Kiel tio okazas? Kiam vi aldonas servilon al Kubernetes-areo, oni raportas kiom da CPU-kernoj ĝi havas disponeblaj. Kaj kreante novan podon, la planilo de Kubernetes scias kiom da kernoj ĉi tiu podo bezonos. Tiel, la pod estos asignita al servilo kie estas sufiĉe da kernoj.

Kio okazos se ne peto estas precizigita (t.e. la podo ne havas difinitan nombron da kernoj kiujn ĝi bezonas)? Ni eltrovu kiel Kubernetes ĝenerale kalkulas rimedojn.

Por pod vi povas specifi kaj petojn (CFS-planilo) kaj limojn (memoru la semaforo?):

  • Se ili estas precizigitaj egalaj, tiam al la pod estas asignita QoS-klaso garantiita. Ĉi tiu nombro da kernoj ĉiam disponeblaj al ĝi estas garantiita.
  • Se la peto estas malpli ol la limo - QoS klaso krevebla. Tiuj. Ni atendas ke pod, ekzemple, ĉiam uzu 1 kernon, sed ĉi tiu valoro ne estas limo por ĝi: kelkfoje pod povas uzi pli (kiam la servilo havas senpagajn rimedojn por tio).
  • Ekzistas ankaŭ QoS-klaso plej bona penado — ĝi inkluzivas tiujn mem podojn por kiuj peto ne estas specifita. Rimedoj estas donitaj al ili laste.

memoro

Kun memoro, la situacio estas simila, sed iomete malsama - finfine, la naturo de ĉi tiuj rimedoj estas malsama. Ĝenerale, la analogio estas kiel sekvas:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ni vidu kiel petoj estas efektivigitaj en memoro. Lasu la podojn vivi sur la servilo, ŝanĝante memorkonsumon, ĝis unu el ili fariĝos tiel granda ke ĝi elĉerpigas memoron. En ĉi tiu kazo, la OOM-murdinto aperas kaj mortigas la plej grandan procezon:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ĉi tio ne ĉiam konvenas al ni, do eblas reguligi, kiuj procezoj estas gravaj por ni kaj ne devas esti mortigitaj. Por fari tion, uzu la parametron oom_score_adj.

Ni revenu al la QoS-klasoj de la CPU kaj desegnu analogion kun la oom_score_adj-valoroj, kiuj determinas memorajn konsumprioritatojn por podoj:

  • La plej malalta oom_score_adj valoro por pod - -998 - signifas, ke tia balgo devas esti mortigita laste, ĉi tiu garantiita.
  • La plej alta - 1000 - estas plej bona penado, tiaj balgoj unue estas mortigitaj.
  • Por kalkuli la ceterajn valorojn (krevebla) ekzistas formulo, kies esenco resumas al tio, ke ju pli da rimedoj petis balgo, des malpli probable ĝi estas mortigota.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

La dua "tordaĵo" - limo_en_bajtoj - por limoj. Kun ĝi, ĉio estas pli simpla: ni simple atribuas la maksimuman kvanton de elsendita memoro, kaj ĉi tie (male al la CPU) ne estas demando pri kiel mezuri ĝin (memoro).

Tuta

Ĉiu pod en Kubernetes estas donita requests и limits - ambaŭ parametroj por CPU kaj memoro:

  1. surbaze de petoj, funkcias la planilo de Kubernetes, kiu distribuas podojn inter serviloj;
  2. surbaze de ĉiuj parametroj, la QoS-klaso de la pod estas determinita;
  3. Relativaj pezoj estas kalkulitaj surbaze de CPU-petoj;
  4. la CFS-planilo estas agordita surbaze de CPU-petoj;
  5. OOM-murdinto estas agordita surbaze de memorpetoj;
  6. "semaforo" estas agordita surbaze de CPU-limoj;
  7. Surbaze de memorlimoj, limo estas agordita por la cgroup.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ĝenerale, ĉi tiu bildo respondas ĉiujn demandojn pri kiel la ĉefa parto de administrado de rimedoj okazas en Kubernetes.

Aŭtoskalo

K8s cluster-autoscaler

Ni imagu, ke la tuta areto jam estas okupata kaj necesas krei novan podon. Dum la balgo ne povas aperi, ĝi pendas en stato Decidota. Por ke ĝi aperu, ni povas konekti novan servilon al la cluster aŭ... instali cluster-autoscaler, kiu faros ĝin por ni: mendi virtualan maŝinon de la nuba provizanto (uzante API-peton) kaj konekti ĝin al la cluster. , post kio la pod estos aldonita .

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Ĉi tio estas aŭtoskalo de la Kubernetes-areto, kiu funkcias bonege (laŭ nia sperto). Tamen, kiel aliloke, estas kelkaj nuancoj ĉi tie...

Tiel longe kiel ni pliigis la areto grandeco, ĉio estis bona, sed kio okazas kiam la areto komencis liberigi sin? La problemo estas, ke migri podojn (por liberigi gastigantojn) estas tre teknike malfacila kaj multekosta rilate rimedojn. Kubernetes uzas tute alian aliron.

Konsideru aron de 3 serviloj, kiuj havas Deplojon. Ĝi havas 6 podojn: nun estas 2 por ĉiu servilo. Ial ni volis malŝalti unu el la serviloj. Por fari tion ni uzos la komandon kubectl drain, kiu:

  • malpermesos sendi novajn podojn al ĉi tiu servilo;
  • forigos ekzistantajn podojn sur la servilo.

Ĉar Kubernetes respondecas pri konservado de la nombro da podoj (6), ĝi simple rekreos ilin sur aliaj nodoj, sed ne sur tiu malŝaltita, ĉar ĝi jam estas markita kiel nedisponebla por gastigi novajn podojn. Ĉi tio estas fundamenta mekaniko por Kubernetes.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Tamen ankaŭ ĉi tie estas nuanco. En simila situacio, por StatefulSet (anstataŭ Deployment), la agoj estos malsamaj. Nun ni jam havas ŝtatan aplikaĵon - ekzemple, tri podojn kun MongoDB, unu el kiuj havas ian problemon (la datumoj koruptiĝis aŭ alian eraron, kiu malhelpas la podon ĝuste komenci). Kaj ni denove decidas malŝalti unu servilon. Kio okazos?

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

MongoDB povus morti ĉar ĝi bezonas kvorumon: por aro de tri instalaĵoj, almenaŭ du devas funkcii. Tamen ĉi tio ne okazas - danke al PodDisruptionBudget. Ĉi tiu parametro determinas la minimuman bezonatan nombron da laborkaptoj. Sciante, ke unu el la MongoDB-podoj ne plu funkcias, kaj vidante, ke PodDisruptionBudget estas agordita por MongoDB. minAvailable: 2, Kubernetes ne permesos al vi forigi pod.

Fundo: por ke la movado (kaj fakte, la rekreado) de podoj funkciu ĝuste kiam la grapolo estas liberigita, necesas agordi PodDisruptionBudget.

Horizontala skalado

Ni konsideru alian situacion. Estas aplikaĵo funkcianta kiel Deplojo en Kubernetes. Uzanttrafiko venas al ĝiaj podoj (ekzemple, estas tri el ili), kaj ni mezuras certan indikilon en ili (diru, CPU-ŝarĝo). Kiam la ŝarĝo pliiĝas, ni registras ĝin laŭ horaro kaj pliigas la nombron da podoj por distribui petojn.

Hodiaŭ en Kubernetes ĉi tio ne bezonas esti farita permane: aŭtomata pliiĝo/malkresko de la nombro da podoj estas agordita depende de la valoroj de la mezuritaj ŝarĝindikiloj.

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

La ĉefaj demandoj ĉi tie estas: kion precize mezuri и kiel interpreti akiritaj valoroj (por fari decidon pri ŝanĝo de la nombro da podoj). Vi povas mezuri multe:

Aŭtoskalado kaj administrado de rimedoj en Kubernetes (recenzo kaj videoraporto)

Kiel fari tion teknike - kolektu metrikojn ktp. — Mi detale parolis en la raporto pri Monitorado kaj Kubernetes. Kaj la ĉefa konsilo por elekti la optimumajn parametrojn estas eksperimento!

Ekzistas UZ metodo (Uzo-Saturiĝo kaj Eraroj), kies signifo estas jena. Sur kiu bazo havas sencon grimpi, ekzemple, php-fpm? Surbaze de tio, ke laboristoj elĉerpas, ĉi tio estas utiligo. Kaj se la laboristoj finiĝas kaj novaj rilatoj ne estas akceptitaj, tio jam estas saturiĝo. Ambaŭ ĉi tiuj parametroj devas esti mezuritaj, kaj depende de la valoroj, skalo devas esti efektivigita.

Anstataŭ konkludo

La raporto havas daŭrigon: pri vertikala skalo kaj kiel elekti la ĝustajn rimedojn. Mi parolos pri tio en estontaj filmetoj nia Jutubo - abonu por ke vi ne maltrafu!

Filmetoj kaj diapozitivoj

Vidbendo de la prezentado (44 minutoj):

Prezento de la raporto:

PS

Aliaj raportoj pri Kubernetes en nia blogo:

fonto: www.habr.com

Aldoni komenton