Kradnúť: kto kradne procesorový čas z virtuálnych strojov

Kradnúť: kto kradne procesorový čas z virtuálnych strojov

Ahoj! Chcem vám jednoducho povedať o mechanizme kradnutia vo virtuálnych strojoch a o niektorých nezjavných artefaktoch, ktoré sa nám podarilo zistiť počas jeho výskumu, do ktorého som sa musel ponoriť ako technický riaditeľ cloudovej platformy. Cloudové riešenia Mail.ru. Platforma beží na KVM.

Čas ukradnutia CPU je čas, počas ktorého virtuálny stroj neprijíma prostriedky procesora na svoje vykonanie. Tento čas sa počíta iba v hosťujúcich operačných systémoch vo virtualizačných prostrediach. Dôvody, kam idú tieto najviac pridelené zdroje, ako v živote, sú veľmi nejasné. Ale rozhodli sme sa na to prísť a dokonca sme vykonali niekoľko experimentov. Nie je to tak, že teraz vieme všetko o krádeži, ale teraz vám povieme niečo zaujímavé.

1. Čo je kradnúť

Kradnúť je teda metrika, ktorá indikuje nedostatok času procesora pre procesy vo virtuálnom stroji. Ako je opísané v záplate jadra KVMStealth je čas, počas ktorého hypervízor vykonáva iné procesy v hostiteľskom OS, aj keď zaradil proces virtuálneho počítača na spustenie. To znamená, že krádež sa vypočíta ako rozdiel medzi časom, keď je proces pripravený na vykonanie, a časom, keď je procesu pridelený čas procesora.

Jadro virtuálneho stroja dostane metriku krádeže od hypervízora. Hypervízor zároveň presne nešpecifikuje, aké ďalšie procesy beží, jednoducho hovorí „keď som zaneprázdnený, nemôžem vám dať čas“. Na KVM bola pridaná podpora pre výpočet krádeže náplasti. Sú tu dva kľúčové body:

  • Virtuálny stroj sa dozvie o krádeži od hypervízora. To znamená, že z pohľadu strát ide pre procesy na samotnom virtuálnom stroji o nepriame meranie, ktoré môže podliehať rôznym skresleniam.
  • Hypervízor nezdieľa s virtuálnym strojom informácie o tom, čo ešte robí – hlavné je, že tomu nevenuje čas. Z tohto dôvodu samotný virtuálny stroj nedokáže detekovať skreslenia v ukazovateli krádeže, čo by sa dalo posúdiť podľa povahy konkurenčných procesov.

2. Čo ovplyvňuje kradnúť

2.1. Ukradnúť výpočet

Ukradnúť sa v podstate počíta približne rovnako ako normálny čas využitia CPU. Nie je veľa informácií o tom, ako sa zvažuje recyklácia. Pravdepodobne preto, že väčšina ľudí považuje túto otázku za samozrejmú. Ale sú tu aj úskalia. Aby ste sa zoznámili s týmto procesom, môžete si prečítať článok Brendana Gregga: dozviete sa o mnohých nuansách pri výpočte využitia a o situáciách, kedy bude tento výpočet chybný z nasledujúcich dôvodov:

  • Procesor sa prehrieva, čo spôsobuje preskakovanie cyklov.
  • Zapnutie/vypnutie funkcie turbo boost, ktorá mení frekvenciu procesora.
  • Zmena dĺžky časového úseku, ku ktorej dochádza pri používaní technológií na úsporu energie procesora, ako je napríklad SpeedStep.
  • Problém s výpočtom priemeru: odhad využitia jednej minúty na 80 % môže zakryť krátkodobý nárast o 100 %.
  • Uzamknutie rotácie spôsobí, že sa procesor získa späť, ale používateľský proces nezaznamená žiadny pokrok v jeho vykonávaní. Výsledkom bude, že vypočítané využitie procesora procesom bude stopercentné, hoci proces nebude fyzicky spotrebovať čas procesora.

Nenašiel som článok popisujúci podobný výpočet pre krádež (ak viete, podeľte sa oň v komentároch). Ale podľa zdrojového kódu je mechanizmus výpočtu rovnaký ako pri recyklácii. Jednoducho, v jadre je pridaný ďalší čítač, priamo pre proces KVM (proces virtuálneho stroja), ktorý počíta dobu čakania procesu KVM na čas CPU. Počítadlo berie informácie o procesore z jeho špecifikácie a kontroluje, či sú všetky jeho tiky využívané procesom virtuálneho stroja. Ak je to všetko, potom predpokladáme, že procesor bol obsadený iba procesom virtuálneho stroja. V opačnom prípade informujeme, že procesor robil niečo iné, objavila sa krádež.

Proces počítania krádeží podlieha rovnakým problémom ako bežné počítanie recyklácie. Nehovorím, že sa takéto problémy objavujú často, no vyzerajú odrádzajúc.

2.2. Typy virtualizácie na KVM

Všeobecne povedané, existujú tri typy virtualizácie, z ktorých všetky sú podporované KVM. Mechanizmus kradnutia môže závisieť od typu virtualizácie.

preklad. V tomto prípade funguje operačný systém virtuálneho stroja s fyzickými hypervízorovými zariadeniami asi takto:

  1. Hosťovský operačný systém odošle príkaz svojmu hosťovskému zariadeniu.
  2. Hosťovský ovládač zariadenia prijme príkaz, vygeneruje požiadavku pre BIOS zariadenia a odošle ju hypervízoru.
  3. Proces hypervízora prekladá príkaz na príkaz pre fyzické zariadenie, vďaka čomu je okrem iného bezpečnejšie.
  4. Ovládač fyzického zariadenia prijme upravený príkaz a odošle ho samotnému fyzickému zariadeniu.
  5. Výsledky vykonávania príkazov idú späť po rovnakej ceste.

Výhodou prekladu je, že umožňuje emulovať akékoľvek zariadenie a nevyžaduje špeciálnu prípravu jadra operačného systému. Za to však musíte zaplatiť v prvom rade rýchlosťou.

Hardvérová virtualizácia. V tomto prípade zariadenie na hardvérovej úrovni rozumie príkazom z operačného systému. Toto je najrýchlejší a najlepší spôsob. Bohužiaľ, nie je podporovaný všetkými fyzickými zariadeniami, hypervízormi a hosťujúcimi operačnými systémami. V súčasnosti sú hlavnými zariadeniami, ktoré podporujú hardvérovú virtualizáciu, procesory.

Paravirtualizácia. Najbežnejšia možnosť virtualizácie zariadení na KVM a vo všeobecnosti najbežnejší režim virtualizácie pre hosťujúce operačné systémy. Jeho zvláštnosťou je, že práca s niektorými podsystémami hypervízora (napríklad so sieťovým alebo diskovým zásobníkom) alebo prideľovanie pamäťových stránok prebieha pomocou API hypervízora bez prekladu nízkoúrovňových príkazov. Nevýhodou tohto spôsobu virtualizácie je, že jadro hosťujúceho operačného systému musí byť upravené tak, aby mohlo komunikovať s hypervízorom pomocou tohto API. To sa však zvyčajne rieši inštaláciou špeciálnych ovládačov do hosťujúceho operačného systému. V KVM sa toto API nazýva virtio API.

Pri paravirtualizácii sa v porovnaní s vysielaním výrazne znižuje cesta k fyzickému zariadeniu odosielaním príkazov priamo z virtuálneho stroja do procesu hypervízora na hostiteľovi. To vám umožní urýchliť vykonávanie všetkých pokynov vo virtuálnom stroji. V KVM to robí virtio API, ktoré funguje len pre určité zariadenia, ako je sieťový alebo diskový adaptér. To je dôvod, prečo sú ovládače virtio nainštalované vo virtuálnych strojoch.

Nevýhodou tohto zrýchlenia je, že nie všetky procesy, ktoré bežia vo virtuálnom stroji, v ňom zostávajú. To vytvára niektoré špeciálne efekty, ktoré môžu mať za následok vznik kradnutia. Odporúčam začať podrobné štúdium tejto problematiky s API pre virtuálne I/O: virtio.

2.3. "Spravodlivé" plánovanie

Virtuálny stroj na hypervízore je v skutočnosti obyčajný proces, ktorý sa riadi zákonmi plánovania (distribúcia zdrojov medzi procesmi) v jadre Linuxu, takže sa naň pozrime bližšie.

Linux používa takzvaný CFS, Completely Fair Scheduler, ktorý sa stal predvoleným plánovačom od jadra 2.6.23. Na pochopenie tohto algoritmu si môžete prečítať architektúru jadra Linuxu alebo zdrojový kód. Podstatou CFS je rozdelenie času procesora medzi procesy v závislosti od dĺžky ich vykonávania. Čím viac času CPU proces vyžaduje, tým menej času CPU dostane. To zaisťuje, že všetky procesy sú vykonávané „férovo“ – aby jeden proces neustále nezaberal všetky procesory a mohli sa vykonávať aj iné procesy.

Niekedy táto paradigma vedie k zaujímavým artefaktom. Dlhoroční používatelia Linuxu si pravdepodobne pamätajú zamrznutie bežného textového editora na pracovnej ploche pri spustení aplikácií náročných na zdroje, ako je kompilátor. Stalo sa to preto, že úlohy nenáročné na zdroje v desktopových aplikáciách súťažili s úlohami náročnými na zdroje, ako je napríklad kompilátor. CFS si myslí, že je to nespravodlivé, a preto pravidelne zastavuje textový editor a necháva procesor, aby riešil úlohy kompilátora. Toto bolo opravené pomocou mechanizmu sched_autogroup, ale mnoho ďalších funkcií distribúcie procesorového času medzi úlohami zostalo. V skutočnosti to nie je príbeh o tom, aké zlé je všetko v CFS, ale pokus upozorniť na skutočnosť, že „spravodlivé“ rozdelenie času procesora nie je najtriviálnejšia úloha.

Ďalším dôležitým bodom v plánovači je preempcia. Je to nevyhnutné na to, aby sa z procesora odstránil snickering proces a nechali ostatní pracovať. Proces vysunutia sa nazýva prepínanie kontextu. V tomto prípade sa zachová celý kontext úlohy: stav zásobníka, registrov atď., po ktorom je proces odoslaný čakať a na jeho miesto nastupuje ďalší. Toto je nákladná operácia pre OS a používa sa len zriedka, ale vo svojej podstate na tom nie je nič zlé. Časté prepínanie kontextu môže naznačovať problém v operačnom systéme, ale zvyčajne je nepretržité a nič konkrétne nenaznačuje.

Takýto dlhý príbeh je potrebný na vysvetlenie jednej skutočnosti: čím viac procesorových zdrojov sa proces snaží spotrebovať v poctivom plánovači Linuxu, tým rýchlejšie bude zastavený, aby mohli fungovať aj iné procesy. Či je to správne alebo nie, je zložitá otázka, ktorú možno pri rôznych zaťaženiach riešiť rôzne. Vo Windowse bol plánovač donedávna zameraný na prioritné spracovanie desktopových aplikácií, čo mohlo spôsobiť zamrznutie procesov na pozadí. Sun Solaris mal päť rôznych tried plánovačov. Keď sme spustili virtualizáciu, pridali sme šiestu, Plánovač spravodlivého zdieľania, pretože predchádzajúcich päť nefungovalo adekvátne s virtualizáciou Solaris Zones. Odporúčam začať podrobné štúdium tejto problematiky knihami ako Solaris Internals: Solaris 10 a architektúra jadra OpenSolaris alebo Pochopenie linuxového jadra.

2.4. Ako sledovať krádež?

Monitorovanie krádeže vo virtuálnom stroji, podobne ako ktorákoľvek iná metrika procesora, je jednoduché: môžete použiť akýkoľvek nástroj na meranie metrík procesora. Hlavná vec je, že virtuálny stroj je na Linuxe. Z nejakého dôvodu systém Windows tieto informácie svojim používateľom neposkytuje. 🙁

Kradnúť: kto kradne procesorový čas z virtuálnych strojov
Výstup horného príkazu: podrobnosti o zaťažení procesora, v stĺpci úplne vpravo - ukradnúť

Problém nastáva pri pokuse získať tieto informácie z hypervízora. Môžete sa pokúsiť predpovedať krádež na hostiteľskom stroji napríklad pomocou parametra Load Average (LA) – priemernej hodnoty počtu procesov čakajúcich vo fronte vykonávania. Metóda výpočtu tohto parametra nie je jednoduchá, ale vo všeobecnosti, ak je LA normalizovaná počtom vlákien procesora viac ako 1, znamená to, že server Linux je niečím preťažený.

Na čo všetky tieto procesy čakajú? Jednoznačnou odpoveďou je procesor. Ale odpoveď nie je úplne správna, pretože niekedy je procesor zadarmo, ale LA ide mimo rozsah. Pamätajte ako NFS odpadáva a ako LA rastie. To isté sa môže stať s diskom a inými vstupno/výstupnými zariadeniami. Ale v skutočnosti môžu procesy čakať na koniec akéhokoľvek zámku, či už fyzického, spojeného s I/O zariadením, alebo logického, ako je mutex. Patrí sem aj uzamykanie na úrovni hardvéru (rovnaká odozva z disku), či logiky (tzv. zamykacie primitívy, ktoré zahŕňajú kopu entít, adaptívne a spinové mutexy, semafory, premenné podmienok, rw zámky, ipc zámky ...).

Ďalšou vlastnosťou LA je, že sa považuje za priemer operačného systému. Napríklad o jeden súbor súťaží 100 procesov a potom LA=50. Takáto veľká hodnota by mohla naznačovať, že operačný systém je zlý. Ale pre iný krivo napísaný kód to môže byť normálny stav, napriek tomu, že iba ten je zlý a ostatné procesy v operačnom systéme netrpia.

Kvôli tomuto spriemerovaniu (a nie menej ako za minútu) nie je určenie čohokoľvek podľa indikátora LA práve najvďačnejšou úlohou, s veľmi neistými výsledkami v konkrétnych prípadoch. Ak sa na to pokúsite prísť, zistíte, že články na Wikipédii a iných dostupných zdrojoch popisujú len tie najjednoduchšie prípady, bez hlbokého vysvetlenia procesu. Všetkým záujemcom posielam ešte raz, sem Brendanovi Greggovi  - postupujte podľa nižšie uvedených odkazov. Kto je príliš lenivý hovoriť po anglicky - preklad jeho populárneho článku o LA.

3. Špeciálne efekty

Teraz sa pozrime na hlavné prípady krádeží, s ktorými sme sa stretli. Poviem vám, ako vyplývajú zo všetkého vyššie uvedeného a ako súvisia s indikátormi na hypervízore.

Recyklácia. Najjednoduchší a najbežnejší: hypervízor bol znovu použitý. Skutočne, existuje veľa spustených virtuálnych strojov, vysoká spotreba procesora v nich, veľká konkurencia, využitie LA je viac ako 1 (normalizované podľa vlákien procesora). Všetko vo všetkých virtuálnych strojoch sa spomaľuje. Rastie aj krádež prenášaná z hypervízora, treba prerozložiť záťaž alebo niekoho vypnúť. Vo všeobecnosti je všetko logické a zrozumiteľné.

Paravirtualizácia vs. jednotlivé inštancie. Na hypervízore je len jeden virtuálny stroj, ktorý spotrebuje malú časť, ale produkuje veľké I/O zaťaženie, napríklad na disku. A odniekiaľ sa v ňom objaví malá krádež, do 10% (ako ukázali viaceré experimenty).

Prípad je zaujímavý. Steal sa tu objavuje práve kvôli blokovaniu na úrovni paravirtualizovaných vodičov. Vo virtuálnom stroji sa vytvorí prerušenie, spracuje ho ovládač a odošle hypervízoru. Vzhľadom na obsluhu prerušení na hypervízore to pre virtuálny stroj vyzerá ako odoslaná požiadavka, je pripravená na vykonanie a čaká na procesor, ale nie je mu daný procesorový čas. Virtuálne dievča si myslí, že tento čas je ukradnutý.

Toto sa deje v momente, keď je vyrovnávacia pamäť odoslaná, prejde do priestoru jadra hypervízora a my na ňu začneme čakať. Aj keď z pohľadu virtuálneho stroja by sa mal okamžite vrátiť. Preto sa podľa algoritmu výpočtu krádeže tento čas považuje za ukradnutý. S najväčšou pravdepodobnosťou v tejto situácii môžu existovať iné mechanizmy (napríklad spracovanie niektorých iných systémových volaní), ale nemali by sa príliš líšiť.

Plánovač verzus vysoko zaťažené virtuálne stroje. Keď jeden virtuálny stroj trpí kradnutím viac ako ostatné, je to spôsobené plánovačom. Čím viac proces zaťažuje procesor, tým skôr ho plánovač vykopne, aby mohli fungovať aj ostatné. Ak virtuálny stroj spotrebuje málo, takmer neuvidí krádež: jeho proces poctivo sedel a čakal, musíme mu dať viac času. Ak virtuálny stroj produkuje maximálnu záťaž na všetkých svojich jadrách, často je vyhodený z procesora a snažia sa mu nedávať veľa času.

Je to ešte horšie, keď sa procesy vo virtuálnom stroji snažia získať viac procesora, pretože sa nedokážu vyrovnať so spracovaním údajov. Potom bude operačný systém na hypervízore vďaka poctivej optimalizácii poskytovať čoraz menej procesorového času. Tento proces prebieha ako lavína a kradne skoky do neba, hoci iné virtuálne stroje si to sotva všimnú. A čím viac jadier, tým horšie je postihnutý stroj. Skrátka najviac trpia vysoko zaťažené virtuálne stroje s mnohými jadrami.

Nízke LA, ale kradne sa. Ak je LA približne 0,7 (to znamená, že hypervízor sa zdá byť nedostatočne zaťažený), ale v jednotlivých virtuálnych strojoch sa pozoruje krádež:

  • Možnosť s paravirtualizáciou už opísaná vyššie. Virtuálny počítač môže prijímať metriky naznačujúce krádež, hoci hypervízor je v poriadku. Podľa výsledkov našich experimentov táto možnosť krádeže nepresahuje 10 % a nemala by mať významný vplyv na výkon aplikácií vo virtuálnom stroji.
  • Parameter LA je vypočítaný nesprávne. Presnejšie povedané, v každom konkrétnom momente je vypočítaná správne, ale pri priemerovaní za jednu minútu sa ukáže ako podhodnotená. Napríklad, ak jeden virtuálny stroj na tretinu hypervízora spotrebuje všetky jeho procesory presne pol minúty, potom LA za minútu na hypervízore bude 0,15; štyri takéto virtuálne stroje pracujúce súčasne dajú 0,6. A to, že na každom z nich bola pol minúty divoká krádež na 25% podľa ukazovateľa LA sa už nedá vytiahnuť.
  • Opäť kvôli plánovačovi, ktorý sa rozhodol, že niekto jedol príliš veľa a nechal niekoho čakať. Medzitým zmením kontext, postarám sa o prerušenia a postarám sa o ďalšie dôležité systémové veci. Výsledkom je, že niektoré virtuálne stroje nevidia žiadne problémy, zatiaľ čo iné zažívajú vážne zníženie výkonu.

4. Iné skreslenia

Existuje milión ďalších dôvodov na skreslenie spravodlivej návratnosti procesorového času na virtuálnom stroji. Napríklad hyperthreading a NUMA prinášajú ťažkosti do výpočtov. Úplne zamotajú výber jadra na vykonávanie procesu, pretože plánovač používa koeficienty – váhy, ktoré pri prepínaní kontextu ešte viac sťažujú výpočet.

Dochádza k skresleniam vďaka technológiám ako turbo boost alebo naopak režim úspory energie, ktorý pri výpočte využitia dokáže umelo zvýšiť alebo znížiť frekvenciu či dokonca časový úsek na serveri. Povolenie turbo boost znižuje výkon jedného procesorového vlákna v dôsledku zvýšenia výkonu iného. V tejto chvíli sa virtuálnemu stroju neprenáša informácia o aktuálnej frekvencii procesora a ten sa domnieva, že mu niekto kradne čas (napríklad žiadal 2 GHz, ale dostal polovicu).

Vo všeobecnosti môže byť skreslenie veľa dôvodov. V konkrétnom systéme môžete nájsť niečo iné. Je lepšie začať s knihami, na ktoré som dal vyššie odkazy, a získať štatistiky z hypervízora pomocou nástrojov ako perf, sysdig, systemtap, z ktorých desiatky.

5. Závery

  1. Určité množstvo krádeže môže nastať v dôsledku paravirtualizácie a možno to považovať za normálne. Na internete píšu, že táto hodnota môže byť 5-10%. Závisí od aplikácií vo virtuálnom stroji a od zaťaženia, ktoré kladie na jeho fyzické zariadenia. Tu je dôležité venovať pozornosť tomu, ako sa aplikácie cítia vo virtuálnych strojoch.
  2. Pomer zaťaženia hypervízora a krádeže vo virtuálnom stroji nie sú vždy jasne vzájomne prepojené, oba odhady krádeže môžu byť v špecifických situáciách pri rôznych zaťaženiach chybné.
  3. Plánovač má zlý postoj k procesom, ktoré si veľa pýtajú. Snaží sa dať menej tým, ktorí žiadajú viac. Veľké virtuálne stroje sú zlo.
  4. Trochu ukradnúť môže byť normou aj bez paravirtualizácie (berúc do úvahy záťaž vo vnútri virtuálneho stroja, charakteristiky záťaže susedov, rozloženie záťaže medzi vlákna a ďalšie faktory).
  5. Ak chcete zistiť krádež v konkrétnom systéme, musíte preskúmať rôzne možnosti, zbierať metriky, starostlivo ich analyzovať a premýšľať o tom, ako rovnomerne rozložiť zaťaženie. Odchýlky od akýchkoľvek prípadov sú možné, čo sa musí experimentálne potvrdiť alebo sa na to pozrieť v ladiacom nástroji jadra.

Zdroj: hab.com

Pridať komentár