Cud inżynierii wirtualizacji — vMotion

Wstęp

Wirtualizacja, czyli moja ulubiona działka z szeroko pojętego IT. Miało być krótko i na temat a zamiast ze dwóch akapitów zwięzłego tekstu wyszło jak zwykle. 

Dla tych, co nie lubią za dużo czytać takie małe tl;dr - głównym tematem jest vMotion, czyli przenoszenie maszyn wirtualnych między hostami i repozytoriami danych w locie, bez ich wcześniejszego wyłączania. Z przestojem liczonym w milisekundach dla większości zastosowań uznawane za "na żywo". 

Wirtualizacja – proces symulowania przez oprogramowanie istnienia zasobów logicznych, które wykorzystują ustalone podczas konfiguracji zasoby fizyczne. np. wirtualna maszyna stosuje wirtualizacje w celu symulowania pracy maszyny z danym systemem operacyjnym pozwalając przez to badać zachowanie tej maszyny i jej oprogramowania bez wpływania na realny system operacyjny na którym pracujemy (Wikipedia)

W domowym zastosowaniu technologia wirtualizacji zyskała popularność za sprawą rozwiązań VMware (pakiet "Workstation"), Hyper-V, czy odchodzącego w zapomnienie "Virtual PC" - W Windows 7 może być znany np. z opcji 'XP Mode' (wirtualnej maszyny z systemem Windows XP). Popularny jest też oczywiście rosący w siłę VirtualBox. 

Pierwszym cudem jest to, że taka maszyna... działa. To nie jest emulacja, ale wirtualizacja - rozkazy są prawie w 100% wykonywane bezpośrednio na procesorze łącznie z wykorzystaniem jego specyficznych instrukcji. Na głównym serwerze wirtualizacyjnym (hoście) takich maszyn może być kilka/kilkadziesiąt i dzielić między sobą "czas procesora", ew. mieć na wyłączność poszczególne rdzenie fizycznego CPU. To samo z pamięcią (RAM). Mają swój niezależny dysk w postaci kontenera ( np. *.vmdk dla VMware, czy (.vhd* w Hyper-V), "RAWa". Jest jeszcze warstwa sieciowa - wirtualny switch może dać dostęp do sieci głównej poprzez "mostowanie" (bridge) wirtulanej karty sieciowej, gdzie taka maszyna zgłosi się w domenie rozgłoszeniowej - będzie dla innych komputerów w sieci widziany także po adresie MAC i praktycznie nie do odróżnienia, czy nie jest to przypadkiem "fizyczny" serwer. Brzmi prosto?

Popatrzmy teraz z punktu widzenia komercyjnego. Technologia zyskała największą popularność około 10-12 lat temu- nie chcę tutaj wchodzić w długą polemikę na temat wirtualizacji w AIXach, czy Xenów od Citrix. Chodzi mi głównie o ten "boom" na tzw. "chmurę prywatną", gdzie około 2007 roku VMware ze swoim ESX 3.x i vCenter z vMotion, DRS i HA mocno zawojowało rynek. 

2007 rok (pomijając końcówkę, kiedy zaczął się kryzys) był pięknym okresem dla integratorów systemów komputerowych - budżety firm pozwalały na całkiem tłuste wydatki i można było spokojnie sprzedać/wdrożyć nowe środowiska serwerowe.

Głównym atutem wirtualizacji jaki był przedstawiany odbiorcom było zmniejszenie ilości fizycznej serwerów: tj. np. zamiast 15-20 "kloców" 2-4U zajmujących kilka szaf udawało się to "upchnąć" w jedną zawierającą klaster x3 hypervisor (serwer wirtualizacji), storage (współdzielone zasoby dyskowe), przełączniki a na samym spodzie solidny UPS. Jest to oczywiście dyskusyjne i często koszt takich rozwiązań przewyższa odpowiednik, gdyby to robić na maszynach "fizycznych", ale o tym może kiedy indziej.

Pojawia się jednak sytuacja, gdy serwerów mamy kilkadziesiąt, lub kilkaset hypervisorów. Po pierwsze, mimo swojej wysokiej ceny serwery potrafią się psuć - nawet jak jest zdublowany (redundantny) zasilacz, to dobre praktyki nakazują jednak taki serwer na czas nawet "wymiany na gorąco" zasilacza dmuchać na zimne (przełączyć na chwilę serwer w tryb serwisowy, aby nie brał udziału w kluczowych zadaniach dla infrastruktury). Czasem też serwer potrzebuje dłużego postoju, np. oczekuje na przyjazd technika w celu wymiany wentylatora, rozbudowy pamięci, czy dodania nowych kart, procesora, czy okablowania). 

Kolejna sprawa - same serwery wirtualizacji wymagają aktualizacji. Podniesienie do najnowszej wersji - np. ostatnia akcja z łataniem środowisk po Meltdown/Spectre. No i tu pojawia się problem. Obecne systemy a raczej usługi przez nie świadczone wymagają bardzo wysokiej dostępności (SLA) liczonego nawet w minutach w skali roku - gdyż np. Ciebie drogi czytelniku Dobrych Programów może nie obchodzić, że administrator w danym dniu musi dodać RAMu, czy przenieść serwer do innego pomieszczenia. Ważne, żeby w tym czasie sama usługa była "w górze", czyli działało forum, czy sama strona główna. Procedury w niektórych firmach są wyjątkowo restrykcyjne a brak działania jednego progamu może pociągnąć za sobą daleko idące konsekwencje.

No i co teraz, gdy dobrej klasy serwer pod wirtualizację mający 1.5TB pamięci (RAM), 80 logicznych wątków procesora (mogący świadczyć x80 vCPU i więcej) hostuje 30-40 serwerów wirtualnych (VM) musi zostać nagle wyłączony?

Jest jeszcze o tyle dobrze, gdy jest to zadanie zaplanowane, mogące być rozciągnięte w czasie - no ale jak z serwera już leci dym ze spalonego zasilacza, lampki migają na czerwono, a przyzakładowa straż pożarna czeka w gotowości, to przestaje być kolorowo. Logiczne więc wydaje się, że sama wirtualizacja powinna zezwolić na uruchomienie VM na innym hypervizorze - np. zamrozić (zahibernować) VM i odpalić gdzie indziej? Tak, jest to możliwe.
To jednak też jest kłopotliwe, gdyż wyłączenie tylu nadal wymaga zaangażowania wielu zespołów: rozpięcia klastrów, przełączenia w inne miejsce baz danych, wyłączenia aplikacji, wykonanie później testów działania przeniesionych serwisów ("sanity check") itd. Mówiąc delikatnie - cyrk, zadyma. A gdyby jakoś magicznie uruchomiona VM nagle pojawiła się bez przestoju (tj. setne sekudny niedostpności) na innym hypervizorze? No ale jak - przecież co z pamięcią (RAM), dyskiem twardym, stanem procesora (rozkazami), siecią, czy nawet tym, co jest wyświetlane w danej chwili na konsoli serwera (pamięć obrazu)?

Trochę podstaw - składniki maszyny wirtualnej

Im Twoja wiedza ogólna z IT jest szersza, powinno pojawić się więcej znaków zapytania - np. jak sieć (przełączniki) zintepretują pojawienie się nagle tego samego interfejsu (adres MAC) w innym segmencie sieci, czy co się wydarzy, gdy maszyna wirtualna uruchomiona na procesorze tego samego producenta (Intel, lub AMD) spotka niewiele różniącą się rodzinę procesorów starszej generacji, która nie ma jeszcze dostępnego danego zestawu instrukcji? O tym może za chwilę, podstawy budowy maszyny wirtualnej.

Każda maszyna wirtualna posiada składniki, które niezależnie od platformy mają swoje odpowiedniki i nazwy u poszczególnych producentów wirtualizatorów. W chwili tworzenia tego wpisu najwygodniej mi to zrobić na VMWare, jednak swoje równoważniki można znaleźć np. w Hyper-V. 

VMX - główna konfiguracja maszyny wirtualnej. Tu znajdują się informacje dotyczące ilości procesorów, pamięci (RAM), sieci, dysków i migawek dysków ("snapshotów"), nawet adresu MAC karty sieciowej.

NVRAM - można porównać do CMOS na płycie głównej. Trzymana jest tam konfiguracja BIOSu (8-10kB), lub UEFI (~70kB) maszyny wirtualnej. 

VMDK - dysk maszyny wirtualnej. Można go porównać do nowego dysku twardego, na którym zakłada się tablicę partycji, system plików a następnie zapełnia danymi. Tutaj też pojawiają się pewne niuanse, gdzie np. definiując nowy dysk o wielkości np. 700GB sam plik będzie się powiększał w zależności od użycia na nim danych aż do 700GB (*.VMDK - thin), lub od samego początku (nawet, jak na nim będzie jeden plik 1MB) zajmie pełne 700GB (*-flat.vmdk - thick). 

VSWP - wielkością odpowiada pamięci (RAM) przeznaczonej dla maszyny wirtualnej. W przypadku braku fizycznej pamięci (na hyperpvizorze) będzie on użyty na podobnej zasadzie, jak plik wymiany w systemie operacyjnym (taki powolny substytut RAMu...).

Są oczywiście jeszcze logi, pliki tymczasowe, czy niektórych może nie być wcalne - np. wspomianego wyżej VSWP ze względu na konfigurację maszyny wirtualnej (rezerwacja pamięci).

Taka wyłączona maszyna ( przy tzw. "cold migration") wydaje się dość prosta do migracji - to jakby wyciągnąć dysk twardy z laptopa z zahibernowanym systemem i wsadzić do bliźniaczego sprzętowo komputera - powinno zadziałać. Pliki maszyny wirtualnej można nawet przenieść na inny zasób dyskowy (storage) do innego centrum danych. 

Można więc:

  • zmienić sam hypervisor (łącznie z klastrem w jakim się znajduje),
  • "storage" (czyli miejsce, gdzie znajdują się pliki powiązane z maszyną wirtualną),
  • obie powyższe opcje jednocześnie.

W tym miejscu powinno już nasuwać się rozwiązanie jak zrobić, aby można było uruchomić wirtualną maszynę na innym hoście - a gdyby tak wszystkie hypervizory (np. z danego klastra) miały dostęp do wszystkich tych plików i powiązanych z nimi zasobów najlepiej na współdzielonym zasobie? Niby można na bezpośrednio podłączonym do hyeprvizora dysku trzymać pliki w zależności od potrzeb przenosić na inny host a nawet udostępniać dla innych serwerów, ale tworzy to dodatkowe ryzyko utraty danych, oraz utrudnienia w zarządzaniu środowiskiem. Tworzy się więc dodatkową sieć (SAN) zapewniającą dostęp do zasobów pamięci masowej - to jeden z najbardziej krytycznych elementów każdej wirtualizacji. Sam temat SAN, dostępnych szybkości to ogromne zagadnienie. Warto wspomnieć, że ostatnia dekada to ogromny postęp i np. Fibre Chanel (FC) w przyszłym roku (siódma generacja - 256GFC) umożliwi transfery rzędu 25.000MB/s!

Rozwiązań w sieciach SAN jest kilka i nawet po "zwykłym" Ethernecie z kartami 10Gbit i agregacją można osiągnąć świetne wyniki. Dochodzą jeszcze różne wynalazki w postaci ESF (100Gbit), ale jak wspomniałem - to nie temat na ten wpis.

VMWare

W szeregach VMware praktycznie od początku istnienia firmy pracował Mike Nelson - osoba, która zamieszała znacząco na rynku wirtualizacji. Architekt VMKernel, vMotion, dodatkowo totalnie przerobił HA. Dzięki niemu ponad 10 lat temu jak zobaczyłem jak to działa, to zbierałem szczękę z podłogi - bawiłem się jak serwerami jak dziecko. Nie mogłem uwierzyć, że będąc podłączonym do Windowsa (zdalna sesja RDP - chyba do Win2000, albo WinXP), mogłem praktycznie cały czas go używać pomimo tego, że zmienił się serwer hostujący! Pamiętam, że jak pokazywałem to koledze, to nie mógł uwierzyć i myślał, że robię go w konia - wypinał kable sieciowe z hypervizorów w celu potwierdzenia, że rzeczywiście następuje migracja. 

Kolejne wersje vMotion wniosły całkiem konkretne zmiany. Zajmijmy się może podstawowymi tematami.

Jak to działa

Od czego zacząć? Wyobraźmy sobie, że psuje się nasz domowy komputer - spaliła się płyta główna. Ocalał dysk twardy. Często pada pytanie - a czy mogę go wsadzić do innej jednostki i uruchomić? Jasne, że tak - tylko nie mamy pewności, że system operacyjny poprawnie zostanie uruchomiony i czy np. Windows nie przywita ekranem błędu, bo:

  • mieliśmy procesor od Intela a teraz jest AMD,
  • zmieniła się płyta główna,
  • wymagane są inne sterowniki do dysku,
  • nie do końca chce działać sieć itd.

I to wszystko się działo przy ponownym uruchomieniu systemu operacyjnego a nie na "gorąco". A co, jeżeli taki komputer byśmy chcieli włączyć w dokładnie takim stanie, jak był po "zamrożeniu" przy działającym OS? Gruba sprawa.

Procesor

Wirtualna maszyna dostaje "wycinek" procesora dla siebie - może więc operować nawet na rozkazach specyficznych dla danej platformy. Pamiętajmy, że nawet niewiele różniące się wydaniem jednostki CPU tego samego producenta nie są takie same. Ponownie uruchomiony komputer (czy maszyna wirtualna) poradzi sobie - dostosuje swoje działanie do sprzętu. Tutaj wydaje się oczywiste - budując środowisko wirtualizacyjne nie miesza się platformy procesorowej Intel z AMD w ramach jednego klastra. Jasne, można przepychać wyłączone VM w tak mieszanym środowisku, ale nawet nie zaleca się za bardzo zbyt rozbieżnych generacji procesorów jednego producenta. Tu zawsze trzeba się posłużyć specyfikacjami co z czym i jak będzie "gadać" bez większego zająknięcia a VMware jeszcze będzie to wspierać. Nie jest to do końca proste w utrzymaniu - w momencie rozbudowy naszej farmy hypervizorów może się okazać, że nawet po roku nie są już dostępne identyczne serwery a procesor będzie niewiele się różnić - pojawia się rozwiązanie w postaci maskowania funkcji CPU. VMware nazwał sobie ten bardzo ważny składnik EVC (Enhanced vMotion Compatibility) . 

Najprościej tłumacząc - nowszej generacji sprzęt (CPU) musi się dostosować do starszego. EVC będzie jak przyzwoitka dbająca o to, żeby wirtualna maszyna nie zobaczyła tego na nowym procesorze, czego później nie będzie miała od starszej generacji. Plusy? Maskowanie da taki sam plac do pracy na każdym hypervizorze. Minusy? Kastracja nie pozwoli wycisnąć z nowszego sprzętu pełnej mocy. 

Gdyby ktoś chciał poczytać o wpływie EVC na wydajność odsyłam do całkiem zwięzłego testu porównawczego

Pamięć

Chyba jednen z ciekawszych elementów samego procesu vMotion - przeniesienie pamięci na drugi serwer. Rzecz znowu wydaje się prosta - czemu nie zrobić anologicznie, jak to ma miejsce w przypadku hibernacji domowego komputera, gdzie pamięć zapisywana jest do pliku na dysku? Zamrozić maszynę i wznowić (odczytać stan) na innym hoście? Tak to działa w przypadku "cold migration". Trudniej będzie przy włączonej, gdy w odpowiednio wąskim oknie czasowym zrobić to np. z 32 GB RAMu. Przesłanie po sieci takiej ilości danych maszyny wirtualnej (tzw. "checkpoint") zajmuje całkiem sporo czasu, gdzie liczy się każda setna sekundy, zanim ktoś się zorientuje, że coś jest nie tak i VM jest niedostępna. Na prostym przykładzie:

  • w domu jeszcze popularne są urządzenia operujące na 100Mbit, co w idealnych warunkach pozwoli skopiować 32 GB w około 45 minut,
  • popularniejsze 1Gbit (1000Mbit) pozwoli to zrobić w jakieś 4,5 minuty,
  • nowoczesne 10Gbit da nadal przydługie 25 sekund.

"Dużo za długo", nawet jak skrócić ten czas agregując kilka "rur" sieciowych na jednym vSwitchu nadal może być zbyt mocno rozciągnięte w czasie. Rozwiązano to wyjątkowo sprytnie. Sam proces jest usprawniany w każdej kolejnej wersji, jednak zasada pozostała ta sama:

Załóżmy, że w miejscu docelowym zarezerwowane jest już miejsce dla przenoszonej maszyny (mówimy tu o pamięci):

Następuje pierwsza faza (często w dokumentacjach oznaczana zerową): tzw. "snapshot" pamięci - zamrożenie jej stanu, aby umożliwić skopiowane jej na drugiego hosta. Serwer jednak cały czas pracuje a wszelkie zmiany są zapisywane w specjalnie wyznaczonym dodatkowym segmencie pamięci:

Z racji tego, że "snapshot" nie zmienia się, więc skopiować wykonać na serwer docelowy pierwszą paczkę - 32GB, potrwa to np. 25 sekund. W tym czasie jednak VM pracowała pół minuty i nastąpiły zmiany na 16GB pamięci:

Kopiujemy więc tylko ze zmiany - plus jest taki, że zajmie już to tylko połowę czasu, tj. 12.5s:

Na źródle nastąpiły znowu zmiany, ale z racji tego, że miały one miejsce w mniejszym oknie czasowym, było ich np. o połowę mniej: analogicznie kopiujemy "kwadraciki":

Gdyby ktoś wczytywał się w dokumentacje Hyper-V, VMWare i podobnych można spotkać różne określenia: od kopiowania zmian (deltas), po nadanie trochę dramaturgii przez określenia typu "dirty memory pages". Dążymy więc do momentu, kiedy przesyłane "paczki" były jak najmniejsze i już 300kB fragmenty będą się przesyłać w około 0.3s. Wtedy też można "wygasić" źródłową maszynę i przesłać ostatnie zmiany pamięci w relatwynie krótkim czasie.
Samo powodzenia procesu, jego szybkość i niedostępność serwisów przenoszonej maszyny wirtualnej zależna jest od wielu czynników:

  • wielkość pamięci (RAM),
  • przepustowości i konfiguracji sieci łączącej hosty - w tym "odległość" dzieląca hypervisory (RTT, czyli w uproszczeniu "ping" między nimi),
  • zadań przenoszonej VM - zupełnie inaczej będzie wyglądać ilość zmian na nudzącym się małym serwerku a inaczej na dociążonej bazie danych,
  • wersji hypervizorów i vCenter,
  • konfiguracji podsystemu dyskowego. 

Czasem warto się więc zastanowić, czy nie lepiej wykonać migracji "na zimno", gdzyż są sytuacje (np. wymienony wyżej serwer bazy danych z 256GB RAM, gdzie niedostępność usługi przez kilka sekund może spowodować małą katastrofę).

Dysk

Większość została już napisana wyżej - vMotion jest możliwe od wersji 5.1 bez współdzielonego "magazynu dyskowego" (storage). Zakładamy, że hypervizory mają dostęp do plików maszyny wirtualnej.

Sieć

Tu też jest zamknięty kawałek magii - taka wirtualna maszyna jest przecież powiązana z fizyczną infrastrukturą - wirtualny switch powoduje, że adres MAC jest widoczny na drugiej wartwie urządzeń sieciowych. Podczas przenoszenia maszyny nagle ten sam adres pojawi się na zupełnie innych portach oddalonych switchy. No i co ma taki biedny switch zrobić? Uciąć taki ruch? "Pomyśleć", że pojawiło się urządzenie ze zduplikowanym adresem MAC? Dodatkowo do maszyny przez switche będą spływać dane, które nagle odbiją się od nieistniejącej maszyny. Rozwiązuje się to stosując dość wiekowy, ale użyteczny protokół RARP (Reverse Address Resolution Protocol). Jest to takie zgłoszenie w sieci: "hej, ten adres MAC już będzie gdzie indziej, przekierujcie to". 

vMotion

Spróbujmy to zebrać w całość - co się dzieje podczas przenoszenia "na żywo" maszyny wirtualnej. Sam wpis zaczął się tymi dziewięcioma punktami i niestety trochę spuchł. 

Scenariusz z sytucją, gdy 'storage' jest dostępny po dwóch stronach. Wygląda to mniej więcej tak:

  1. wybadanie gruntu - czy wirtualna maszyna będzie miała szansę zadziałać na docelowym hoście (hypervizorze) - kompatybliność RAM, CPU, czy np. będą dostępne odpowiednie sieci,
  2. sprawdzenie, czy nie ma większych przeciwskazań do przeniesienia maszyny z obecnej lokalizacji - np. "przypięty" wirtualny DVD do obrazu (ISO) znajdującego lokalnie pliku, 
  3. zostają zerezerwowane zasoby na docelowym hypervizorze (vCPU, vRAM),
  4. następuje przeniesienie pamięci ze źródła do celu (checkpoint/checkpoint-restore),
  5. w tle dzieje trochę dodatowych zadań (np. spowolenie maszyny, żeby wykonywała jak najmniej zadań),
  6. po upewnieniu się, że można to przepięcie wykonać szybko (~500ms, lub mniej) następuje całkowite "uśpienie" źródłowej maszyny i jak najszybciej możliwe przeniesienie ostatnich zmian w źródłowym VM (pamięć, stan procesora, pamięć wideo, sieć),
  7. przakazanie informacji do urządzeń sieciowych, że zaraz pojawi się na nich urządzenie, które jeszcze kilkadziesiąt milisekund wcześniej było w inny miejscu,
  8. "odmrożenie" wirtualnej maszyny,
  9. wyrejestrowanie wirtualnej maszyny ze źródłowego hypervizora. 

Jako ciekawostkę można wspomnieć, że np. uśpiona maszyna przy wybudzaniu informowana jest przez VMware Tools o aktualnym czasie - warto więc zadbać o to, żeby źródłowy i docelowy hypervizor miały zscynchronizowaną godzinę (korzystały np. z tego samego serwera NTP).

Podsumowanie

Temat jest szeroki i długi jak rzeka - wraz z kolejnymi wydaniami hypervizorów nie zmienia się tylko numerek wersji, ale oferowane możliwości - od Live vMotion na oddalonych od siebie centrach danych (RTT rzędu 100ms), czy ukłon w stronę rozwiązań hybrydowych (chmura <--> własne centrum danych) z zachowaniem szyfrowania vMotion nawet między różnymi instancjami vCenter. Wirtualizacja i powiązane z nią procesy to moim zdaniem majstersztyk inżynierii posypanej szczyptą magii.

--------------------------------------------------------------------------------
Kilka mniej, lub bardziej użytecznych dokumentów do poczytania:

https://docs.vmware.com/en/VMware-vSphere/6.5/com.vmware.vsphere.vcent...
https://www.vmware.com/support/ws5/doc/ws_learning_files_in_a_vm.html

https://www.vmware.com/resources/compatibility/search.php
http://sanbarrow.com/vmdk/disktypes.html
https://fibrechannel.org/wp-content/uploads/2017/04/FCIA-SpeedMap-Fina...

https://en.wikipedia.org/wiki/Fibre_Channel
https://www.vmware.com/content/dam/digitalmarketing/vmware/en/pdf/tech...
https://blogs.vmware.com/vsphere/2013/07/vxlan-series-how-vmotion-impa...

--------------------------------------------------------------------------------