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

27. travnja na konferenciji Štrajk 2019, u sklopu sekcije “DevOps” održano je izvješće “Auto-scaling and resource management in Kubernetes”. Govori o tome kako možete koristiti K8s kako biste osigurali visoku dostupnost svojih aplikacija i osigurali vrhunske performanse.

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

Po tradiciji, sa zadovoljstvom predstavljamo video izvještaja (44 minute, mnogo informativnije od članka) i glavni sažetak u obliku teksta. Ići!

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

Kubernetes

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

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

  1. Prestajemo razmišljati o tim strojevima i počinjemo raditi s "oblakom" klaster kontejnera ili mahune (skupine spremnika).
  2. Štoviše, niti ne razmišljamo o pojedinačnim mahunama, već upravljamo višeоveće grupe. Takav primitivci visoke razine dopustite 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 predložak, sve će se instance promijeniti.
  3. S deklarativni API Umjesto izvršavanja niza specifičnih naredbi, opisujemo "strukturu svijeta" (u YAML-u), koju je kreirao Kubernetes. I opet: kad se opis promijeni, promijenit će se i njegov stvarni prikaz.

Upravljanje resursima

CPU

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

Automatsko skaliranje i upravljanje resursima u Kubernetesu (pregled i video izvješće)
(brojevi na slajdu su "papige", apstraktna potreba svakog procesa za računalnom snagom)

Da bi se s tim lakše radilo, logično je procese kombinirati u grupe (na primjer, sve nginx procese u jednu grupu “nginx”). Jednostavan i očigledan način za to je staviti svaku grupu u spremnik:

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

Da biste nastavili, morate se sjetiti što je spremnik (u Linuxu). Njihovo pojavljivanje omogućeno je zahvaljujući tri ključne značajke u kernelu, implementirane prije dosta vremena: sposobnosti, imenskom prostoru и grupama. Daljnji razvoj olakšale su i druge tehnologije (uključujući prikladne "ljuske" poput Dockera):

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

U kontekstu izvješća zanima nas samo grupama, jer su kontrolne grupe dio funkcionalnosti spremnika (Docker i sl.) koji implementira upravljanje resursima. Procesi spojeni u grupe, kao što smo htjeli, 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šće)
(Ponavljam da su svi brojevi apstraktni izraz potrebe za resursima)

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

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

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

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

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

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

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

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

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

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

Ovaj pristup naziva se tvrdim kvotama (tvrdo ograničenje). Zapamtimo to jednostavno kao granice. Međutim, ako raspodijelite ograničenja na sve spremnike, javlja se problem: mysql se vozio po cesti iu nekom trenutku njegova potreba za CPU-om je prestala, ali svi ostali procesi su prisiljeni čekati dok CPU besposlen.

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

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

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

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

  1. težina za kontejner (zahtjevi) je dionice;
  2. postotak ukupnog CPU vremena za rad na zadacima spremnika (ograničenja) je udio.

Kako izmjeriti CPU?

Postoje različiti načini:

  1. što papige, nitko ne zna - svaki put morate pregovarati.
  2. interes jasnije, ali relativno: 50% poslužitelja s 4 jezgre i s 20 jezgri su potpuno različite stvari.
  3. Možete koristiti one već spomenute težina, koje Linux poznaje, ali su i oni relativni.
  4. Najprikladnija opcija je mjerenje računalnih resursa u sekundi. Oni. u sekundama procesorskog vremena u odnosu na sekunde stvarnog vremena: 1 sekunda procesorskog vremena dana je za 1 stvarnu sekundu - ovo je jedna cijela CPU jezgra.

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

Razmotrimo jednostavan primjer s poslužiteljem s 3 CPU jezgre, gdje će trima modulima biti dodijeljene težine (500, 1000 i 1500) koje se lako pretvaraju u odgovarajuće dijelove jezgri koje su im dodijeljene (0,5, 1 i 1,5).

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

Ako uzmete drugi poslužitelj, gdje će biti dvostruko više jezgri (6), i tamo postavite iste mahune, distribucija jezgri može se lako izračunati jednostavnim množenjem s 2 (1, 2 i 3, respektivno). Ali važan trenutak se događa kada se na ovom poslužitelju pojavi četvrti pod, čija će težina, radi praktičnosti, biti 3000. Oduzima dio CPU resursa (polovica jezgri), a za preostale podove se preračunavaju (prepolovljuju):

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

Kubernetes i CPU resursi

U Kubernetesu se CPU resursi obično mjere u milliadrax, tj. Kao osnovna težina uzima se 0,001 jezgre. (Ista stvar u terminologiji Linux/cgroups naziva se CPU udio, iako, točnije, 1000 milicores = 1024 CPU udio.) K8s osigurava da ne postavlja više podova na poslužitelj nego što ima CPU resursa za zbroj težina svih podova.

Kako se to događa? Kada dodate poslužitelj u Kubernetes klaster, javlja se koliko CPU jezgri ima na raspolaganju. A kada kreirate novi pod, Kubernetes planer zna koliko će jezgri trebati ovom podu. Stoga će pod biti dodijeljen poslužitelju na kojem ima dovoljno jezgri.

Što će se dogoditi ako ne zahtjev je naveden (tj. modul nema definiran broj jezgri koje treba)? Hajdemo shvatiti kako Kubernetes općenito broji resurse.

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

  • Ako su navedeni jednaki, tada se modulu dodjeljuje QoS klasa garantiran. Zajamčen je ovaj broj uvijek dostupnih jezgri.
  • Ako je zahtjev manji od ograničenja - QoS klasa rasprsnuti. Oni. Očekujemo da će pod, na primjer, uvijek koristiti 1 jezgru, ali ova vrijednost nije ograničenje za nju: ponekad pod može koristiti više (kada poslužitelj ima slobodne resurse za to).
  • Postoji i QoS klasa najbolji trud — uključuje upravo one mahune za koje zahtjev nije naveden. Resursi im se daju zadnji.

memorija

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

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

Pogledajmo kako se zahtjevi implementiraju u memoriju. Neka mahune žive na poslužitelju, mijenjajući potrošnju memorije, sve dok jedna od njih ne postane toliko velika da joj ponestane memorije. U ovom slučaju pojavljuje se OOM ubojica i ubija najveći proces:

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

To nam ne odgovara uvijek, pa je moguće regulirati koji su nam procesi važni, a ne smiju se ubijati. Da biste to učinili, upotrijebite parametar oom_core_adj.

Vratimo se QoS klasama CPU-a i povucimo analogiju s vrijednostima oom_score_adj koje određuju prioritete potrošnje memorije za mahune:

  • Najniža vrijednost oom_score_adj za mahunu - -998 - znači da takva mahuna treba biti ubijena zadnja, ovo garantiran.
  • Najveći - 1000 - je najbolji trud, takve mahune se prvo ubijaju.
  • Za izračun preostalih vrijednosti (rasprsnuti) postoji formula čija se bit svodi na činjenicu da što je više resursa mahuna zatražila, manja je vjerojatnost da će biti ubijena.

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

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

Ukupno

Svaka mahuna u Kubernetesu je data requests и limits - oba parametra za CPU i memoriju:

  1. na temelju zahtjeva radi Kubernetes planer koji distribuira podove među poslužiteljima;
  2. na temelju svih parametara određuje se QoS klasa modula;
  3. Relativne težine izračunavaju se na temelju CPU zahtjeva;
  4. CFS planer je konfiguriran na temelju CPU zahtjeva;
  5. OOM killer je konfiguriran na temelju memorijskih zahtjeva;
  6. "semafor" je konfiguriran na temelju CPU ograničenja;
  7. Na temelju ograničenja memorije, ograničenje je konfigurirano za cgroup.

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

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

Automatsko skaliranje

K8s klaster-autoscaler

Zamislimo da je cijeli klaster već zauzet i da je potrebno kreirati novi pod. Dok se pod ne može pojaviti, visi u statusu U tijeku. Da bi se pojavio, možemo spojiti novi poslužitelj na klaster ili... instalirati cluster-autoscaler, koji će to učiniti umjesto nas: naručiti virtualni stroj od cloud providera (koristeći API zahtjev) i spojiti ga na klaster , nakon čega će se dodati mahuna .

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

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

Sve dok smo povećavali veličinu klastera, sve je bilo u redu, ali što se događa kada klaster počeo se oslobađati? Problem je u tome što je migracija podova (za oslobađanje hostova) vrlo tehnički teška i skupa u smislu resursa. Kubernetes koristi potpuno drugačiji pristup.

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

  • zabranit će slanje novih mahuna na ovaj poslužitelj;
  • će izbrisati postojeće mahune na poslužitelju.

Budući da je Kubernetes odgovoran za održavanje broja mahuna (6), jednostavno ponovno će stvoriti na drugim čvorovima, ali ne na onom koji je onemogućen, budući da je već označen kao nedostupan za hosting novih modula. Ovo je temeljna mehanika za Kubernetes.

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

Međutim, i ovdje postoji jedna nijansa. U sličnoj situaciji, za StatefulSet (umjesto za Deployment), radnje će biti drugačije. Sada već imamo aplikaciju sa statusom - na primjer, tri mahune s MongoDB-om, od kojih jedna ima nekakav problem (podaci su oštećeni ili postoji neka druga pogreška koja onemogućuje pravilno pokretanje mahunarke). I opet odlučujemo onemogućiti jedan poslužitelj. Što će se dogoditi?

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

MongoDB mogao umrijeti jer treba kvorum: za klaster od tri instalacije moraju funkcionirati najmanje dvije. Međutim, ovo ne događa se - zahvaljujući PodDisruptionBudget. Ovaj parametar određuje minimalno potreban broj radnih mahuna. Znajući da jedan od MongoDB modula više ne radi i vidjeti da je PodDisruptionBudget postavljen za MongoDB minAvailable: 2, Kubernetes vam neće dopustiti da izbrišete pod.

Zaključak: kako bi kretanje (i zapravo ponovno stvaranje) mahuna radilo ispravno kada se klaster otpusti, potrebno je konfigurirati PodDisruptionBudget.

Horizontalno skaliranje

Razmotrimo drugu situaciju. Postoji aplikacija koja se izvodi kao implementacija u Kubernetesu. Korisnički promet dolazi u svoje podove (na primjer, ima ih tri), a mi u njima mjerimo određeni pokazatelj (recimo opterećenje CPU-a). Kada se opterećenje poveća, bilježimo ga na raspored i povećavamo broj podova za distribuciju zahtjeva.

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

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

Glavna pitanja ovdje su: što točno mjeriti и kako protumačiti dobivene vrijednosti (za donošenje odluke o promjeni broja mahuna). Možete mjeriti puno:

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

Kako to učiniti tehnički - prikupiti metriku itd. — Govorio sam detaljno u izvješću o Praćenje i Kubernetes. A glavni savjet za odabir optimalnih parametara je eksperiment!

Tu je UPOTREBNA metoda (Zasićenost korištenja i pogreške), čije je značenje sljedeće. Na temelju čega ima smisla skalirati npr. php-fpm? Na temelju činjenice da radnika ponestaje, ovo je korišćenje. A ako su radnici gotovi i nove veze nisu prihvaćene, to je već zasićenje. Oba ova parametra moraju se mjeriti, a ovisno o vrijednostima potrebno je izvršiti skaliranje.

Umjesto zaključka

Izvješće ima nastavak: o okomitom skaliranju i kako odabrati prave resurse. O tome ću govoriti u budućim videima naš YouTube - pretplatite se da ne propustite!

Video zapisi i slajdovi

Video s nastupa (44 minute):

Prezentacija izvješća:

PS

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

Izvor: www.habr.com

Dodajte komentar