Jak KVM działa pod maską
KVM zamienia jądro Linuksa w hiperwizor typu Type-1, udostępniając urządzenie znakowe /dev/kvm. Proces w przestrzeni użytkownika (zwykle QEMU) otwiera to urządzenie, prosi jądro o utworzenie wirtualnego CPU, a następnie wykonuje instrukcje gościa bezpośrednio na fizycznym CPU dzięki sprzętowym rozszerzeniom wirtualizacji. Jądro obsługuje zdarzenia uprzywilejowane; reszta wykonuje się z pełną prędkością.
Trzy komponenty sprawiają, że KVM działa. Po pierwsze, moduł jądra kvm.ko zarządza wirtualizacją CPU i pamięci oraz udostępnia interfejs /dev/kvm. Po drugie, moduł zależny od architektury — kvm-intel.ko dla Intel VT-x lub kvm-amd.ko dla AMD-V — tłumaczy między ogólnym API KVM a instrukcjami wirtualizacji konkretnego CPU. Po trzecie, proces hiperwizora w przestrzeni użytkownika, taki jak QEMU, cloud-hypervisor lub Firecracker, zapewnia emulację urządzeń: wirtualne dyski, karty sieciowe, kontrolery USB oraz oprogramowanie układowe BIOS lub UEFI. Ponieważ to samo jądro Linuksa jest hiperwizorem, każdy linuksowy scheduler, menedżer pamięci i mechanizm bezpieczeństwa stosuje się do maszyn wirtualnych tak samo, jak do procesów natywnych. Z punktu widzenia jądra gość KVM to po prostu „ciężki” proces, dlatego narzędzia takie jak top, perf i cgroups działają na nim bez modyfikacji.
KVM vs OpenVZ vs VMware ESXi vs Hyper-V
KVM zapewnia pełną wirtualizację sprzętową z osobnym jądrem gościa dla każdej maszyny wirtualnej. OpenVZ wykorzystuje konteneryzację na poziomie systemu operacyjnego, gdzie każdy kontener współdzieli jądro hosta. VMware ESXi to zamknięty hiperwizor typu Type-1 bare-metal z własnym jądrem (VMkernel). Hyper-V to hiperwizor typu Type-1 firmy Microsoft osadzony w Windows. Tylko KVM, ESXi i Hyper-V dają realne, izolowane jądro gościa.
OpenVZ (i jego następca Virtuozzo) to technologia kontenerowa, a nie hiperwizor. Każdy kontener OpenVZ współdzieli jądro Linuksa hosta, co oznacza brak możliwości uruchomienia innej wersji jądra, ładowania własnych modułów jądra ani uruchomienia systemu operacyjnego innego niż Linux. W zamian uzyskuje się gęstość: ponieważ nie ma narzutu jądra dla każdej maszyny, host OpenVZ może upchnąć więcej kontenerów na tym samym sprzęcie, dlatego niskobudżetowe plany VPS współdzielonego często z niego korzystały. VMware ESXi jest korporacyjnym standardem wirtualizacji typu Type-1, ale jest dostarczany jako produkt o zamkniętym kodzie z licencjonowaniem na gniazdo CPU, które historycznie wykluczało go z masowego rynku VPS. Hyper-V dominuje w środowiskach Windows Server i ściśle integruje się z Active Directory oraz System Center, ale rzadziej bywa wybierany w flotach hostingowych nastawionych na Linuksa. KVM stał się domyślnym rozwiązaniem dla nowoczesnego hostingu VPS, ponieważ jest open source, należy do głównej linii jądra, obsługuje dowolny system gościa działający na x86_64 lub aarch64 i ma dojrzały ekosystem zarządzania (libvirt, oVirt, Proxmox, OpenStack Nova).
Dlaczego KVM jest dziś domyślnym wyborem dla VPS
KVM stał się dominującą technologią VPS, ponieważ daje każdemu klientowi realne, izolowane jądro bez konieczności płacenia za licencje typu VMware. Obsługuje gości Linux, Windows, BSD i Solaris, działa na powszechnie dostępnym sprzęcie x86_64 i ARM oraz jest zintegrowany z każdym ważniejszym stosem orkiestracji chmury — OpenStack, Proxmox VE, Kubernetes przez KubeVirt i AWS Nitro bazują właśnie na nim.
Trzy siły zbiegły się, by uczynić KVM standardem. Po pierwsze, sprzętowe rozszerzenia wirtualizacji stały się powszechne: Intel VT-x trafił do układów Core 2 w 2006 r., a AMD-V do wczesnych Athlon 64, więc na początku lat 2010 niemal każdy serwerowy CPU mógł hostować KVM przy wydajności bliskiej natywnej. Po drugie, społeczność Linuksa odrzuciła paravirtualizację w stylu Xena w głównej linii, ale w 2007 r. zintegrowała KVM, dając każdej dystrybucji wbudowany hiperwizor. Po trzecie, ekosystem chmury publicznej zainwestował w KVM mocno: Google Compute Engine wystartował na KVM, AWS przeniósł się z Xena na opartą na KVM architekturę Nitro, a OpenStack ustandaryzował KVM jako referencyjny hiperwizor. Mniejsi dostawcy VPS korzystają z tego ciążenia grawitacyjnego, ponieważ to samo oprzyrządowanie, które obsługuje floty hyperscalerów — libvirt, sterowniki virtio, cloud-init — działa też na pojedynczej szafie powszechnie dostępnych serwerów.
Realne charakterystyki wydajności: CPU steal, I/O i narzut
Na właściwie skonfigurowanym hoście KVM należy spodziewać się jednocyfrowego procentowo narzutu CPU w porównaniu z bare metal, dodanego opóźnienia sieciowego poniżej milisekundy na trasach lokalnych oraz 80-95% natywnych IOPS dyskowych przy użyciu virtio-blk lub virtio-scsi z paravirtualizowanym sterownikiem. Stałe wartości CPU steal powyżej 5% to klasyczna oznaka przesycenia hosta i mocny sygnał do zmiany planu.
Trzy liczby mają znaczenie dla gościa KVM w produkcji. CPU steal time, widoczne w /proc/stat jako ósme pole, mierzy odsetek czasu, w którym wirtualny CPU był gotowy do pracy, ale fizyczny CPU był zajęty wykonywaniem innych gości. Wartości poniżej 1-2% to normalny szum tła; stałe wartości powyżej 5% oznaczają, że host jest przesycony, a obciążenie jest dławione. IO wait, ujawniany przez narzędzia takie jak iostat i top, mierzy odsetek czasu, w którym CPU był blokowany na dysku lub sieci. Przy paravirtualizowanych sterownikach virtio i nowoczesnym backendzie NVMe stałe IO wait powyżej 20% przy obciążeniu, które powinno być ograniczone CPU, jest mocnym sygnałem nasycenia podsystemu dyskowego. Przepustowość sieci na virtio-net powinna sięgać 80-95% line rate fizycznej karty sieciowej; istotnie niższe wartości wskazują na źle skonfigurowane offloady lub stary emulowany sterownik e1000.
Kiedy NIE używać KVM
KVM jest złym wyborem w trzech sytuacjach: przy obciążeniach kontenerowych o ekstremalnej gęstości, gdzie narzut jądra na maszynę wirtualną dominuje; przy wdrożeniach wrażliwych na licencje Windows, gdzie Hyper-V z cennikiem SPLA jest istotnie tańszy; oraz w określonych scenariuszach passthrough sprzętu o niskich opóźnieniach, gdzie SR-IOV lub passthrough GPU jest słabo wspierany na konkretnym modelu karty sieciowej lub GPU.
Dla mikrousług kontenerowych, które nie potrzebują izolacji jądra, kontenery Linuksa (Docker, Podman, Kubernetes) działające bezpośrednio na bare metal upakują się gęściej niż jakikolwiek VPS oparty na KVM 3-5 razy, bo każdy kontener to po prostu grupa procesów z namespaces i cgroups. Niskobudżetowi dostawcy VPS wrażliwi na gęstość historycznie wybierali OpenVZ z tego samego powodu. Wdrożenia z dominacją Windows — szczególnie te z licencjami Windows Server kupowanymi przez SPLA — czasem płacą istotnie mniej na Hyper-V niż na KVM, ze względu na sposób, w jaki Microsoft wycenia licencje gościa na konkurencyjnych hiperwizorach. Wreszcie, pewne scenariusze passthrough sprzętu nadal bywają bolesne na KVM: passthrough GPU wymaga czystej izolacji grup IOMMU, niektóre konsumenckie karty sieciowe nie mają obsługi SR-IOV, a passthrough PCIe dysków NVMe czasem wyzwala obejścia błędów resetu. Dla 95% obciążeń ogólnego przeznaczenia VPS na Linuksie żaden z tych przypadków nie ma znaczenia, a KVM jest właściwym domyślnym wyborem.
Jak zweryfikować, że VPS naprawdę działa na KVM
Wewnątrz gościa Linux należy uruchomić `systemd-detect-virt` — powinno zwrócić `kvm`. Warto skonfrontować to z `lscpu` (linia 'Hypervisor vendor' powinna pokazywać 'KVM') i `dmesg | grep -i kvm`. Jeśli zamiast tego widać 'OpenVZ', 'lxc' lub 'VMware', dostawca używa innej technologii, niezależnie od marketingowych zapewnień.
Przed podpisaniem umowy warto przeprowadzić niewielką diagnostykę na próbnym VPS. Należy uruchomić `systemd-detect-virt` po kanoniczny wynik wykrycia. Następnie `cat /proc/cpuinfo | grep -E 'vmx|svm'`, aby potwierdzić, że sprzętowe rozszerzenia wirtualizacji są przekazywane (niektórzy dostawcy je usuwają, łamiąc wirtualizację zagnieżdżoną). Polecenie `uname -r` pozwala sprawdzić, czy widzi się jądro specyficzne dla gościa, a nie współdzielone jądro hosta — na prawdziwym KVM VPS można zainstalować inne jądro przez `apt install linux-image-...` lub `dnf install kernel-...` i uruchomić się z niego. Na OpenVZ to niemożliwe. Na koniec warto sprawdzić `/proc/user_beancounters` — jeśli ten plik istnieje, host działa na OpenVZ niezależnie od treści marketingowych.