Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Apirilaren 27an, jardunaldietan 2019ko greba, "DevOps" atalaren barruan, "Autoscaling and resource management in Kubernetes" txostena eman zen. K8ak nola erabil ditzakezun zure aplikazioen erabilgarritasun handia bermatzeko eta errendimendu gorena ziurtatzeko moduari buruz hitz egiten du.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Tradizioz, pozik aurkezten dugu erreportajearen bideoa (44 minutu, artikulua baino askoz argigarriagoa) eta laburpen nagusia testu moduan. Joan!

Azter dezagun hitzez hitz txostenaren gaia eta has gaitezen amaieratik.

Kubernetes

Demagun Docker edukiontziak ditugula gure ostalarian. Zertarako? Errepikagarritasuna eta isolamendua bermatzeko, eta horrek hedapen erraz eta ona ahalbidetzen du, CI/CD. Horrelako ibilgailu asko ditugu edukiontziekin.

Zer eskaintzen du Kubernetes-ek kasu honetan?

  1. Makina hauetan pentsatzeari utzi eta "hodeiarekin" lanean hasten gara edukiontzi multzoa edo lekak (ontzi-taldeak).
  2. Gainera, ez dugu ontzi indibidualetan pentsatzen, gehiago kudeatzen baizikΠΎtalde handiagoak. Halakoak goi-mailako primitiboak utz iezaguzu esan lan-karga jakin bat exekutatzeko txantiloi bat dagoela, eta hona hemen exekutatzeko beharrezkoa den instantzia kopurua. Gero txantiloia aldatzen badugu, instantzia guztiak aldatuko dira.
  3. With API deklaratiboa Komando zehatzen sekuentzia bat exekutatu beharrean, Kubernetes-ek sortutako "munduaren egitura" (YAML-n) deskribatzen dugu. Eta berriro: deskribapena aldatzen denean, bere benetako pantaila ere aldatuko da.

Baliabideen kudeaketa

CPU

Exekutatu ditzagun nginx, php-fpm eta mysql zerbitzarian. Zerbitzu hauek are prozesu gehiago izango dituzte martxan, eta horietako bakoitzak informatika baliabideak behar ditu:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)
(Diapositibako zenbakiak "loroak" dira, prozesu bakoitzaren behar abstraktua konputatzeko ahalmena)

Honekin lan egitea errazteko, logikoa da prozesuak taldetan konbinatzea (adibidez, nginx prozesu guztiak "nginx") talde batean. Horretarako modu erraz eta ageriko bat talde bakoitza edukiontzi batean jartzea da:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Jarraitzeko, edukiontzi bat zer den gogoratu behar duzu (Linuxen). Haien agerpena nukleoaren hiru ezaugarri nagusiei esker egin zen, aspaldi inplementatuta: gaitasun, Izen-leku ΠΈ ctaldeak. Eta garapen gehiago beste teknologia batzuek (Docker bezalako "shell" erosoak barne):

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Txostenaren testuinguruan, soilik interesatzen zaigu ctaldeak, kontrol taldeak baliabideen kudeaketa inplementatzen duen edukiontzien (Docker, etab.) funtzionalitatearen zatia direlako. Taldetan konbinatutako prozesuak, nahi genuen bezala, kontrol taldeak dira.

Itzuli gaitezen PUZaren eskakizunetara prozesu hauetarako, eta orain prozesu taldeetarako:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)
(Errepikatzen dut zenbaki guztiak baliabideen beharraren adierazpen abstraktua direla)

Aldi berean, CPUak berak baliabide finitu jakin bat du (adibidean hau 1000 da), denek falta izan dezaketena (talde guztien beharren batura 150+850+460=1460 da). Zer gertatuko da kasu honetan?

Nukleoa baliabideak banatzen hasten da eta β€œnahiko” egiten du, talde bakoitzari baliabide kopuru bera emanez. Baina lehen kasuan, behar baino gehiago daude (333>150), beraz, soberakina (333-150=183) erreserban geratzen da, eta hori ere berdin banatuta dago beste bi ontziren artean:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Ondorioz: lehen edukiontziak baliabide nahikoak zituen, bigarrenak -ez zituen baliabide nahikorik, hirugarrenak- ez zituen baliabide nahikorik. Hau ekintzen ondorioa da Linux-en programatzaile "zintzoa". - CFS. Bere funtzionamendua esleipena erabiliz egokitu daiteke pisuak ontzietako bakoitza. Adibidez, honela:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Ikus dezagun bigarren edukiontzian (php-fpm) baliabide faltaren kasua. Edukiontzien baliabide guztiak berdin banatzen dira prozesuen artean. Ondorioz, maisu-prozesuak ondo funtzionatzen du, baina langile guztiek moteldu egiten dute, behar dutenaren erdia baino gutxiago jasotzen dute:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Honela funtzionatzen du CFS programatzaileak. Are gehiago, edukiontziei esleitzen dizkiegun pisuei deituko diegu eskaerak. Zergatik den horrela - ikusi gehiago.

Ikus dezagun egoera guztia beste alde batetik. Dakizuenez, bide guztiek Erromara eramaten dute, eta ordenagailu baten kasuan, CPUra. CPU bat, zeregin asko - semaforo bat behar duzu. Baliabideak kudeatzeko modurik errazena β€œsemaforoa” da: prozesu bati CPUrako sarbide-denbora finkoa ematen zioten, gero hurrengoari, etab.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Ikuspegi honi kuota gogorrak deitzen zaio (muga gogorra). Gogora dezagun besterik gabe mugak. Hala ere, edukiontzi guztietan mugak banatzen badituzu, arazo bat sortzen da: mysql errepidean zehar gidatzen ari zen eta uneren batean CPUren beharra amaitu zen, baina beste prozesu guztiak CPUra arte itxaron behartuta daude. alferrik.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Itzuli gaitezen Linux kernelera eta CPUarekin duen elkarrekintzara - irudi orokorra honakoa da:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

cgroup-ek bi ezarpen ditu - funtsean, hauek zehazten uzten duten bi "bira" sinple dira:

  1. edukiontzirako pisua (eskaerak) da akzioak;
  2. Edukiontzi-zereginetan (mugak) lan egiteko CPU denbora osoaren ehunekoa da quota.

Nola neurtu CPU?

Modu desberdinak daude:

  1. Zer da loroak, inork ez daki - aldi bakoitzean negoziatu behar duzu.
  2. interes argiagoa, baina erlatiboa: 50 nukleo eta 4 nukleo dituen zerbitzari baten %20 gauza guztiz desberdinak dira.
  3. Lehen aipatutakoak erabil ditzakezu pisuak, Linuxek ezagutzen duena, baina erlatiboak ere badira.
  4. Aukerarik egokiena baliabide informatikoak neurtzea da segundoak. Horiek. prozesadorearen denboraren segundotan denbora errealeko segundotan: segundo erreal bakoitzeko prozesadorearen denbora segundo 1 eman zen - hau CPU-nukleo oso bat da.

Hitz egitea are errazago egiteko, zuzenean neurtzen hasi ziren nukleoak, hauen arabera, CPU denbora bera benetakoarekiko. Linux-ek pisuak ulertzen dituenez, baina ez hainbeste CPU denbora/nukleoak, mekanismo bat behar zen batetik bestera itzultzeko.

Demagun adibide sinple bat 3 CPU nukleo dituen zerbitzari batekin, non hiru podi pisuak emango zaizkien (500, 1000 eta 1500), haiei esleitutako nukleoei dagozkien zatietara erraz bihurtzen direnak (0,5, 1 eta 1,5).

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Bigarren zerbitzari bat hartuz gero, non nukleoen bikoitza egongo den (6), eta hor leka berdinak jartzen badituzu, nukleoen banaketa erraz kalkula daiteke 2z biderkatuz (1, 2 eta 3, hurrenez hurren). Baina une garrantzitsu bat gertatzen da zerbitzari honetan laugarren pod bat agertzen denean, zeinaren pisua, erosotasunerako, 3000koa izango da. CPU baliabideen zati bat kentzen du (nukleoen erdia), eta gainerako podetan berriz kalkulatzen dira (erdira):

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Kubernetes eta CPU baliabideak

Kubernetesen, CPU baliabideak normalean neurtzen dira miliadrax, hau da. 0,001 nukleo hartzen dira oinarrizko pisu gisa. (Linux/cgroups terminologian gauza bera CPU partekatzea deitzen da, nahiz eta, zehatzago, 1000 milicore = 1024 CPU partekatzea). K8s-ek ziurtatzen du ez duela zerbitzarian ontzi gehiago jartzen PUZ-baliabideak dauden baino ontzi guztien pisuen baturarako.

Nola gertatzen da hau? Kubernetes kluster batean zerbitzari bat gehitzen duzunean, zenbat CPU-nukleo dituen eskuragarri jakinaraziko da. Eta pod berri bat sortzerakoan, Kubernetes programatzaileak badaki zenbat nukleo beharko dituen pod honek. Horrela, pod-a nahikoa nukleo dagoen zerbitzari bati esleituko zaio.

Zer gertatuko da baldin ez eskaera zehaztuta dago (hau da, podak ez du behar dituen nukleo kopuru zehazturik)? Ikus dezagun Kubernetes-ek orokorrean baliabideak nola zenbatzen dituen.

Pod baterako eskaerak (CFS programatzailea) eta mugak (gogoratzen al duzu semaforoa?):

  • Berdinak zehazten badira, QoS klase bat esleitzen zaio podari bermatzen. Beti eskuragarri dituen nukleo kopuru hori bermatuta dago.
  • Eskaera muga baino txikiagoa bada - QoS klasea lehergarria. Horiek. Esate baterako, pod batek beti nukleo 1 erabiltzea espero dugu, baina balio hau ez da horretarako muga bat: batzuetan podak gehiago erabil dezake (zerbitzariak horretarako doako baliabideak dituenean).
  • QoS klase bat ere badago ahalegin onena β€” Eskaera zehazten ez den lekak barne hartzen ditu. Baliabideak azkenengo ematen zaizkie.

ΠŸΠ°ΠΌΡΡ‚ΡŒ

Memoriarekin, egoera antzekoa da, baina zertxobait ezberdina - azken finean, baliabide horien izaera ezberdina da. Oro har, analogia hau da:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Ikus dezagun nola inplementatzen diren eskaerak memorian. Utzi lekak zerbitzarian bizi, memoria-kontsumoa aldatuz, haietako bat hain handia izan arte, non memoria agortu arte. Kasu honetan, OOM hiltzailea agertzen da eta prozesu handiena hiltzen du:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Hau ez zaigu beti komeni, beraz, guretzat garrantzitsuak diren eta hil behar ez diren zein prozesu diren arautu daiteke. Horretarako, erabili parametroa oom_score_adj.

Itzuli PUZaren QoS klaseetara eta marraz ditzagun analogia bat pods-en memoria-kontsumoaren lehentasunak zehazten dituzten oom_score_adj balioekin:

  • Pod baten oom_score_adj baliorik baxuenak -998 - esan nahi du pod bat azkenik hil behar dela, hau bermatzen.
  • Altuena - 1000 - da ahalegin onena, horrelako lekak hiltzen dira lehenik.
  • Gainerako balioak kalkulatzeko (lehergarria) formula bat dago, zeinaren funtsa leka batek zenbat eta baliabide gehiago eskatu, orduan eta aukera gutxiago hiltzeko.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Bigarren "bira" - muga_bytetan - mugak egiteko. Harekin, dena errazagoa da: igorritako memoria kopuru maximoa esleitzen dugu, eta hemen (PUZak ez bezala) ez dago nola neurtu (memoria).

Guztira

Kubernetes-en pod bakoitza ematen da requests ΠΈ limits - CPU eta memoriaren bi parametroak:

  1. eskaeren arabera, Kubernetes programatzaileak funtzionatzen du, zerbitzarien artean lekak banatzen dituena;
  2. parametro guztietan oinarrituta, pod-aren QoS klasea zehazten da;
  3. Pisu erlatiboak CPU eskaeren arabera kalkulatzen dira;
  4. CFS programatzailea CPU eskaeren arabera konfiguratzen da;
  5. OOM killer memoria-eskaeretan oinarrituta konfiguratzen da;
  6. "semaforoa" konfiguratzen da CPU mugen arabera;
  7. Memoria-mugetan oinarrituta, muga bat konfiguratzen da cgroup-erako.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Oro har, irudi honek Kubernetesen baliabideen kudeaketaren zati nagusia nola gertatzen den buruzko galdera guztiei erantzuten die.

Autoeskalatzea

K8s cluster-autoscaler

Imajina dezagun kluster osoa dagoeneko okupatuta dagoela eta pod berri bat sortu behar dela. Pod-a agertu ezin den bitartean, egoeran zintzilikatzen da Pendiente. Ager dadin, zerbitzari berri bat konektatu dezakegu klusterera edo... cluster-autoscaler instalatu eta horrek egingo diguna: hodeiko hornitzailetik makina birtual bat eskatu (API eskaera bat erabiliz) eta klusterera konektatu. , ondoren leka gehituko da .

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Hau Kubernetes klusterraren eskalatze automatikoa da, bikain funtzionatzen duena (gure esperientziaren arabera). Hala ere, beste leku batzuetan bezala, hemen badaude Γ±abardura batzuk...

Klusterren tamaina handitzen genuen bitartean, dena ondo zegoen, baina zer gertatzen da kluster denean askatzen hasi zen? Arazoa da pods migratzea (ostalariak askatzeko) teknikoki oso zaila eta garestia dela baliabideei dagokienez. Kubernetes-ek guztiz bestelako ikuspegia erabiltzen du.

Demagun Inplementazioa duen 3 zerbitzariko multzo bat. 6 pod ditu: orain 2 daude zerbitzari bakoitzeko. Zerbaitegatik zerbitzarietako bat itzali nahi izan dugu. Horretarako komandoa erabiliko dugu kubectl drain, zeina:

  • zerbitzari honetara pod berriak bidaltzea debekatuko du;
  • zerbitzarian dauden lekak ezabatuko ditu.

Kubernetes lek kopurua mantentzeaz arduratzen denez (6), besterik gabe birsortuko du beste nodo batzuetan, baina ez desgaituta dagoenean, jada erabilgarri gisa markatuta baitago pod berriak ostatatzeko. Hau Kubernetesentzako oinarrizko mekanika da.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Hala ere, hemen ere badago Γ±abardura bat. Antzeko egoera batean, StatefulSet-erako (Deployment-en ordez), ekintzak desberdinak izango dira. Orain dagoeneko badugu egoera-aplikazio bat - adibidez, hiru pod MongoDBrekin, horietako batek nolabaiteko arazoa du (datuak hondatu egin dira edo poda behar bezala abiatzea eragozten duen beste errore bat). Eta berriro zerbitzari bat desgaitzea erabakitzen dugu. Zer gertatuko da?

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

MongoDB liteke hil, quoruma behar duelako: hiru instalazioko multzo baterako, gutxienez bik funtzionatu behar dute. Hala ere, hau ez da gertatzen - eskerrik asko PodDisruptionBudget. Parametro honek lan egiteko behar den gutxieneko kopurua zehazten du. MongoDB leketako bat jada ez dagoela funtzionatzen jakitea eta PodDisruptionBudget MongoDBrako ezarrita dagoela ikusita minAvailable: 2, Kubernetes-ek ez dizu pod bat ezabatzen utziko.

Beheko lerroa: klusterrak askatzen direnean poden mugimenduak (eta, hain zuzen ere, birsortzeak) behar bezala funtziona dezan, beharrezkoa da PodDisruptionBudget konfiguratzea.

Eskalatze horizontala

Azter dezagun beste egoera bat. Kubernetesen Deployment gisa exekutatzen ari da aplikazio bat. Erabiltzaileen trafikoa bere podetara iristen da (adibidez, hiru daude), eta horietan adierazle jakin bat neurtzen dugu (esan, CPU karga). Karga handitzen denean, programazio batean grabatzen dugu eta eskaerak banatzeko pods kopurua handitzen dugu.

Gaur egun Kubernetesen ez da hori eskuz egin behar: karga-adierazleen balioen arabera, lek kopuruaren igoera/gutxitze automatikoa konfiguratzen da.

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Hemen galdera nagusiak hauek dira: zer neurtu zehazki ΠΈ nola interpretatu lortutako balioak (leka kopurua aldatzeko erabakia hartzeko). Asko neurtu dezakezu:

Autoeskala eta baliabideen kudeaketa Kubernetes-en (berrikuspena eta bideo-txostena)

Nola egin hau teknikoki - bildu metrika, etab. β€” Txostenean zehatz-mehatz hitz egin nuen Monitorizazioa eta Kubernetes. Eta parametro optimoak aukeratzeko aholku nagusia da esperimentua!

Ez dago ERABILI metodoa (Erabilera-saturazioa eta akatsak), zeinaren esanahia honako hau da. Zein oinarritan dago zentzua eskalatzeak, adibidez, php-fpm? Langileak agortzen ari direla oinarri, hau da erabilera. Eta langileak amaitu eta konexio berriak onartzen ez badira, hau jada saturazioa. Bi parametro horiek neurtu behar dira, eta balioen arabera eskalatzea egin behar da.

Horren ordez Ondorio baten

Txostenak jarraipena du: eskalatze bertikalari buruz eta baliabide egokiak nola hautatu. Honetaz hitz egingo dut hurrengo bideoetan gure YouTube - Harpidetu, galdu ez dezazun!

Bideoak eta diapositibak

Emanaldiko bideoa (44 minutu):

Txostenaren aurkezpena:

PS

Kubernetes-i buruzko beste erreportaje batzuk gure blogean:

Iturria: www.habr.com

Gehitu iruzkin berria