Czy na VPS można zainstalować Proxmox?
Sprawdź dostępność flagy vmx lub svm za pomocą polecenia kvm-ok. Dowiedz się, dlaczego VPS może nie obsługiwać nested virtualization i jak uniknąć błędów.
Krótka odpowiedź
Wirtualizacja zagnieżdżona (nested virtualization) to hypervisor uruchomiony wewnątrz maszyny wirtualnej: VPS jest już klientem (guest), a użytkownik chce uruchomić na nim własnych klientów. Funkcja ta działa tylko wtedy, gdy hypervisor dostawcy celowo udostępnia rozszerzenia wirtualizacji procesora instancji — należy sprawdzić flagę vmx (Intel) lub svm (AMD) w /proc/cpuinfo. Jeśli żadna z nich nie występuje, żadna konfiguracja wewnątrz VPS nie rozwiąże problemu.
Ważne zastrzeżenie: Docker nie wymaga tych funkcji. Kontenery współdzielą jądro (kernel) systemu VPS i nie korzystają z /dev/kvm. Jeśli celem jest "uruchomienie kilku usług w kontenerach na serwerze", wymagane zasoby są już dostępne. Wirtualizacja zagnieżdżona jest wymagana, gdy potrzebne jest drugie jądro — np. laboratorium Proxmox, klient Windows, mikroVM Firecracker, emulator Android, środowisko testowe Kubernetes z rzeczywistymi maszynami VM lub runnery CI uruchamiające obrazy VM.
Co jest faktycznie zagnieżdżane
Trzy warstwy:
- L0 — hypervisor dostawcy, działający bezpośrednio na sprzęcie. Brak dostępu do tej warstwy.
- L1 — VPS. Dla warstwy L0 jest to tylko maszyna gościa.
- L2 — maszyna VM uruchamiana wewnątrz VPS.
Wirtualizacja sprzętowa to VT-x (flaga vmx) oraz EPT na procesorach Intel, a AMD-V / SVM (svm) oraz RVI/NPT na procesorach AMD. Hypervisor wykorzystuje te instrukcje, aby wejść w tryb gościa i umożliwić procesorowi jednoczesne przeszukiwanie dwóch tablic stron.
Żadna z tych technologii nie została zaprojektowana jako reentrant, dlatego zagnieżdżanie jest emulowane: gdy L1 wykonuje instrukcję VMX, następuje przechwycenie (trap) do L0, które utrzymuje struktury shadow w imieniu L1 dla L2. KVM realizuje to wydajnie, jednak L0 musi wykonywać dodatkowe operacje przy każdym wyjściu (exit) — dlatego dostawca musi umożliwić tę funkcję.
Dla przyspieszonego działania L2 muszą zostać spełnione oba warunki:
- Moduł KVM w L0 musi być załadowany z flagą
nested=1. - L0 musi przypisać VPS model procesora posiadający flagę —
<cpu mode='host-passthrough'/>w libvirt,cpu: hostw Proxmox,-cpu hostw surowym QEMU. Generyczny model emulowany (qemu64,kvm64) ukrywavmx, nawet gdy zagnieżdżanie jest włączone globalnie.
Sprawdź swój VPS w jedną minutę
# 1. Are you in a VM, and under what?
systemd-detect-virt # kvm, vmware, xen, microsoft, or "none" on metal
# 2. Does the CPU expose the extensions to you?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u
lscpu | grep -i -E 'virtual|hypervisor'
# 3. The definitive check
sudo apt update && sudo apt install -y cpu-checker
kvm-ok
# 4. The device node the whole stack depends on
ls -l /dev/kvmSprawna instancja zwraca vmx lub svm, kvm-ok zwraca KVM acceleration can be used, a /dev/kvm występuje jako root:kvm w trybie 660. Jeśli flaga jest obecna, ale węzeł urządzenia nie istnieje, należy ręcznie załadować moduł i sprawdzić logi jądra:
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20Jeden plik jest często cytowany, lecz błędnie interpretowany:
cat /sys/module/kvm_intel/parameters/nested # Y or NWewnątrz Twojego VPS jest to ustawienie modułu KVM, które decyduje o tym, czy gość L2 może uruchomić trzeci poziom gniazdowania (nesting). Nie określa ono, czy L0 umożliwiło gniazdowanie dla Ciebie — informację tę podają /proc/cpuinfo oraz kvm-ok. Parametr nested jest ustawieniem, które konfiguruje się na własnym sprzęcie:
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intelUsunięcie modułu jest niemożliwe, gdy maszyna wirtualna jest uruchomiona; należy najpierw wyłączyć wszystkie instancje gościa.
Dlaczego większość dostawców VPS wyłącza tę funkcję
- Live migration. Udostępnienie
vmxoznacza ujawnienie modelu CPU posiadającego flagę. Gość zależny od tych funkcji CPU nie może zostać bezpiecznie przeniesiony na maszynę, której CPU ich nie posiada. Host, który odciąża węzły poprzez migrację klientów, traci tę możliwość w momencie włączenia nestingu. - Powierzchnia ataku. Ścieżki nested VMX/SVM należą do najbardziej złożonych fragmentów kodu w warstwie wirtualizacji jądra i posiadają historię podatności CVE.
- L0 może nie być KVM. Jeśli
systemd-detect-virtwypisujevmware,xenlubmicrosoft, reguły nestingu należą do tego stosu, a nie do KVM.
Brak flagi na instancji? Skontaktuj się z supportem (niektórzy włączają ją na pojedyncze VM), wybierz plan dokumentujący nesting lub przejdź na serwer dedykowany. Dalsza część tekstu zakłada uprawnienia root na maszynie, która wyświetla flagę.
Uruchamianie gościa L2 przy użyciu libvirt
sudo apt install -y qemu-system-x86 libvirt-daemon-system virtinst ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER" # log out and back in
virt-install \
--name guest1 \
--memory 2048 \
--vcpus 2 \
--cpu host-passthrough \
--disk path=/var/lib/libvirt/images/guest1.qcow2,size=20,format=qcow2,bus=virtio \
--network network=default,model=virtio \
--os-variant debian13 \
--location https://deb.debian.org/debian/dists/trixie/main/installer-amd64/ \
--graphics none \
--console pty,target_type=serial \
--extra-args 'console=ttyS0,115200n8'Sesja graficzna nie jest wymagana. Instalacja przez port szeregowy (serial) trwa długo, dlatego należy ją uruchomić wewnątrz trwałej powłoki: ten sam workflow tmux, który utrzymuje sesje Claude Code na VPS pozwala na podtrzymanie konsoli virt-install po zerwaniu połączenia SSH. Jeśli --os-variant debian13 zostanie odrzucone, oznacza to, że osinfo-db jest starsza niż wersja wydana — należy uruchomić osinfo-query os i wybrać istniejącą nazwę. --cpu host-passthrough przekazuje vmx do poziomu L2; jest to wymagane tylko wtedy, gdy L2 musi przeprowadzić własną wirtualizację. Aby zapewnić bezpieczeństwo rozruchu gościa, należy użyć virsh autostart guest1.
Szyna virtio dla dysku i karty sieciowej (NIC) nie służy jedynie celom estetycznym: emulowane urządzenia IDE oraz e1000 generują znacznie więcej przerwań (traps) do hiperwizora niż kolejki virtio, a w przypadku gniazdowania (nesting) każde przerwanie jest procesowane dwukrotnie.
Networking: elementy pomijane w poradnikach
VPS posiada jeden publiczny adres IP i znajduje się za siecią filtrującą nieznane adresy MAC. Wynikają z tego dwa skutki.
Mostkowanie (bridging) gości L2 do sieci publicznej zazwyczaj nie działa. Po ustawieniu br0 na publicznym interfejsie NIC oraz przypisaniu gościowi własnego adresu MAC, zapytania ARP nie otrzymają odpowiedzi — przełącznik dostawcy odrzuca ramki pochodzące z adresu MAC, który nie został przydzielony. Jeśli występuje taki objaw, należy zaprzestać debugowania mostka; jest to działanie mechanizmu sieci.
Zamiast tego należy używać sieci NAT. libvirt dostarcza default: virbr0, 192.168.122.0/24 oraz dzierżawy dnsmasq, co zapewnia natychmiastową łączność wychodną. W przypadku połączeń przychodzących należy terminować TLS na L1 i stosować proxy — ścieżki certyfikatów poniżej pochodzą z wydawania certyfikatu Let's Encrypt za pomocą Certbot na Nginx:
server {
listen 443 ssl;
server_name lab.example.com;
ssl_certificate /etc/letsencrypt/live/lab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;
location / {
proxy_pass http://192.168.122.50:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Najpierw należy przypisać gościowi statyczną dzierżawę (virsh net-edit default), aby adres w proxy_pass pozostał niezmienny.
Interfejsy zarządzania pozostają odcięte od internetu: VNC na porcie 5900 oraz interfejs webowy Proxmox na porcie 8006 powinny być dostępne przez loopback, poprzez tunel SSH (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) lub przez własny serwer VPN WireGuard do VPS, co umieszcza całą podsieć gości 192.168.122.0/24 o jeden prywatny skok od sieci. Należy stosować restrykcyjne reguły firewall — sudo ufw allow 22,80,443/tcp, nic więcej. Jeśli goście tracą łączność wychodną natychmiast po włączeniu ufw, typową przyczyną jest DEFAULT_FORWARD_POLICY="DROP" w /etc/default/ufw — należy ustawić go na ACCEPT i przeładować ufw.
Proxmox na VPS
Proxmox VE 9 bazuje na systemie Debian 13. Instalacja na VPS z systemem Debian polega na dodaniu repozytorium pve-no-subscription oraz pakietu proxmox-ve. Należy pobrać linie repozytorium oraz klucza keyring z oficjalnej dokumentacji Proxmox — użycie adresu URL skopiowanego ze starego wpisu na blogu spowoduje błąd instalacji.
Najtrudniejsze nie są pakiety. Proxmox wymaga mostka vmbr0 podłączonego do fizycznej karty sieciowej (NIC), co powoduje problem z filtrowaniem adresów MAC opisany powyżej. Rozwiązaniem działającym na VPS jest mostek vmbr0 w trybie NAT lub routingu bez przypisanej fizycznej karty. Maszyny gości muszą znajdować się w prywatnym zakresie adresów, a dla usług publicznych należy skonfigurować reguły DNAT lub reverse proxy na hoście. W przypadku, gdy usługi publiczne są kontenerami, a nie maszynami wirtualnymi, Traefik obsługujący wiele aplikacji z jednego pliku Docker Compose realizuje to samo zadanie routingu i zapewnia automatyczne certyfikaty. Najpierw wykonaj snapshot /etc/network/interfaces: błędna definicja mostka uniemożliwia dostęp do maszyny, do której konsola może być niedostępna.
Wydajność, bez ubarwień
Wirtualizacja zagnieżdżona (nested) jest wolniejsza od jednowarstwowej. Przyczyna jest konkretna: koszt nie wynika z dostępu do pamięci, lecz z wyjść (exits). Dzięki technologiom EPT/NPT, warstwa L0 utrzymuje shadow page tables dla L2, co pozwala na odczyty pamięci z prędkością sprzętową. Kosztowne są operacje powodujące wyjście z trybu guest: I/O, przerwania czasowe, MMIO oraz przerwania interprocesorowe (IPI). Każde wyjście L2 musi zostać obsłużone przez L0 i może zostać przekazane z powrotem przez L1. Zadania obciążające CPU przy danych w pamięci RAM wykazują wydajność zbliżoną do natywnej. Operacje zdominowane przez syscalls, pakiety sieciowe oraz disk I/O wykazują wyraźny spadek wydajności przez dodatkowe warstwy.
Wniosek: należy stosować urządzenia virtio w każdym miejscu. Plik qcow2 znajduje się na dysku, który został już zvirtualizowany przez dostawcę. Powstają dwie warstwy thin-provisioning, gdzie cache=none na dysku gościa zapobiega jednoczesnemu przechowywaniu tych samych bloków w dwóch pamięciach cache stron. Nie podajemy wyników benchmarków: należy zmierzyć wydajność własnego obciążenia na własnej instancji.
Tryby awarii oraz wyświetlane komunikaty
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used z kvm-ok. Moduł nie został załadowany lub flaga nie jest wystawiona. Najpierw sprawdź /proc/cpuinfo.
kvm: disabled by bios w dmesg. W systemach bare metal należy przełączyć opcję VT-x/SVM w firmware. W środowisku VPS oznacza to, że L0 nie udostępnia rozszerzeń; żadna konfiguracja wewnątrz guest nie zmieni tego stanu.
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. Procesor wykrywany przez kernel nie posiada vmx — jest to decyzja warstwy L0.
Could not access KVM kernel module: Permission denied. Przyczyną są uprawnienia, a nie sprzęt. ls -l /dev/kvm powinien wskazywać grupę kvm i tryb 660; należy dodać użytkownika do tej grupy i uruchomić nową powłokę loginową, ponieważ przynależność do grupy nie jest aktualizowana w trwającej sesji.
kvm: Device or resource busy podczas uruchamiania QEMU. Inny moduł hypervisora zajmuje procesor: należy uruchomić lsmod, sprawdzić, czy obok kvm_intel występują moduły vboxdrv lub VMware, a następnie odładować niepożądany moduł.
/var/run/libvirt/libvirt-sock: No such file or directory z virsh. Usługa (daemon) nie działa: sudo systemctl enable --now libvirtd.
Proxmox: KVM virtualisation configured, but not available. Gość ma zaznaczoną akcelerację KVM na hoście, który nie może jej zapewnić. Należy naprawić nesting lub odznaczyć tę opcję, aby używać emulacji.
Android emulator: x86_64 emulation currently requires hardware acceleration! ponownie /dev/kvm — zazwyczaj problem z grupą.
Brak błędów, a wydajność jest bardzo niska. QEMU bez flagi akceleratora przełącza się na TCG (emulator programowy). Działanie jest poprawne, ale bardzo wolne — czas bootowania wydłuża się z sekund do minut. Należy jawnie przekazać -accel kvm, aby QEMU przerywał działanie z błędem zamiast cichej emulacji.
Gość znika w trakcie pracy. Należy sprawdzić dmesg pod kątem Out of memory: Killed process ... qemu-system-x86_64. Gość L2 jest procesem w L1, a mechanizm OOM killer traktuje go jak każdy inny proces. Pamięć RAM dla L2 pochodzi z przydzielonej puli L1 — nie można jej pożyczyć bezpośrednio od hosta.
Eksploatacja: kopie zapasowe, aktualizacje, limity
Kopie zapasowe. Kopiowanie pliku qcow2 działającej maszyny guest powoduje uszkodzenie obrazu. Należy użyć virsh shutdown guest1 i wykonać kopiowanie lub wykonać zewnętrzny snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic). Dzięki temu zapisy są kierowane do overlay, co pozwala na kopiowanie statycznego pliku base, a następnie scalenie zmian za pomocą virsh blockcommit. Kopie należy przesyłać poza VPS — snapshot na tym samym dysku nie zapewnia ochrony.
Aktualizacje. apt full-upgrade instaluje nowe moduły kvm_intel/kvm_amd, jednak działające jądro zachowuje stare moduły aż do restartu systemu. Należy zachować poprzednie jądro i ponownie uruchomić kvm-ok po każdej zmianie jądra: host bez vmx wymaga jedynie jednego wpisu w menu bootowania, aby odzyskać sprawność.
Granice skalowalności. Jeden publiczny adres IP oznacza, że każda usługa L2 komunikuje się ze światem przez proxy lub regułę DNAT na L1. Funkcja live migration nie jest dostępna. Przy wysokim obciążeniu CPU ścieżka nested exit wykazuje największe opóźnienia. Hypervisor z wieloma maszynami guest zużywa dostępny RAM — wirtualizacja zagnieżdżona (nested VMs) nie pozwala na obejście sztywnej alokacji poprzez overcommit. Gdy środowisko laboratoryjne przekracza te limity, rozwiązaniem nie jest budowa głębszego stosu zagnieżdżonego, lecz dedykowany serwer, gdzie użytkownik ma uprawnienia L0 i powyższe ograniczenia nie obowiązują.
FAQ
Do I need nested virtualization to run Docker on a VPS?
No. Containers share your VPS kernel and never open /dev/kvm, so a plain instance with no vmx or svm flag runs Docker and Docker Compose fine. Nesting only matters when you want a second kernel: a Proxmox lab, a Windows guest, Firecracker microVMs, an Android emulator, or CI runners that boot VM images.
How do I check whether my VPS supports nested virtualization?
Run grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u, then kvm-ok from the cpu-checker package. A usable instance prints vmx (Intel) or svm (AMD), kvm-ok reports KVM acceleration can be used, and /dev/kvm exists with group kvm and mode 660. Ignore /sys/module/kvm_intel/parameters/nested for this question — that file describes your own KVM module, not what the provider's hypervisor exposed to you.
Why do most VPS providers disable nested virtualization?
Exposing vmx means handing the guest a CPU model that carries the flag, and a guest that depends on those CPU features cannot be live-migrated onto a machine whose CPU lacks them — a provider that drains nodes by moving customers around gives that up. The nested VMX/SVM code paths also carry a long CVE history. Some hosts still enable it per-VM on request, and others document nesting as a plan feature.
My nested VM has no network on the public bridge. What is wrong?
The provider's switch drops frames from a MAC address it never leased you, so an L2 guest bridged onto the public NIC sends ARP and hears nothing back. Stop debugging br0 — use libvirt's NAT default network (virbr0, 192.168.122.0/24), give the guest a static lease, and publish anything public through a reverse proxy or DNAT rule on the VPS itself.
How much slower is a nested VM?
The cost lands on VM exits, not on memory access. With EPT/NPT active, ordinary reads and writes inside L2 run at hardware speed, while I/O, timer interrupts, MMIO and IPIs are handled by L0 and may be bounced back through L1. CPU-bound work over data already in RAM looks close to native; syscall-, packet- and disk-heavy workloads feel every layer. Use virtio devices everywhere and cache=none on guest disks, then measure your own workload.