Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

27. aprillil konverentsil Streik 2019, jaotise "DevOps" osana esitati aruanne "Automaatne skaleerimine ja ressursside haldamine Kubernetesis". See räägib sellest, kuidas saate K8-sid kasutada, et tagada oma rakenduste kõrge kättesaadavus ja tippjõudlus.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Traditsiooni kohaselt on meil hea meel esitleda video raportist (44 minutit, palju informatiivsem kui artikkel) ja põhikokkuvõte teksti kujul. Mine!

Analüüsime aruande teemat sõna-sõnalt ja alustame lõpust.

Kubernetes

Oletame, et meie hostis on Dockeri konteinerid. Milleks? Korratavuse ja isolatsiooni tagamiseks, mis omakorda võimaldab lihtsat ja head juurutamist, CI/CD. Meil on palju selliseid konteineritega sõidukeid.

Mida Kubernetes sel juhul pakub?

  1. Lõpetame nendele masinatele mõtlemise ja hakkame töötama "pilvega" konteinerite klaster või kaunad (konteinerite rühmad).
  2. Lisaks ei mõtle me isegi üksikutele kaunadele, vaid juhime rohkemоsuuremad rühmad. Sellised kõrgetasemelised primitiivid lubage meil öelda, et teatud töökoormuse käitamiseks on mall ja siin on selle käitamiseks vajalik arv eksemplare. Kui hiljem malli muudame, muutuvad kõik eksemplarid.
  3. Koos deklaratiivne API Konkreetsete käskude jada täitmise asemel kirjeldame "maailma struktuuri" (YAML-is), mille on loonud Kubernetes. Ja veel: kui kirjeldus muutub, muutub ka selle tegelik kuva.

Ressursside haldamine

Protsessor

Laske meil serveris käivitada nginx, php-fpm ja mysql. Nendel teenustel töötab tegelikult veelgi rohkem protsesse, millest igaüks nõuab arvutusressursse:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)
(numbrid slaidil on "papagoid", iga protsessi abstraktne vajadus arvutusvõimsuse järele)

Sellega töötamise hõlbustamiseks on loogiline ühendada protsessid rühmadesse (näiteks kõik nginxi protsessid ühte rühma “nginx”). Lihtne ja ilmne viis selleks on panna iga rühm konteinerisse:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Jätkamiseks peate meeles pidama, mis on konteiner (Linuxis). Nende ilmumine sai võimalikuks tänu kolmele kerneli põhifunktsioonile, mis rakendati üsna kaua aega tagasi: võimeid, nimeruumi и rühmad. Ja edasist arengut hõlbustasid muud tehnoloogiad (sealhulgas mugavad "kestad", nagu Docker):

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Aruande kontekstis oleme huvitatud ainult sellest rühmad, sest kontrollrühmad on konteinerite (Docker jne) funktsionaalsuse osa, mis rakendab ressursside haldust. Rühmadeks kombineeritud protsessid, nagu soovisime, on kontrollrühmad.

Pöördume tagasi nende protsesside ja nüüd protsessirühmade CPU nõuete juurde:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)
(Ma kordan, et kõik numbrid on ressursside vajaduse abstraktne väljend)

Samal ajal on protsessoril endal teatud piiratud ressurss (näites on see 1000), millest kõigil võib puudust tunda (kõikide rühmade vajaduste summa on 150+850+460=1460). Mis sel juhul juhtub?

Tuum hakkab ressursse jaotama ja teeb seda "õiglaselt", andes igale rühmale sama palju ressursse. Aga esimesel juhul on neid rohkem kui vaja (333>150), seega jääb ülejääk (333-150=183) reservi, mis samuti jaotub võrdselt kahe teise konteineri vahel:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Selle tulemusena: esimesel konteineril oli piisavalt ressursse, teisel - sellel ei olnud piisavalt ressursse, kolmandal - sellel ei olnud piisavalt ressursse. See on tegude tulemus "aus" planeerija Linuxis - CFS. Selle tööd saab ülesande abil reguleerida kaal iga konteiner. Näiteks nii:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Vaatame teise konteineri (php-fpm) ressursside puudumise juhtumit. Kõik konteineriressursid jaotatakse protsesside vahel võrdselt. Selle tulemusel toimib põhiprotsess hästi, kuid kõik töötajad aeglustavad, saades vähem kui poole vajalikust:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Nii töötab CFS-i planeerija. Edasi nimetame konteineritele määratud raskusi taotlusi. Miks see nii on - vaata edasi.

Vaatame kogu olukorda teisest küljest. Teatavasti viivad kõik teed Rooma ja arvuti puhul protsessorini. Üks protsessor, palju ülesandeid – vajate valgusfoori. Lihtsaim viis ressursside haldamiseks on "valgusfoor": nad andsid ühele protsessile CPU-le kindla juurdepääsuaja, seejärel järgmisele jne.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Seda lähenemisviisi nimetatakse kõvadeks kvootideks (raske piiramine). Jätame seda lihtsalt nii piirid. Kui aga jaotada limiidid kõikidele konteineritele, tekib probleem: mysql sõitis mööda teed ja mingil hetkel lõppes selle protsessori vajadus, kuid kõik muud protsessid on sunnitud ootama kuni CPU tühikäigul.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Tuleme tagasi Linuxi tuuma ja selle koostoime juurde CPU-ga – üldpilt on järgmine:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

cgroupil on kaks seadistust – sisuliselt on need kaks lihtsat keerdkäiku, mis võimaldavad teil kindlaks teha:

  1. konteineri kaal (päringud) on aktsiad;
  2. protsent kogu CPU ajast konteineriülesannetega töötamiseks (limiidid). kvoot.

Kuidas CPU-d mõõta?

On erinevaid viise:

  1. Mis on papagoid, keegi ei tea – iga kord on vaja läbi rääkida.
  2. Huvi selgem, aga suhteline: 50% 4 tuumaga ja 20 tuumaga serverist on täiesti erinevad asjad.
  3. Võite kasutada juba mainitud kaal, mida Linux teab, kuid need on ka suhtelised.
  4. Kõige sobivam võimalus on mõõta arvutusressursse sekundit. Need. protsessori aja sekundites reaalaja sekundite suhtes: 1 sekund protsessori aega anti 1 reaalsekundi kohta – see on üks terve protsessori tuum.

Et rääkida oleks veelgi lihtsam, hakati otse mõõtma tuumad, mis tähendab nende jaoks sama protsessori aega võrreldes tegeliku protsessoriga. Kuna Linux mõistab kaalusid, kuid mitte nii palju CPU aega/tuumasid, oli vaja mehhanismi, mis tõlkiks ühelt teisele.

Vaatleme lihtsat näidet 3 protsessori tuumaga serveriga, kus kolmele podile antakse kaalud (500, 1000 ja 1500), mis on kergesti teisendatavad neile eraldatud tuumade vastavateks osadeks (0,5, 1 ja 1,5).

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Kui võtate teise serveri, kus on kaks korda rohkem südamikke (6), ja asetate sinna samad kaustad, saab tuumade jaotuse hõlpsalt arvutada, korrutades lihtsalt 2-ga (vastavalt 1, 2 ja 3). Kuid oluline hetk saabub siis, kui sellesse serverisse ilmub neljas pod, mille kaal on mugavuse huvides 3000. See võtab osa CPU ressurssidest (pooled tuumad) ära ja ülejäänud podude jaoks arvutatakse need ümber (poolitatakse):

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Kubernetes ja CPU ressursid

Kubernetesis mõõdetakse protsessori ressursse tavaliselt milliadrax, st. Baaskaaluks võetakse 0,001 südamikku. (Sama asja nimetatakse Linuxi/cgroupsi terminoloogias protsessori jagamiseks, kuigi täpsemalt 1000 millituuma = 1024 protsessori jagamist.) K8s tagab, et see ei paiguta serverisse rohkem mooduleid, kui on protsessori ressursse kõigi podide kaalude summaks.

Kuidas see juhtub? Kui lisate Kubernetese klastrisse serveri, antakse teada, mitu protsessorituuma sellel on saadaval. Ja uue podi loomisel teab Kubernetese ajakava, kui palju südamikke see pod vajab. Seega määratakse pod serverile, kus on piisavalt südamikke.

Mis saab siis, kui ei päring on täpsustatud (st podil pole määratletud arvu tuumasid, mida ta vajab)? Mõelgem välja, kuidas Kubernetes üldiselt ressursse loeb.

Podi jaoks saate määrata nii päringud (CFS-i ajakava) kui ka piirangud (kas mäletate valgusfoori?):

  • Kui need on määratud võrdseks, määratakse podile QoS klass tagatud. See alati saadaval olev südamike arv on garanteeritud.
  • Kui päring on limiidist väiksem - QoS klass purunev. Need. Eeldame, et näiteks pod kasutab alati 1 tuuma, kuid see väärtus ei ole selle jaoks piiratud: mõnikord pod saab kasutada rohkem (kui serveril on selleks vabu ressursse).
  • Samuti on olemas QoS klass parim pingutus — see hõlmab just neid kaunasid, mille kohta taotlust ei ole täpsustatud. Ressursid antakse neile viimasena.

mälu

Mäluga on olukord sarnane, kuid veidi erinev - lõppude lõpuks on nende ressursside olemus erinev. Üldiselt on analoogia järgmine:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Vaatame, kuidas päringuid mällu rakendatakse. Laske kaunadel serveris elada, muutes mälutarbimist, kuni üks neist muutub nii suureks, et mälu saab otsa. Sel juhul ilmub OOM-i tapja ja tapab suurima protsessi:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

See meile alati ei sobi, seega on võimalik reguleerida, millised protsessid on meile olulised ja neid ei tohi tappa. Selleks kasutage parameetrit oom_score_adj.

Pöördume tagasi CPU QoS-klasside juurde ja toome analoogia oom_score_adj väärtustega, mis määravad kaustade mälutarbimise prioriteedid:

  • Podi madalaim oom_score_adj väärtus -998 - tähendab, et selline pod tuleks tappa viimasena. tagatud.
  • Kõrgeim – 1000 – on parim pingutus, sellised kaunad tapetakse kõigepealt.
  • Ülejäänud väärtuste arvutamiseks (purunev) on olemas valem, mille põhiolemus seisneb selles, et mida rohkem ressursse kaun on taotlenud, seda väiksem on selle tapmise tõenäosus.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Teine "keerd" - limit_in_bytes - piirangute jaoks. Sellega on kõik lihtsam: määrame lihtsalt maksimaalse väljastatud mälumahu ja siin (erinevalt CPU-st) pole küsimust, kuidas seda (mälu) mõõta.

Kogusummas

Iga Kubernetese kaun on antud requests и limits - mõlemad protsessori ja mälu parameetrid:

  1. päringute alusel töötab Kubernetese planeerija, mis jaotab podid serverite vahel;
  2. kõigi parameetrite põhjal määratakse podi QoS klass;
  3. Suhtelised kaalud arvutatakse protsessori taotluste põhjal;
  4. CFS-i planeerija on konfigureeritud CPU päringu alusel;
  5. OOM killer on konfigureeritud mälupäringu alusel;
  6. valgusfoor on konfigureeritud protsessori piirangute alusel;
  7. Mälupiirangute põhjal on cgroupi jaoks konfigureeritud limiit.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Üldiselt vastab see pilt kõigile küsimustele, kuidas Kubernetesis ressursside haldamise põhiosa toimub.

Automaatne skaleerimine

K8s klastri-automaatne skaleerija

Kujutagem ette, et kogu klaster on juba hõivatud ja vaja on luua uus pod. Kuigi kausta ei saa kuvada, ripub see olekus kuni. Selle ilmumiseks saame ühendada klastriga uue serveri või... installida cluster-autoscaler, mis teeb seda meie eest: tellib pilveteenuse pakkujalt virtuaalmasina (kasutades API päringut) ja ühenda klastriga , mille järel lisatakse kaun .

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

See on Kubernetese klastri automaatne skaleerimine, mis töötab suurepäraselt (meie kogemuse kohaselt). Samas, nagu mujalgi, on ka siin omad nüansid...

Niikaua kui me klastri suurust suurendasime, oli kõik korras, aga mis saab siis, kui klastrit hakkas end vabastama? Probleem on selles, et kaubikute migreerimine (hostide vabastamiseks) on tehniliselt väga keeruline ja ressursside poolest kallis. Kubernetes kasutab täiesti teistsugust lähenemist.

Kaaluge 3-st serverist koosnevat klastrit, millel on juurutamine. Sellel on 6 kausta: nüüd on iga serveri jaoks 2. Millegipärast tahtsime ühe serveri välja lülitada. Selleks kasutame käsku kubectl drain, mis:

  • keelab sellesse serverisse uute kaustade saatmise;
  • kustutab serveris olemasolevad kaustad.

Kuna Kubernetes vastutab kaunade arvu (6) säilitamise eest, on see lihtsalt hakkab uuesti looma neid teistes sõlmedes, kuid mitte sellel, mis on keelatud, kuna see on juba märgitud uute kaustade majutamiseks kättesaamatuks. See on Kubernetese põhimehaanik.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Siiski on siin ka nüanss. Sarnases olukorras on StatefulSeti (juurutamise asemel) toimingud erinevad. Nüüd on meil juba olekupõhine rakendus - näiteks kolm podi MongoDB-ga, millest ühes on mingi probleem (andmed on rikutud või muu viga, mis ei lase podil õigesti käivituda). Ja taas otsustame ühe serveri keelata. Mis juhtub?

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

MongoDB võiks surema, sest see vajab kvoorumit: kolmest installatsioonist koosneva klastri puhul peab toimima vähemalt kaks. Siiski, see ei toimu - tänu PodDisruptionBudget. See parameeter määrab minimaalse nõutava töötavate kaunade arvu. Teades, et üks MongoDB kaustadest enam ei tööta, ja nähes, et PodDisruptionBudget on MongoDB jaoks määratud minAvailable: 2, Kubernetes ei luba teil kausta kustutada.

Alumine rida: selleks, et kaunade liikumine (ja tegelikult ka taasloomine) klastri vabastamisel õigesti toimiks, on vaja konfigureerida PodDisruptionBudget.

Horisontaalne skaleerimine

Vaatleme teist olukorda. Kubernetesis töötab juurutusena rakendus. Kasutajaliiklus tuleb selle kaustadesse (neid on näiteks kolm) ja me mõõdame neis teatud näitajat (näiteks protsessori koormust). Kui koormus suureneb, salvestame selle ajakava järgi ja suurendame taotluste levitamiseks kaunade arvu.

Täna ei pea Kubernetesis seda käsitsi tegema: kaunade arvu automaatne suurendamine/vähendamine on konfigureeritud sõltuvalt mõõdetud koormuse indikaatorite väärtustest.

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Siin on peamised küsimused: mida täpselt mõõta и kuidas tõlgendada saadud väärtused (kaunade arvu muutmise otsuse tegemiseks). Saate mõõta palju:

Automaatne skaleerimine ja ressursside haldamine Kubernetesis (ülevaade ja videoaruanne)

Kuidas seda tehniliselt teha – koguda mõõdikuid jne. — Rääkisin raportis üksikasjalikult Järelevalve ja Kubernetes. Ja peamine nõuanne optimaalsete parameetrite valimiseks on katse!

On KASUTAGE meetodit (Kasutamise küllastus ja vead), mille tähendus on järgmine. Mille alusel on mõtet skaleerida näiteks php-fpm? Arvestades asjaolu, et töötajad hakkavad otsa saama, on see nii ärakasutamine. Ja kui töötajad on läbi ja uusi sidemeid vastu ei võeta, on see juba nii küllastus. Mõlemad parameetrid tuleb mõõta ja sõltuvalt väärtustest tuleb läbi viia skaleerimine.

Selle asemel, et järeldus

Aruandel on jätk: vertikaalse skaleerimise ja õigete ressursside valimise kohta. Ma räägin sellest tulevastes videotes meie YouTube - tellige, et mitte ilma jääda!

Videod ja slaidid

Video etendusest (44 minutit):

Aruande esitlus:

PS

Muud aruanded Kubernetese kohta meie ajaveebis:

Allikas: www.habr.com

Lisa kommentaar