Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

27 April by die konferensie Staking 2019, as deel van die "DevOps"-afdeling, is die verslag "Outomatiese skaal en hulpbronbestuur in Kubernetes" gegee. Dit praat oor hoe jy K8s kan gebruik om hoë beskikbaarheid van jou toepassings te verseker en piekwerkverrigting te verseker.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Volgens tradisie bied ons graag aan video met die verslag (44 minute, baie meer insiggewend as die artikel) en die hoofopsomming in teksvorm. Gaan!

Kom ons ontleed die onderwerp van die verslag woord vir woord en begin van die einde af.

Kubernetes

Kom ons sê ons het Docker-houers op ons gasheer. Vir wat? Om herhaalbaarheid en isolasie te verseker, wat weer 'n eenvoudige en goeie ontplooiing moontlik maak, CI/CD. Ons het baie sulke voertuie met houers.

Wat bied Kubernetes in hierdie geval?

  1. Ons hou op om aan hierdie masjiene te dink en begin met die "wolk" werk groep houers of peule (groepe houers).
  2. Boonop dink ons ​​nie eers aan individuele peule nie, maar bestuur meerоgroter groepe. Sulke hoëvlak primitiewe laat ons toe om te sê dat daar 'n sjabloon is om 'n sekere werklading uit te voer, en hier is die vereiste aantal gevalle om dit uit te voer. As ons daarna die sjabloon verander, sal alle gevalle verander.
  3. Met verklarende API In plaas daarvan om 'n reeks spesifieke opdragte uit te voer, beskryf ons die "struktuur van die wêreld" (in YAML), wat deur Kubernetes geskep word. En weer: wanneer die beskrywing verander, sal die werklike vertoning daarvan ook verander.

Hulpbron bestuur

CPU

Laat ons nginx, php-fpm en mysql op die bediener laat loop. Hierdie dienste sal eintlik nog meer prosesse aan die gang hê, wat elkeen rekenaarhulpbronne benodig:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)
(die nommers op die skyfie is "papegaaie", die abstrakte behoefte van elke proses vir rekenaarkrag)

Om dit makliker te maak om hiermee te werk, is dit logies om prosesse in groepe te kombineer (byvoorbeeld alle nginx-prosesse in een groep “nginx”). 'n Eenvoudige en voor die hand liggende manier om dit te doen, is om elke groep in 'n houer te plaas:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Om voort te gaan, moet jy onthou wat 'n houer is (in Linux). Hul voorkoms is moontlik gemaak danksy drie sleutelkenmerke in die kern, wat redelik lank gelede geïmplementeer is: vermoëns, naamruimtes и groepe. En verdere ontwikkeling is gefasiliteer deur ander tegnologieë (insluitend gerieflike "skulpe" soos Docker):

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

In die konteks van die verslag stel ons slegs belang in groepe, want kontrolegroepe is die deel van die funksionaliteit van houers (Docker, ens.) wat hulpbronbestuur implementeer. Prosesse wat in groepe gekombineer is, soos ons wou, is kontrolegroepe.

Kom ons keer terug na die SVE-vereistes vir hierdie prosesse, en nou vir groepe prosesse:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)
(Ek herhaal dat alle getalle 'n abstrakte uitdrukking is van die behoefte aan hulpbronne)

Terselfdertyd het die SVE self 'n sekere eindige hulpbron (in die voorbeeld is dit 1000), waaraan almal mag kortkom (die som van die behoeftes van alle groepe is 150+850+460=1460). Wat sal in hierdie geval gebeur?

Die kern begin hulpbronne versprei en doen dit "regverdig", en gee dieselfde hoeveelheid hulpbronne aan elke groep. Maar in die eerste geval is daar meer van hulle as wat nodig is (333>150), so die oormaat (333-150=183) bly in reserwe, wat ook eweredig tussen twee ander houers versprei word:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

As gevolg hiervan: die eerste houer het genoeg hulpbronne gehad, die tweede – dit het nie genoeg hulpbronne gehad nie, die derde – dit het nie genoeg hulpbronne gehad nie. Dit is die gevolg van aksies "eerlike" skeduleerder in Linux - CFS. Die werking daarvan kan met behulp van die opdrag aangepas word gewig elk van die houers. Byvoorbeeld, soos volg:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Kom ons kyk na die geval van 'n gebrek aan hulpbronne in die tweede houer (php-fpm). Alle houerhulpbronne word gelykop tussen prosesse verdeel. As gevolg hiervan werk die meesterproses goed, maar alle werkers vertraag, en ontvang minder as die helfte van wat hulle nodig het:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Dit is hoe die CFS skeduleerder werk. Ons sal verder die gewigte noem wat ons aan houers toeken versoeke. Hoekom dit so is - sien verder.

Kom ons kyk na die hele situasie van die ander kant af. Soos u weet, lei alle paaie na Rome, en in die geval van 'n rekenaar, na die SVE. Een SVE, baie take - jy het 'n verkeerslig nodig. Die eenvoudigste manier om hulpbronne te bestuur is "verkeerslig": hulle het een proses 'n vaste toegangstyd tot die SVE gegee, dan die volgende een, ens.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Hierdie benadering word harde kwotas genoem (moeilike beperking). Kom ons onthou dit eenvoudig as grense. As jy egter limiete na alle houers versprei, ontstaan ​​'n probleem: mysql het langs die pad gery en op 'n stadium het sy behoefte aan SVE geëindig, maar alle ander prosesse word gedwing om te wag totdat die SVE ledig.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Kom ons keer terug na die Linux-kern en sy interaksie met die SVE - die algehele prentjie is soos volg:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

cgroup het twee instellings - in wese is dit twee eenvoudige "draaie" wat jou toelaat om te bepaal:

  1. gewig vir houer (versoeke) is aandele;
  2. persentasie van die totale SVE tyd vir werk aan houer take (limiete) is kwota.

Hoe om SVE te meet?

Daar is verskillende maniere:

  1. Wat is papegaaie, niemand weet nie - jy moet elke keer onderhandel.
  2. belangstelling duideliker, maar relatief: 50% van 'n bediener met 4 kerne en met 20 cores is heeltemal verskillende dinge.
  3. Jy kan die wat reeds genoem is, gebruik gewig, wat Linux ken, maar hulle is ook relatief.
  4. Die mees geskikte opsie is om rekenaarhulpbronne in te meet sekondes. Dié. in sekondes verwerkertyd relatief tot sekondes intydse tyd: 1 sekonde verwerkertyd is per 1 regte sekonde gegee - dit is een hele SVE-kern.

Om dit nog makliker te maak om te praat, het hulle direk begin meet pitte, wat deur hulle dieselfde SVE-tyd relatief tot die regte een beteken. Aangesien Linux gewigte verstaan, maar nie soveel SVE-tyd/-kerne nie, was 'n meganisme nodig om van die een na die ander te vertaal.

Kom ons kyk na 'n eenvoudige voorbeeld met 'n bediener met 3 SVE-kerns, waar drie peule gewigte (500, 1000 en 1500) sal kry wat maklik omgeskakel word na die ooreenstemmende dele van die kerne wat aan hulle toegeken is (0,5, 1 en 1,5).

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

As jy 'n tweede bediener neem, waar daar twee keer soveel kerns (6) sal wees, en dieselfde peule daar plaas, kan die verspreiding van kerns maklik bereken word deur eenvoudig met 2 te vermenigvuldig (1, 2 en 3, onderskeidelik). Maar 'n belangrike oomblik vind plaas wanneer 'n vierde peul op hierdie bediener verskyn, wie se gewig, gerieflikheidshalwe, 3000 sal wees. Dit neem 'n deel van die SVE-hulpbronne (die helfte van die kerns) weg en vir die oorblywende peule word hulle herbereken (gehalveer):

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Kubernetes en SVE hulpbronne

In Kubernetes word SVE-hulpbronne gewoonlik gemeet in milliadrax, d.w.s. 0,001 kerne word as die basisgewig geneem. (Dieselfde ding in Linux/cgroups-terminologie word 'n SVE-aandeel genoem, alhoewel, meer presies, 1000 millicores = 1024 SVE-aandele.) K8s verseker dat dit nie meer peule op die bediener plaas as wat daar SVE-hulpbronne is vir die som van die gewigte van alle peule nie.

Hoe gebeur dit? Wanneer jy 'n bediener by 'n Kubernetes-kluster voeg, word gerapporteer hoeveel SVE-kerne dit beskikbaar het. En wanneer 'n nuwe peul geskep word, weet die Kubernetes-skeduleerder hoeveel kerns hierdie peul sal benodig. Die pod sal dus aan 'n bediener toegewys word waar daar genoeg kerns is.

Wat sal gebeur as geen versoek gespesifiseer word (d.w.s. die peul het nie 'n gedefinieerde aantal kerne wat dit benodig nie)? Kom ons vind uit hoe Kubernetes oor die algemeen hulpbronne tel.

Vir 'n pod kan jy beide versoeke (CFS skeduleerder) en limiete spesifiseer (onthou jy die verkeerslig?):

  • As hulle gelyk gespesifiseer word, word 'n QoS-klas aan die peul toegeken gewaarborg. Hierdie aantal kerns wat altyd beskikbaar is, is gewaarborg.
  • As die versoek minder is as die limiet - QoS klas barsbaar. Dié. Ons verwag dat 'n peul byvoorbeeld altyd 1 kern sal gebruik, maar hierdie waarde is nie 'n beperking daarvoor nie: soms pod kan meer gebruik (wanneer die bediener gratis hulpbronne hiervoor het).
  • Daar is ook 'n QoS-klas beste poging - dit sluit daardie einste peule in waarvoor versoek nie gespesifiseer is nie. Hulpbronne word laaste aan hulle gegee.

geheue

Met geheue is die situasie soortgelyk, maar effens anders - die aard van hierdie hulpbronne is immers anders. Oor die algemeen is die analogie soos volg:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Kom ons kyk hoe versoeke in die geheue geïmplementeer word. Laat die peule op die bediener bly, en verander geheueverbruik, totdat een van hulle so groot word dat dit sonder geheue opraak. In hierdie geval verskyn die OOM-moordenaar en maak die grootste proses dood:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Dit pas ons nie altyd nie, so dit is moontlik om te reguleer watter prosesse vir ons belangrik is en nie doodgemaak moet word nie. Om dit te doen, gebruik die parameter oom_telling_adj.

Kom ons keer terug na die QoS-klasse van die SVE en teken 'n analogie met die oom_score_adj waardes wat geheueverbruiksprioriteite vir peule bepaal:

  • Die laagste oom_score_adj waarde vir 'n peul - -998 - beteken dat so 'n peul laaste doodgemaak moet word, hierdie gewaarborg.
  • Die hoogste - 1000 - is beste poging, sulke peule word eerste doodgemaak.
  • Om die oorblywende waardes te bereken (barsbaar) is daar 'n formule waarvan die essensie daarop neerkom dat hoe meer hulpbronne 'n peul aangevra het, hoe minder waarskynlik is dit om doodgemaak te word.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Die tweede "draai" - limiet_in_grepe - vir perke. Daarmee is alles eenvoudiger: ons ken eenvoudig die maksimum hoeveelheid uitgereikte geheue toe, en hier (anders as die SVE) is daar geen sprake van hoe om dit (geheue) te meet nie.

In totaal

Elke peul in Kubernetes word gegee requests и limits - beide parameters vir SVE en geheue:

  1. gebaseer op versoeke, werk die Kubernetes skeduleerder, wat peule onder bedieners versprei;
  2. gebaseer op alle parameters, word die peul se QoS-klas bepaal;
  3. Relatiewe gewigte word bereken op grond van SVE-versoeke;
  4. die CFS-skeduleerder is gekonfigureer op grond van SVE-versoeke;
  5. OOM moordenaar is gekonfigureer gebaseer op geheue versoeke;
  6. 'n "verkeerslig" is opgestel op grond van SVE-limiete;
  7. Gebaseer op geheuelimiete, word 'n limiet vir die cgroup opgestel.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Oor die algemeen beantwoord hierdie prentjie al die vrae oor hoe die hoofgedeelte van hulpbronbestuur in Kubernetes plaasvind.

Outoskaal

K8s groep-outoskaaler

Kom ons stel ons voor dat die hele groep reeds beset is en 'n nuwe peul moet geskep word. Terwyl die peul nie kan verskyn nie, hang dit in status Hangende. Vir dit om te verskyn, kan ons 'n nuwe bediener aan die cluster koppel of... cluster-autoscaler installeer, wat dit vir ons sal doen: bestel 'n virtuele masjien van die wolkverskaffer (met 'n API-versoek) en koppel dit aan die cluster , waarna die peul bygevoeg sal word.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Dit is outoskaling van die Kubernetes-groepering, wat uitstekend werk (in ons ervaring). Maar, soos elders, is daar 'n paar nuanses hier ...

Solank as wat ons die trosgrootte vergroot het, was alles goed, maar wat gebeur wanneer die tros homself begin bevry het? Die probleem is dat migrasie van peule (om gashere vry te maak) tegnies baie moeilik en duur is in terme van hulpbronne. Kubernetes gebruik 'n heeltemal ander benadering.

Oorweeg 'n groep van 3 bedieners wat Ontplooiing het. Dit het 6 peule: nou is daar 2 vir elke bediener. Om een ​​of ander rede wou ons een van die bedieners afskakel. Om dit te doen sal ons die opdrag gebruik kubectl drain, watter:

  • sal die stuur van nuwe peule na hierdie bediener verbied;
  • sal bestaande peule op die bediener uitvee.

Aangesien Kubernetes verantwoordelik is vir die instandhouding van die aantal peule (6), is dit eenvoudig sal herskep hulle op ander nodusse, maar nie op die een wat gedeaktiveer is nie, aangesien dit reeds as onbeskikbaar gemerk is om nuwe peule te huisves. Dit is 'n fundamentele werktuigkundige vir Kubernetes.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Hier is egter ook 'n nuanse. In 'n soortgelyke situasie, vir StatefulSet (in plaas van Ontplooiing), sal die aksies anders wees. Nou het ons reeds 'n stateful-toepassing - byvoorbeeld drie peule met MongoDB, waarvan een 'n soort probleem het (die data het korrupte geraak of 'n ander fout wat verhoed dat die peul reg begin). En ons besluit weer om een ​​bediener te deaktiveer. Wat sal gebeur?

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

MongoDB kon sterf omdat dit 'n kworum benodig: vir 'n groep van drie installasies moet ten minste twee funksioneer. Hierdie nie gebeur nie - te danke aan PodOntwrigting Begroting. Hierdie parameter bepaal die minimum vereiste aantal werkende peule. Om te weet dat een van die MongoDB-peule nie meer werk nie, en sien dat PodDisruptionBudget vir MongoDB ingestel is minAvailable: 2, Kubernetes sal jou nie toelaat om 'n peul uit te vee nie.

Bottom line: sodat die beweging (en in werklikheid die herskepping) van peule korrek kan werk wanneer die groep vrygestel word, is dit nodig om PodDisruptionBudget op te stel.

Horisontale skaal

Kom ons kyk na 'n ander situasie. Daar is 'n toepassing wat as Ontplooiing in Kubernetes loop. Gebruikersverkeer kom na sy peule (byvoorbeeld, daar is drie van hulle), en ons meet 'n sekere aanwyser daarin (sê SVE-lading). Wanneer die vrag toeneem, teken ons dit op 'n skedule aan en verhoog die aantal peule om versoeke te versprei.

Vandag in Kubernetes hoef dit nie met die hand gedoen te word nie: 'n outomatiese toename/afname in die aantal peule word gekonfigureer afhangende van die waardes van die gemete lasaanwysers.

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Die hoofvrae hier is: wat presies om te meet и hoe om te interpreteer verkry waardes (vir die neem van 'n besluit oor die verandering van die aantal peule). Jy kan baie meet:

Outoskaal en hulpbronbestuur in Kubernetes (oorsig en videoverslag)

Hoe om dit tegnies te doen - versamel maatstawwe, ens. — Ek het in die berig breedvoerig gepraat oor Monitering en Kubernetes. En die belangrikste advies vir die keuse van die optimale parameters is eksperimenteer!

Daar is GEBRUIK metode (Gebruikversadiging en foute), waarvan die betekenis soos volg is. Op watter basis maak dit sin om byvoorbeeld php-fpm te skaal? Gebaseer op die feit dat werkers opraak, is dit benutting. En as die werkers verby is en nuwe verbindings nie aanvaar word nie, is dit reeds versadiging. Beide hierdie parameters moet gemeet word, en afhangende van die waardes, moet skaal uitgevoer word.

In plaas daarvan om 'n gevolgtrekking

Die verslag het 'n voortsetting: oor vertikale skaal en hoe om die regte hulpbronne te kies. Ek sal hieroor praat in toekomstige video's op ons YouTube - teken in sodat jy nie uitmis nie!

Video's en skyfies

Video van die optrede (44 minute):

Verslagaanbieding:

PS

Ander berigte oor Kubernetes in ons blog:

Bron: will.com

Voeg 'n opmerking