MAATRIX / Блог / virtio против эмуляции: почему драйверы решают всё

virtio против эмуляции: почему драйверы решают всё

MAATRIX

Вы создаёте виртуальную машину в Proxmox или через libvirt, доходите до выбора типа диска и сетевой карты — и видите список из нескольких вариантов, среди которых есть что-то с непонятным словом virtio. По умолчанию мастер создания часто предлагает более «безопасный» с виду вариант — эмулированный IDE-диск или сетевую карту Intel E1000. Разница между этим выбором и virtio — не косметическая настройка, а фактор, который определяет, получите ли вы производительность реального железа или потеряете значительную её часть на ровном месте.

Что вообще эмулирует гипервизор

Когда вы создаёте виртуальную машину, гостевой ОС нужно с чем-то общаться: с диском, сетевой картой, видеокартой, контроллером USB. У гипервизора (в нашем случае QEMU под управлением KVM) есть два принципиально разных подхода к тому, как это устройство появится внутри VM.

Первый подход — полная эмуляция. QEMU программно воссоздаёт поведение конкретного реального устройства настолько точно, что немодифицированная гостевая ОС считает, будто работает с настоящим железом. Классические примеры — сетевая карта Intel E1000/E1000E, дисковый контроллер IDE/PIIX3, видеокарта Cirrus Logic или VGA. Гостевая ОС грузит для них тот же драйвер, что использовала бы на физическом сервере с такой картой — драйвер вообще не знает, что находится внутри виртуальной машины.

Второй подход — паравиртуализация через интерфейс virtio. Это устройство, которого не существует в физическом мире: оно с самого начала спроектировано под задачу «эффективно передавать данные между гостем и гипервизором», а не под задачу «выглядеть как конкретная железка 2000-х годов». Для virtio-устройства гостевой ОС нужен специальный драйвер, который знает про virtio-протокол — но взамен операции ввода-вывода обходятся без большей части накладных расходов эмуляции.

Почему эмуляция железа — это дорого

Чтобы понять, откуда берётся разница в производительности, стоит представить, что происходит при одной операции записи на диск через эмулированный IDE-контроллер.

Гостевая ОС не знает, что она в виртуалке. Она обращается к «диску» так, как обращалась бы к настоящему IDE/ATA-контроллеру — через порты ввода-вывода и регистры, с той же последовательностью команд, что ожидает реальный чип. Каждое такое обращение — это инструкция процессора, которая на реальном железе просто ушла бы в контроллер, а в виртуальной машине вызывает выход из гостевого режима исполнения в гипервизор (VM exit). Гипервизор перехватывает обращение, эмулирует поведение контроллера программно — сверяется с внутренним состоянием эмулируемого устройства, формирует ответ, который ожидал бы драйвер настоящего IDE-чипа, — и возвращает управление гостю.

Каждый VM exit и последующий вход обратно в гостевую систему (VM entry) стоит процессорного времени: сохранение и восстановление состояния, работа гипервизора, повторная валидация. Если устройство спроектировано для общения мелкими порциями (а старые протоколы вроде IDE и E1000 к этому склонны — они рассчитаны на частоту обращений реального железа 90-х и 2000-х годов), то на каждую полезную операцию приходится непропорционально много переключений контекста между гостем и хостом. Диск и сеть в виртуалке в таком режиме упираются не в физическую скорость накопителя или канала, а в накладные расходы самого механизма эмуляции.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Как virtio убирает эти накладные расходы

Виртио решает задачу иначе: вместо того чтобы притворяться конкретным физическим устройством, он даёт гостю и хосту общий эффективный протокол обмена данными, построенный вокруг разделяемой памяти и очередей (virtqueue). Гостевой драйвер кладёт запросы в кольцевой буфер в памяти, которую видят обе стороны, и уведомляет гипервизор об этом одним относительно дешёвым сигналом — вместо серии мелких обращений к портам ввода-вывода на каждый шаг протокола. Хост забирает пачку запросов из общей памяти, обрабатывает и складывает ответы туда же.

Смысл в том, что механизм изначально спроектирован с расчётом на виртуальное окружение: минимум VM exit на единицу полезной работы, передача данных большими порциями через общую память вместо посимвольной эмуляции регистров чипа. Именно поэтому виртуализация с virtio-устройствами показывает заметно меньшие накладные расходы по сравнению с эмуляцией классического железа — насколько именно меньше, зависит от нагрузки, ядра хоста, версии QEMU и конкретного профиля ввода-вывода, и здесь не будет универсального числа для всех случаев: если вам нужны точные цифры под вашу нагрузку, их стоит измерить на своём стенде через fio для диска и iperf3 для сети, сравнив virtio и эмулированное устройство при прочих равных.

Экосистема virtio не ограничивается диском и сетью. У неё есть несколько устройств под разные задачи:

УстройствоЧто виртуализируетТипичное применение
virtio-blk / virtio-scsiБлочное устройство (диск)Основной диск VM
virtio-netСетевой адаптерОсновной сетевой интерфейс VM
virtio-balloonУправление памятью гостяДинамический возврат неиспользуемой RAM хосту
virtio-rngИсточник энтропииУскорение генерации случайных чисел в гостe
virtio-consoleПоследовательная консольРанняя загрузка, отладка, serial-логи
virtio-fsПроброс файловой системы хостаОбщие каталоги хост-гость без сети

virtio-scsi стоит отдельного слова: это виртуализация не диска напрямую, а SCSI-транспорта поверх virtio-механизма. На практике virtio-scsi даёт больше гибкости (например, поддержку TRIM/discard, множество дисков через один контроллер, hotplug), тогда как virtio-blk чуть проще и в некоторых сценариях немного быстрее за счёт более короткого пути от гостя к хосту. Для большинства задач разница между ними не критична, и Proxmox по умолчанию предлагает virtio-scsi-single как разумный компромисс.

Почему для Linux-гостей это решение почти всегда очевидно

Ключевая практическая деталь: начиная с ядра версии около 2.6.25 (то есть уже больше пятнадцати лет), драйверы virtio входят в состав самого ядра Linux. Любой современный дистрибутив — Debian, Ubuntu, AlmaLinux, Rocky Linux, Arch — собирает virtio_net, virtio_blk, virtio_scsi, virtio_balloon и virtio_console прямо в стандартное ядро или как модули, загружаемые автоматически при обнаружении соответствующего устройства.

Практическое следствие: для Linux-гостя выбор virtio на этапе создания VM не требует от вас вообще ничего дополнительного. Драйвер уже есть в системе, ядро подхватит устройство при загрузке, ничего вручную ставить не нужно. Единственная ситуация, где стоит быть внимательнее — очень старые или сильно урезанные образы (например, минимальные initramfs для встраиваемых сценариев), где модуль virtio может быть осознанно выпилен из сборки; в подавляющем большинстве серверных дистрибутивов это не ваш случай.

Практическая проверка после установки Linux-гостя:

# Диск через virtio должен определяться как /dev/vda, а не /dev/sda
lsblk

# Сетевой интерфейс virtio обычно виден как ens18/enp1s0 в зависимости от схемы именования
ip link show

# Убедиться, что модуль загружен
lsmod | grep virtio

Если lsblk показывает диск как /dev/sda, а не /dev/vda — значит, VM создана с эмулированным SATA/IDE-контроллером, а не с virtio-blk/virtio-scsi, и стоит проверить настройки диска в конфигурации VM.

Почему для Windows это отдельная задача

С Windows ситуация принципиально другая: у гостевой ОС нет встроенных virtio-драйверов «из коробки». Если вы создадите Windows VM с диском virtio и запустите установку без дополнительных действий, инсталлятор Windows на этапе выбора диска для установки просто не увидит ни одного накопителя — драйвера, который умеет разговаривать с virtio-blk/virtio-scsi, в системе нет.

Решение — драйверы из пакета virtio-win, который поддерживается сообществом (проект Fedora/RedHat virtio-win, публикуется как ISO с драйверами и как пакет для Windows Update). Практическая последовательность для установки Windows на virtio в KVM:

1. Подключить к VM два образа: ISO с Windows и ISO virtio-win (как второй CD-привод)
2. На этапе выбора диска в инсталляторе Windows нажать "Load driver"
3. Указать путь на virtio-win ISO, например: 
   E:\vioscsi\w10\amd64\ (для virtio-scsi) или E:\viostor\w10\amd64\ (для virtio-blk)
4. После загрузки драйвера диск появится в списке — продолжить установку
5. После установки ОС аналогично поставить драйвер сетевой карты (NetKVM) 
   и, при желании, virtio-balloon (Balloon) для динамической памяти

Из-за этой дополнительной возни некоторые администраторы на старте создают Windows VM с эмулированным диском (SATA) и сетевой картой E1000 «чтобы просто заработало», планируя переключиться на virtio позже — и потом забывают об этом на месяцы. Смена системного диска с SATA на virtio-scsi постфактум на уже установленной и загруженной Windows возможна, но требует аккуратности: сначала нужно установить драйвер virtio-win, пока диск ещё эмулированный (иначе система не сможет загрузиться после смены типа контроллера), и только потом менять тип устройства в конфигурации VM.

Практический чек-лист при создании VM

Что стоит явно проверить в момент создания виртуальной машины, а не полагаться на значение по умолчанию:

  • Диск. В Proxmox — тип Bus/Device должен быть VirtIO Block или SCSI с контроллером VirtIO SCSI (не SATA, не IDE). В libvirt/virt-manager — Disk bus: virtio в разделе диска.
  • Сеть. В Proxmox — модель сетевого адаптера VirtIO (paravirtualized) (не Intel E1000, не Realtek RTL8139). В virt-manager — Device model: virtio на вкладке NIC.
  • Для Linux-гостя — после первой загрузки проверить /dev/vda и ip link, как показано выше; если диск определился как /dev/sda, пересоздайте диск с правильным типом контроллера до того, как накопите на нём данные.
  • Для Windows-гостя — заранее скачать актуальный virtio-win ISO и подключить его вторым приводом ещё до начала установки, чтобы не прерывать инсталляцию на середине.
  • Баланс памяти. Если планируете динамически перераспределять RAM между VM (ballooning), драйвер virtio-balloon должен быть установлен в госте заранее — иначе гипервизор не сможет запросить у гостя освобождение памяти.
  • Не путайте virtio-scsi и virtio-blk с «SCSI (virtio)» и просто «SCSI» — в интерфейсе Proxmox легко выбрать SCSI-контроллер типа LSI 53C895A (эмуляция) вместо VirtIO SCSI по невнимательности, оба варианта называются похоже.

О более широком наборе мест, где виртуализация в принципе теряет производительность — не только на устройствах ввода-вывода, но и на уровне VM exit при работе с памятью и планировщиком — можно почитать в статье где виртуализация теряет производительность. Если стоит более общий вопрос выбора между Proxmox и голым KVM/libvirt для управления такими VM, разбор — в статье Proxmox или голое KVM: что выбрать. А для случаев, когда даже virtio-диска недостаточно и нужен прямой доступ гостя к физическому накопителю или USB-контроллеру, — в статье проброс диска и USB в виртуалку.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Если я уже создал VM с эмулированным диском, можно ли переключиться на virtio без переустановки ОС?

Да, для Linux это обычно безопасно: подключите диск как virtio, убедитесь что initramfs содержит модуль virtio_blk/virtio_scsi (update-initramfs -u в Debian/Ubuntu или dracut -f в RHEL-подобных с добавлением модуля в конфиг), затем смените тип устройства в конфигурации VM. Для Windows порядок обратный — сначала поставьте драйвер virtio-win, пока диск ещё эмулированный, потом меняйте тип контроллера, иначе система не загрузится.

Virtio работает только в KVM/QEMU или ещё где-то?

Спецификация virtio — открытый стандарт (VIRTIO, ныне под OASIS), её также поддерживают другие гипервизоры, но на практике в контексте аренды VPS и серверов вы почти всегда встретите virtio именно в связке с KVM/QEMU — это основная платформа, где данный механизм получил массовое распространение.

Даёт ли virtio какую-то гарантированную прибавку в процентах?

Нет универсального числа — накладные расходы эмуляции сильно зависят от профиля нагрузки (мелкие синхронные операции страдают от эмуляции сильнее, чем крупные последовательные), версии QEMU, ядра хоста и гостя. Единственный надёжный способ узнать разницу именно для вашей нагрузки — сравнить эмулированное и virtio-устройство на одном и том же стенде с fio/iperf3, не полагаясь на чужие цифры из интернета.

Что делать, если в панели создания VM нет отдельного пункта virtio, только общий список типов дисков?

Ищите в списке буквальное слово "VirtIO" или "Paravirtualized" — обычно оно есть, просто не всегда стоит первым в выпадающем списке. Если платформа не предоставляет virtio вовсе (редкость для современных KVM-based панелей), это повод уточнить у провайдера, какой гипервизор используется на самом деле.

Нужно ли что-то менять в самой гостевой ОС после установки, кроме драйвера?

Для Linux — обычно нет, всё определяется автоматически при следующей загрузке. Для Windows после установки драйверов диска и сети стоит дополнительно поставить QEMU Guest Agent (тоже часть пакета virtio-win) — он не про производительность ввода-вывода, но даёт гипервизору корректную информацию о состоянии гостя для снапшотов и graceful shutdown.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →