Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

27. aprila na konferenciji Štrajk 2019, u okviru sekcije „DevOps“ dat je izveštaj „Autoskaliranje i upravljanje resursima u Kubernetesu“. Govori o tome kako možete koristiti K8s da biste osigurali visoku dostupnost svojih aplikacija i osigurali vrhunske performanse.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Po tradiciji, sa zadovoljstvom predstavljamo video izvještaja (44 minuta, mnogo informativnije od članka) i glavni sažetak u tekstualnom obliku. Idi!

Analizirajmo temu izvještaja riječ po riječ i krenimo od kraja.

Kubernet

Recimo da imamo Docker kontejnere na našem hostu. Za što? Kako bi se osigurala ponovljivost i izolacija, što zauzvrat omogućava jednostavnu i dobru implementaciju, CI/CD. Imamo mnogo takvih vozila sa kontejnerima.

Šta Kubernetes pruža u ovom slučaju?

  1. Prestajemo da razmišljamo o ovim mašinama i počinjemo da radimo sa "oblakom" klaster kontejnera ili mahune (grupe kontejnera).
  2. Štaviše, čak i ne razmišljamo o pojedinačnim mahunama, već upravljamo višeоveće grupe. Takve primitivima visokog nivoa dozvolite nam da kažemo da postoji predložak za pokretanje određenog radnog opterećenja, a ovdje je potreban broj instanci za njegovo pokretanje. Ako naknadno promijenimo šablon, sve instance će se promijeniti.
  3. Uz pomoć deklarativni API Umjesto izvršavanja niza specifičnih naredbi, opisujemo „strukturu svijeta“ (u YAML-u), koju kreira Kubernetes. I opet: kada se promijeni opis, promijenit će se i njegov stvarni prikaz.

Upravljanje resursima

CPU

Pokrenimo nginx, php-fpm i mysql na serveru. Ove usluge će zapravo imati još više pokrenutih procesa, od kojih svaki zahtijeva računarske resurse:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)
(brojevi na slajdu su "papagaji", apstraktna potreba svakog procesa za računarskom snagom)

Da bi se olakšao rad s ovim, logično je kombinovati procese u grupe (na primjer, sve nginx procese u jednu grupu “nginx”). Jednostavan i očigledan način da to učinite je da svaku grupu stavite u kontejner:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Da biste nastavili, morate zapamtiti šta je kontejner (u Linuxu). Njihova pojava je omogućena zahvaljujući tri ključne karakteristike u kernelu, implementirane dosta davno: mogućnosti, Prostori imena и cgroups. A daljnji razvoj je olakšan drugim tehnologijama (uključujući prikladne „ljuske“ poput Dockera):

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

U kontekstu izvještaja, samo nas zanima cgroups, jer su kontrolne grupe dio funkcionalnosti kontejnera (Docker, itd.) koji implementira upravljanje resursima. Procesi kombinovani u grupe, kako smo želeli, su kontrolne grupe.

Vratimo se CPU zahtjevima za ove procese, a sada za grupe procesa:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)
(Ponavljam da su svi brojevi apstraktni izraz potrebe za resursima)

Istovremeno, sam CPU ima određeni ograničeni resurs (u primjeru ovo je 1000), što svima može nedostajati (zbir potreba svih grupa je 150+850+460=1460). Šta će se dogoditi u ovom slučaju?

Kernel počinje distribuirati resurse i to čini “pošteno”, dajući istu količinu resursa svakoj grupi. Ali u prvom slučaju ih ima više nego što je potrebno (333>150), pa višak (333-150=183) ostaje u rezervi, koji se također ravnomjerno raspoređuje između dva druga kontejnera:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Kao rezultat: prvi kontejner je imao dovoljno resursa, drugi - nije imao dovoljno resursa, treći - nije imao dovoljno resursa. Ovo je rezultat akcija "pošteni" planer u Linuxu - CFS. Njegov rad se može podesiti pomoću zadatka utezi svaki od kontejnera. Na primjer, ovako:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Pogledajmo slučaj nedostatka resursa u drugom kontejneru (php-fpm). Svi resursi kontejnera ravnomjerno su raspoređeni između procesa. Kao rezultat toga, glavni proces radi dobro, ali svi radnici usporavaju, primajući manje od polovine onoga što im je potrebno:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Ovako radi CFS planer. Dalje ćemo zvati težine koje dodjeljujemo kontejnerima zahtjevi. Zašto je to tako - pogledajte dalje.

Pogledajmo cijelu situaciju s druge strane. Kao što znate, svi putevi vode u Rim, a u slučaju računara, do CPU-a. Jedan CPU, mnogo zadataka - potreban vam je semafor. Najjednostavniji način upravljanja resursima je "semafor": jednom procesu su dali fiksno vrijeme pristupa CPU-u, zatim sljedećem, itd.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Ovaj pristup se naziva tvrde kvote (tvrdo ograničenje). Pamtimo to jednostavno kao ograničenja. Međutim, ako rasporedite ograničenja na sve kontejnere, pojavljuje se problem: mysql se vozio cestom i u nekom trenutku je prestala njegova potreba za CPU-om, ali svi ostali procesi su prisiljeni čekati dok CPU idle.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Vratimo se Linux kernelu i njegovoj interakciji sa CPU-om - ukupna slika je sljedeća:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

cgroup ima dvije postavke - u suštini ovo su dva jednostavna "okreta" koja vam omogućavaju da odredite:

  1. težina za kontejner (zahtjevi) je akcija;
  2. postotak ukupnog CPU vremena za rad na kontejnerskim zadacima (ograničenja) je kvota.

Kako izmjeriti CPU?

Postoje različiti načini:

  1. šta papagaji, niko ne zna - svaki put treba pregovarati.
  2. Kamata jasnije, ali relativno: 50% servera sa 4 jezgra i sa 20 jezgara su potpuno različite stvari.
  3. Možete koristiti one koje smo već spomenuli utezi, koje Linux poznaje, ali su i relativne.
  4. Najadekvatnija opcija je mjerenje računarskih resursa u sekundi. One. u sekundama procesorskog vremena u odnosu na sekunde realnog vremena: 1 sekunda procesorskog vremena je data za 1 realnu sekundu - ovo je jedno cijelo CPU jezgro.

Da bi bilo još lakše govoriti, počeli su direktno mjeriti jezgra, što znači isto CPU vrijeme u odnosu na stvarno. Budući da Linux razumije težine, ali ne toliko CPU vrijeme/jezgra, bio je potreban mehanizam za prevođenje s jednog na drugi.

Razmotrimo jednostavan primjer sa serverom sa 3 CPU jezgra, gdje će tri pod-a dobiti težine (500, 1000 i 1500) koje se lako pretvaraju u odgovarajuće dijelove jezgri koji su im dodijeljeni (0,5, 1 i 1,5).

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Ako uzmete drugi server, gdje će biti dvostruko više jezgri (6), i tamo postavite iste podove, distribucija jezgri se može lako izračunati jednostavnim množenjem sa 2 (1, 2 i 3, respektivno). Ali važan momenat se dešava kada se na ovom serveru pojavi četvrti pod, čija će težina, radi pogodnosti, biti 3000. Oduzima deo CPU resursa (pola jezgri), a za preostale podove se preračunavaju (prepolovljavaju):

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Kubernetes i CPU resursi

U Kubernetesu se resursi procesora obično mjere u milliadrax, tj. 0,001 jezgra se uzima kao osnovna težina. (Ista stvar u terminologiji Linux/cgroups naziva se udio CPU-a, iako, preciznije, 1000 milicores = 1024 CPU dionica.) K8s osigurava da ne postavlja više podova na server nego što ima CPU resursa za zbir težina svih podova.

Kako se to dešava? Kada dodate server u Kubernetes klaster, prijavljuje se koliko CPU jezgara ima na raspolaganju. A kada kreirate novi pod, Kubernetes planer zna koliko će jezgara ovom podu trebati. Dakle, pod će biti dodijeljen serveru na kojem ima dovoljno jezgara.

Šta će se desiti ako ne zahtjev je naveden (tj. pod nema definirani broj jezgara koji su mu potrebni)? Hajde da shvatimo kako Kubernetes generalno broji resurse.

Za pod možete odrediti i zahtjeve (CFS planer) i ograničenja (sjećate li se semafora?):

  • Ako su specificirani jednaki, pod je dodijeljen QoS klasa garantovano. Ovaj broj jezgara koji su mu uvijek dostupni je zagarantovan.
  • Ako je zahtjev manji od ograničenja - QoS klasa burstable. One. Očekujemo da pod, na primjer, uvijek koristi 1 jezgro, ali ova vrijednost nije ograničenje za njega: ponekad pod može koristiti više (kada server ima slobodne resurse za ovo).
  • Postoji i QoS klasa najbolji trud — uključuje upravo one mahune za koje zahtjev nije naveden. Sredstva im se daju posljednji.

memorija

S pamćenjem je situacija slična, ali malo drugačija - na kraju krajeva, priroda ovih resursa je drugačija. Općenito, analogija je sljedeća:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Pogledajmo kako se zahtjevi implementiraju u memoriju. Pustite podove da žive na serveru, mijenjajući potrošnju memorije, sve dok jedan od njih ne postane toliko velik da ostane bez memorije. U ovom slučaju, pojavljuje se OOM ubica i ubija najveći proces:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

To nam ne odgovara uvijek, pa je moguće regulisati koji procesi su nam važni i ne treba ih ubijati. Da biste to učinili, koristite parametar oom_score_adj.

Vratimo se QoS klasama CPU-a i napravimo analogiju sa vrijednostima oom_score_adj koje određuju prioritete potrošnje memorije za podove:

  • Najniža vrijednost oom_score_adj za mahunu - -998 - znači da takvu mahunu treba ubiti posljednju, ovo garantovano.
  • Najviša - 1000 - je najbolji trud, takve mahune se prvo ubijaju.
  • Za izračunavanje preostalih vrijednosti (burstable) postoji formula čija se suština svodi na činjenicu da što više resursa kapsula traži, manja je vjerovatnoća da će biti ubijena.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Drugi "okret" - limit_in_bytes - za granice. S njim je sve jednostavnije: jednostavno dodijelimo maksimalnu količinu izdane memorije, a ovdje (za razliku od CPU-a) nema pitanja kako je izmjeriti (memoriju).

Ukupno

Svaki pod u Kubernetesu je dat requests и limits - oba parametra za CPU i memoriju:

  1. na osnovu zahteva radi Kubernetes planer, koji distribuira podove između servera;
  2. na osnovu svih parametara, određuje se QoS klasa pod;
  3. Relativne težine se izračunavaju na osnovu CPU zahtjeva;
  4. CFS planer je konfigurisan na osnovu CPU zahteva;
  5. OOM killer se konfiguriše na osnovu zahteva za memorijom;
  6. „semafor“ je konfigurisan na osnovu CPU ograničenja;
  7. Na osnovu ograničenja memorije, ograničenje je konfigurirano za cgroup.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Općenito, ova slika odgovara na sva pitanja o tome kako se glavni dio upravljanja resursima odvija u Kubernetesu.

Automatsko skaliranje

K8s klaster-autoskaler

Zamislimo da je cijeli klaster već zauzet i da treba kreirati novi pod. Dok se modul ne može pojaviti, visi u statusu na čekanju. Da bi se pojavio, možemo povezati novi server na klaster ili... instalirati cluster-autoscaler, koji će to učiniti umjesto nas: naručiti virtuelnu mašinu od provajdera u oblaku (pomoću API zahtjeva) i spojiti je na klaster , nakon čega će se dodati pod .

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Ovo je automatsko skaliranje Kubernetes klastera, što radi odlično (po našem iskustvu). Međutim, kao i drugdje, i ovdje postoje neke nijanse...

Dokle god smo povećavali veličinu klastera, sve je bilo u redu, ali šta se dešava kada se klaster počeo da se oslobađa? Problem je u tome što je migracija podova (da bi se oslobodili hostovi) vrlo tehnički teška i skupa u smislu resursa. Kubernetes koristi potpuno drugačiji pristup.

Razmotrite klaster od 3 servera koji ima Deployment. Ima 6 podova: sada postoje 2 za svaki server. Iz nekog razloga smo htjeli isključiti jedan od servera. Za to ćemo koristiti naredbu kubectl drain, koji:

  • će zabraniti slanje novih podova na ovaj server;
  • će izbrisati postojeće podove na serveru.

Pošto je Kubernetes odgovoran za održavanje broja podova (6), jednostavno će rekreirati na drugim čvorovima, ali ne i na onom koji je onemogućen, pošto je već označen kao nedostupan za hostovanje novih podova. Ovo je osnovna mehanika za Kubernetes.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Međutim, i ovdje postoji nijansa. U sličnoj situaciji, za StatefulSet (umjesto za Deployment), radnje će biti drugačije. Sada već imamo aplikaciju sa statusom - na primjer, tri pod-a sa MongoDB-om, od kojih jedan ima neku vrstu problema (podaci su se oštetili ili druga greška koja sprječava pod da se ispravno pokrene). I ponovo odlučujemo da onemogućimo jedan server. Šta će se desiti?

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

MongoDB mogao umre jer treba kvorum: za klaster od tri instalacije, najmanje dvije moraju funkcionisati. Međutim, ovo ne dešava se - Hvala za PodDisruptionBudget. Ovaj parametar određuje minimalno potreban broj radnih podova. Znajući da jedan od MongoDB podova više ne radi, i vidjeti da je PodDisruptionBudget postavljen za MongoDB minAvailable: 2, Kubernetes vam neće dozvoliti da izbrišete pod.

Zaključak: da bi kretanje (i zapravo, ponovno kreiranje) podova radilo ispravno kada se klaster pusti, potrebno je konfigurirati PodDisruptionBudget.

Horizontalno skaliranje

Hajde da razmotrimo drugu situaciju. Postoji aplikacija koja radi kao Deployment u Kubernetesu. Korisnički promet dolazi do njegovih podova (na primjer, ima ih tri), a u njima mjerimo određeni indikator (recimo opterećenje CPU-a). Kada se opterećenje poveća, snimamo ga na rasporedu i povećavamo broj podova za distribuciju zahtjeva.

Danas u Kubernetesu to ne treba raditi ručno: automatsko povećanje/smanjenje broja podova konfigurira se ovisno o vrijednostima izmjerenih indikatora opterećenja.

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Glavna pitanja ovdje su: šta tačno meriti и kako protumačiti dobijene vrijednosti (za donošenje odluke o promjeni broja mahuna). Možete izmjeriti mnogo toga:

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvještaj)

Kako to tehnički učiniti - prikupiti metriku itd. — Detaljno sam govorio u izvještaju o Monitoring i Kubernetes. A glavni savjet za odabir optimalnih parametara je eksperiment!

Postoje KORISTI metodu (Zasićenost korištenja i greške), čije je značenje sljedeće. Na osnovu čega ima smisla skalirati, na primjer, php-fpm? Na osnovu činjenice da radnika ponestaje, to je tako iskorištavanje. A ako su radnici prestali i nove veze nisu prihvaćene, to je već zasićenje. Oba ova parametra moraju biti izmjerena, a ovisno o vrijednostima, mora se izvršiti skaliranje.

Umjesto zaključka

Izvještaj ima nastavak: o vertikalnom skaliranju i kako odabrati prave resurse. O tome ću pričati u narednim video snimcima naš YouTube - pretplatite se da ne propustite!

Video zapisi i slajdovi

Video sa nastupa (44 minute):

Prezentacija izvještaja:

PS

Ostali izvještaji o Kubernetesu na našem blogu:

izvor: www.habr.com

Dodajte komentar