SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Вложенная виртуализация на VPS: как запустить Proxmox

Узнайте, поддерживает ли ваш VPS вложенную виртуализацию. Проверьте флаг vmx через kvm-ok и разберитесь, почему без аппаратной поддержки вы получите ошибку KVM: disabled by BIOS.

Краткий ответ

Вложенная виртуализация (nested virtualization) — это гипервизор, работающий внутри виртуальной машины: ваш VPS уже является гостевой системой, и вы хотите запустить на нем собственные виртуальные машины. Это работает только в том случае, если гипервизор провайдера намеренно предоставляет вашей инстанции доступ к аппаратным расширениям виртуализации процессора. Проверьте /proc/cpuinfo на наличие флага vmx (для Intel) или svm (для AMD). Если ни один из них не отображается, никакие настройки внутри VPS не исправят ситуацию.

Важное уточнение: Docker не требует вложенной виртуализации. Контейнеры используют ядро вашего VPS и никогда не обращаются к /dev/kvm. Если ваша цель — «запустить несколько сервисов в контейнерах на сервере», у вас уже есть всё необходимое. Вложенность нужна, если вы планируете использовать второе ядро, лабораторную среду Proxmox, гостевую ОС Windows, микро-ВМ Firecracker, эмулятор Android, тестовый кластер Kubernetes на базе полноценных ВМ или CI-раннеры, загружающие образы виртуальных машин.

Что именно подвергается вложенности

Существует три уровня:

  • L0, гипервизор провайдера, работающий на «железе». У вас нет к нему доступа.
  • L1, ваш VPS. Для L0 это просто гостевая система.
  • L2, виртуальная машина, которую вы хотите запустить внутри вашего VPS.

Аппаратная виртуализация — это VT-x (флаг vmx) плюс EPT на Intel, или AMD-V / SVM (svm) плюс RVI/NPT на AMD. Гипервизор использует эти инструкции для перехода в гостевой режим и для того, чтобы позволить процессору одновременно работать с двумя таблицами страниц.

Ни одна из этих технологий не проектировалась как реентерабельная, поэтому вложенность эмулируется: когда L1 выполняет VMX-инструкцию, такую как VMLAUNCH или VMRESUME, происходит перехват (trap) на уровень L0, который поддерживает теневые структуры для L2 от имени L1. На процессорах с поддержкой VMCS shadowing инструкции VMREAD и VMWRITE уровня L1 могут выполняться без выхода (exit), что устраняет значительную часть нагрузки, но не всю. KVM хорошо справляется с этой задачей, но именно L0 выполняет дополнительную работу при каждом выходе, поэтому провайдер должен разрешить использование этой функции.

Если L0 — это KVM, для ускорения работы L2 должны выполняться два условия:

  1. Модуль KVM на уровне L0 загружен с параметром nested=1.
  2. L0 предоставляет вашему VPS модель процессора, которая поддерживает этот флаг: <cpu mode='host-passthrough'/> в libvirt, cpu: host в Proxmox, -cpu host в «чистом» QEMU. Стандартная эмулируемая модель (qemu64, kvm64) скрывает vmx, даже если вложенность включена глобально.

У других гипервизоров есть свои переключатели. Например, Hyper-V эмулирует расширения виртуализации для вложенного гипервизора внутри своих ВМ, но только в тех ВМ, где вложенность была включена индивидуально.

Проверка VPS за одну минуту

# 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/kvm

Рабочий экземпляр выводит vmx или svm, kvm-ok сообщает KVM acceleration can be used, а /dev/kvm существует как root:kvm в режиме 660. Если флаг присутствует, но узел устройства отсутствует, загрузите модуль вручную и изучите журнал ядра:

sudo modprobe kvm_intel     # or kvm_amd
sudo dmesg | tail -n 20

Один файл постоянно цитируют и часто понимают неверно:

cat /sys/module/kvm_intel/parameters/nested   # Y or N

Внутри вашего VPS это настройка вашего модуля KVM, которая определяет, может ли гостевая система L2 вкладывать третий уровень. Она ничего не говорит о том, включил ли для вас вложенность уровень L0; /proc/cpuinfo и kvm-ok дают ответ на этот вопрос. Параметр nested — это переключатель, который вы настраиваете на машине, находящейся в вашем полном владении:

echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel

Удаление модуля запрещено, пока работает виртуальная машина, поэтому сначала выключите гостевые системы. Если этот компьютер является узлом Proxmox, в материале включение вложенной виртуализации в Proxmox VE 9 описано то же изменение в modprobe.d, а также настройка cpu: host для каждой виртуальной машины, благодаря которой флаг становится виден внутри гостевой системы.

Почему большинство хостинг-провайдеров VPS отключают эту функцию

  • Live migration. Предоставление vmx означает использование модели процессора с соответствующим флагом. Гостевая система, зависящая от этих функций процессора, не может быть безопасно перенесена на машину, процессор которой их не поддерживает. Хостинг, который освобождает узлы путем миграции клиентов, теряет эту возможность сразу после включения вложенной виртуализации.
  • Поверхность атаки. Пути вложенного VMX/SVM являются одними из самых сложных участков кода в уровне виртуализации ядра, что подтверждается историей CVE.
  • L0 может быть не KVM. Если systemd-detect-virt выводит vmware, xen или microsoft, то правила вложенности определяются этим стеком, а не KVM.

На вашем экземпляре нет флага? Обратитесь в службу поддержки (некоторые провайдеры включают его для отдельных ВМ), выберите тарифный план с поддержкой вложенной виртуализации или перейдите на выделенный сервер. Дальнейшее руководство предполагает наличие прав root на машине, где этот флаг отображается.

Запуск гостевой системы L2 с помощью 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'

Графическая сессия не требуется. Установка через последовательный порт занимает некоторое время, поэтому запускайте её внутри постоянной оболочки: тот же рабочий процесс tmux, который поддерживает сессии Claude Code на VPS, позволяет держать консоль virt-install активной при разрыве SSH-соединения. Если --os-variant debian13 отклоняется, значит ваша версия osinfo-db старше данного релиза; выполните osinfo-query os и выберите существующее имя. --cpu host-passthrough пробрасывает vmx внутрь L2; это необходимо только в том случае, если L2 должна в свою очередь выполнять виртуализацию. Обеспечьте безопасную загрузку гостевой системы с помощью virsh autostart guest1.

Шина virtio для диска и сетевой карты — это не декорация: эмулируемые устройства IDE и e1000 обращаются к гипервизору гораздо чаще, чем очереди virtio. При вложенной виртуализации выход из гостя, который L0 не может обработать самостоятельно, транслируется на уровень L1, где его обработка может спровоцировать дополнительные выходы.

Сети: то, что пропускают в руководствах

Ваш VPS имеет один публичный IP-адрес и находится за сетевой инфраструктурой, которая фильтрует неизвестные MAC-адреса. Из этого следуют два вывода.

Объединение L2-гостей в мост с публичной сетью обычно не работает. Если вы настроите br0 на публичном сетевом интерфейсе и присвоите гостевой системе собственный MAC-адрес, вы увидите, что ARP-запросы уходят, но ответов нет: коммутатор провайдера отбрасывает кадры от MAC-адреса, который он вам не выделял. Если вы столкнулись с этим симптомом, прекратите отладку моста; это особенность работы механизма.

Используйте сеть NAT. libvirt поставляет default: virbr0, 192.168.122.0/24, выдачу адресов через dnsmasq, исходящий трафик работает сразу. Для входящего трафика завершайте TLS на L1 и проксируйте запросы внутрь; пути к сертификатам ниже взяты из руководства выпуск сертификата Let's Encrypt с помощью Certbot в 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;
    }
}

Сначала назначьте гостевой системе статический адрес (virsh net-edit default), чтобы адрес в файле proxy_pass оставался неизменным.

Интерфейсы управления должны быть закрыты от интернета: VNC на порту 5900 и веб-интерфейс Proxmox на 8006 должны работать только через loopback. Доступ к ним осуществляется через SSH-туннель (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) или через собственный VPN-сервер WireGuard на VPS, который делает весь диапазон адресов гостевых систем 192.168.122.0/24 доступным в один внутренний переход. Ограничьте настройки межсетевого экрана, sudo ufw allow 22,80,443/tcp, и ничего более. Если у гостевых систем пропадает исходящая связь сразу после включения ufw, типичная причина — DEFAULT_FORWARD_POLICY="DROP" в файле /etc/default/ufw; установите значение ACCEPT и перезагрузите ufw.

Proxmox на VPS

Proxmox VE 9 базируется на Debian 13, поэтому он устанавливается на VPS с Debian путем добавления репозитория pve-no-subscription и пакета proxmox-ve. Используйте строки репозитория и ключи из актуальной документации Proxmox; URL, скопированный из старой статьи, приведет к ошибке установки. Стоит ли размещать Proxmox на арендованном оборудовании — вопрос, который нужно решить до того, как вы потратите вечер на настройку сети, а сравнение стоимости и возможностей домашнего сервера Proxmox и арендованного VPS содержит расчеты мощности и оборудования, которые помогут вам определиться.

Пакеты — это не самая сложная часть. Proxmox ожидает, что vmbr0 будет объединен с физическим сетевым интерфейсом, что сразу приводит к проблеме фильтрации MAC-адресов, описанной выше. Рабочая конфигурация на VPS — это NAT или маршрутизируемый vmbr0 без привязки к физическому порту, гостевые системы в частной подсети и правила DNAT или reverse proxy на хосте для публичного доступа. Если публичные сервисы работают в контейнерах, а не в виртуальных машинах, Traefik для управления несколькими приложениями через один Docker Compose описывает решение той же задачи маршрутизации с автоматическим выпуском сертификатов. Сначала сделайте snapshot /etc/network/interfaces: некорректное определение bridge может заблокировать доступ к машине, консоль которой может быть вам недоступна.

Производительность: честный взгляд

Вложенная виртуализация работает медленнее, чем одноуровневая, и механизм этого замедления конкретен: основные затраты приходятся на выходы из гостевой системы (exits) и трансляцию адресов, а не на обычные инструкции. При наличии EPT/NPT гипервизор L0 объединяет таблицы страниц L1 для L2 и свои собственные в одну теневую таблицу, поэтому при попадании в TLB выполнение идет на аппаратной скорости. Промах в TLB обходится дороже: оборудование выполняет обход таблицы страниц гостя и теневой таблицы одновременно, а каждое изменение, которое L1 вносит в свои таблицы, вызывает выход из режима гостя, чтобы L0 мог синхронизировать теневую таблицу. Дорогостоящими становятся все операции, требующие выхода из режима гостя: ввод-вывод, таймерные прерывания, MMIO, межпроцессорные прерывания, так как выход из L2 обрабатывается гипервизором L0 и может транслироваться обратно через L1. Вычисления, ограниченные мощностью процессора (CPU-bound) с небольшим рабочим набором данных, работают почти со скоростью «железа»; большие рабочие наборы в оперативной памяти приводят к затратам на промахи TLB, а задачи, где преобладают системные вызовы, обработка пакетов и дисковый ввод-вывод, ощущают влияние всех уровней.

Итог: используйте устройства virtio везде, где это возможно. Ваш файл qcow2 находится на диске, который провайдер уже виртуализировал — это два уровня thin-provisioning, наложенных друг на друга, где cache=none на гостевом диске предотвращает дублирование одних и тех же блоков в двух кэшах страниц одновременно. Здесь нет результатов тестов: измеряйте производительность своей рабочей нагрузки на своем собственном экземпляре.

Типичные ошибки и сообщения, которые вы увидите

INFO: /dev/kvm does not exist / KVM acceleration can NOT be used из kvm-ok. Либо модуль не загружен, либо флаг не доступен. Сначала проверьте /proc/cpuinfo.

kvm: disabled by bios в dmesg. На физическом сервере переключите параметр VT-x/SVM в настройках BIOS/UEFI. Внутри VPS это означает, что L0 не предоставляет вам расширения, и никакие действия внутри гостевой системы это не изменят.

modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. Процессор, который видит ваше ядро, не имеет vmx; это также решение уровня L0.

Could not access KVM kernel module: Permission denied. Проблема прав доступа, а не оборудования. ls -l /dev/kvm должен показывать группу kvm и права 660; добавьте себя в эту группу и запустите новый сеанс оболочки, так как членство в группах не применяется к уже запущенным сессиям.

kvm: Device or resource busy при запуске QEMU. Другой модуль гипервизора занял процессор: выполните lsmod, найдите vboxdrv или модули VMware рядом с kvm_intel и выгрузите тот, который вам не нужен.

/var/run/libvirt/libvirt-sock: No such file or directory из virsh. Демон не запущен: sudo systemctl enable --now libvirtd.

Proxmox: KVM virtualisation configured, but not available. У гостевой системы включено ускорение KVM на хосте, который не может его предоставить. Исправьте настройки вложенной виртуализации (nesting) или отключите ускорение, согласившись на программную эмуляцию.

Android emulator: x86_64 emulation currently requires hardware acceleration! Снова /dev/kvm, обычно это случай с правами группы.

Ошибок нет, но всё работает крайне медленно. QEMU без флага ускорителя переключается на TCG — программный эмулятор. Это работает корректно, но медленно: загрузка, которая должна занимать секунды, растягивается на минуты. Явно укажите -accel kvm, чтобы QEMU завершался с ошибкой вместо того, чтобы тихо переходить на эмуляцию.

Гостевая система внезапно исчезает во время работы. Ищите в dmesg записи о Out of memory: Killed process ... qemu-system-x86_64. Гостевая система L2 является процессом на уровне L1, и OOM killer обрабатывает её как любой другой процесс. Оперативная память L2 выделяется из фиксированного объема L1, заимствование ресурсов у хоста невозможно.

Эксплуатация: резервное копирование, обновления, ограничения

Резервное копирование. Копирование файла qcow2 работающей гостевой системы создает риск получения несогласованного образа, так как гостевая система продолжает запись во время чтения. Либо выполните virsh shutdown guest1, дождитесь, пока virsh domstate guest1 сообщит о shut off (команда выключения может завершиться до того, как гостевая система полностью остановится), и только после этого копируйте; либо создайте внешний снапшот (virsh snapshot-create-as guest1 snap1 --disk-only --atomic), чтобы операции записи перенаправлялись в оверлей, пока вы копируете статический базовый образ, а затем объедините его обратно с помощью virsh blockcommit guest1 vda --active --pivot. Переносите копии за пределы VPS, так как снапшот на том же диске не защищает ни от чего.

Обновления. apt full-upgrade устанавливает новые модули kvm_intel/kvm_amd, но работающее ядро продолжает использовать старые до тех пор, пока вы не выполните перезагрузку. Оставляйте предыдущее ядро установленным и повторно запускайте kvm-ok после каждого изменения ядра: если хост после перезагрузки останется без vmx, вы сможете вернуть его в рабочее состояние, просто выбрав нужный пункт в меню загрузчика.

Пределы масштабирования. Один публичный IP-адрес означает, что любой сервис L2 выходит в сеть через прокси или правило DNAT на уровне L1. Живая миграция (live migration) здесь невозможна. При нехватке ресурсов CPU первым делом замедляется путь выхода из вложенной виртуализации (nested exit path). Гипервизор с несколькими гостевыми системами — это машина, оперативная память которой уже распределена; вложенные виртуальные машины не могут использовать оверкоммит для обхода фиксированного выделения ресурсов. Когда лаборатория перерастает эти рамки, решение заключается не в наращивании вложенного стека, а в использовании выделенного сервера, где вы являетесь уровнем L0 и данные ограничения не применяются.

FAQ

Нужно ли мне вложенная виртуализация для запуска Docker на VPS?

Нет. Контейнеры используют ядро вашего VPS и не запускают /dev/kvm, поэтому обычный инстанс без флагов vmx или svm корректно работает с Docker и Docker Compose. Вложенность требуется только если вам нужно второе ядро: для лаборатории Proxmox, гостевой ОС Windows, микро-ВМ Firecracker, эмулятора Android или CI-раннеров, которые загружают образы ВМ.

Как проверить, поддерживает ли мой VPS вложенную виртуализацию?

Выполните grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u, а затем kvm-ok из пакета cpu-checker. Пригодный инстанс выведет vmx (Intel) или svm (AMD), kvm-ok покажет KVM acceleration can be used, а файл /dev/kvm будет существовать с группой kvm и правами 660. Игнорируйте /sys/module/kvm_intel/parameters/nested в контексте этого вопроса: этот файл описывает ваш собственный модуль KVM, а не то, что гипервизор провайдера предоставил вам.

Почему большинство провайдеров VPS отключают вложенную виртуализацию?

Предоставление vmx означает передачу гостевой системе модели процессора с соответствующим флагом. Гостевая ОС, зависящая от этих функций процессора, не может быть «живой» миграцией перенесена на машину, где эти функции отсутствуют. Провайдеры, которые освобождают узлы путем перемещения клиентов, отказываются от такой возможности. Код вложенных VMX/SVM также имеет длинную историю CVE. Некоторые хостеры всё же включают эту функцию для ВМ по запросу, а другие указывают вложенность как особенность конкретного тарифного плана.

У моей вложенной ВМ нет сети на публичном мосту. В чем проблема?

Коммутатор провайдера отбрасывает кадры с MAC-адресом, который он вам не выдавал. Поэтому гостевая система L2, подключенная к публичному сетевому интерфейсу, отправляет ARP-запросы, но не получает ответа. Прекратите отладку br0, используйте NAT-сеть default в libvirt (virbr0, 192.168.122.0/24), назначьте гостевой системе статический адрес и публикуйте всё необходимое через reverse proxy или правило DNAT на самом VPS.

Насколько медленнее работает вложенная ВМ?

Потери производительности приходятся на выходы из ВМ (VM exits) и трансляцию адресов. При активных EPT/NPT инструкции и попадания в TLB внутри L2 выполняются на аппаратной скорости. Однако промах TLB приводит к обходу дополнительных таблиц страниц, а операции ввода-вывода, таймерные прерывания, MMIO и IPI обрабатываются на уровне L0 и могут возвращаться через L1. Вычисления, ограниченные мощностью процессора с небольшим рабочим набором данных, работают почти как на «железе». Большие рабочие наборы в памяти и нагрузки с интенсивным использованием системных вызовов, пакетов и диска ощущают влияние каждого слоя. Используйте устройства virtio везде и cache=none для гостевых дисков, а затем измерьте производительность на своей нагрузке.