virt-manager удобен для редких запусков, но серверные сценарии — скрипты, шаблоны, автозапуск после перезагрузки — требуют прямой работы с qemu-system-x86_64. Разберём создание дисков, запуск виртуальной машины из командной строки, проброс портов, управление монитором и типичные проблемы ускорения KVM.
Подготовка и проверка ускорения
Без аппаратного ускорения KVM виртуализация идёт в режиме эмуляции и в десятки раз медленнее. Убедитесь, что процессор поддерживает виртуализацию, а ядро загрузило нужный модуль, иначе каждый запуск завершится понятной ошибкой.
# поддержка виртуализации процессором
grep -Ec '(vmx|svm)' /proc/cpuinfo
# устройство KVM и права на него
ls -l /dev/kvm
# версия эмулятора и утилиты образов
qemu-system-x86_64 --version
qemu-img --version
# модуль уже загружен?
lsmod | grep -E 'kvm_(intel|amd)'
Если /dev/kvm отсутствует, проверьте загрузку модуля kvm_intel или kvm_amd и параметры ядра. Пакеты для запуска: qemu-system-x86, qemu-utils и qemu-kvm, на других дистрибутивах имена отличаются.
Диски и образы
Формат qcow2 поддерживает тонкое выделение, снапшоты и диффы, поэтому подходит для большинства задач. raw быстрее на записи, но занимает место сразу и не умеет снапшоты, поэтому его берут под базы с высокой нагрузкой.
# создать образ диска 40 ГБ с динамическим расширением
qemu-img create -f qcow2 /var/lib/vms/web01.qcow2 40G
# фактически занятое место и размер виртуального диска
qemu-img info /var/lib/vms/web01.qcow2
# внутренний снапшот перед опасным изменением
qemu-img snapshot -c pre-upgrade /var/lib/vms/web01.qcow2
# откат к снапшоту и список снимков
qemu-img snapshot -a pre-upgrade /var/lib/vms/web01.qcow2
qemu-img snapshot -l /var/lib/vms/web01.qcow2
Внутренний снапшот хранится в самом образе: откат возвращает диск к состоянию на момент снимка. Для переноса машины на другой хост удобна конвертация: qemu-img convert соберёт цельный файл за считанные минуты.
Запуск машины с установочного образа
Минимальный набор аргументов: память, процессоры, диск, привод и загрузка с CD. Ключ -enable-kvm включает ускорение, а -cpu host передаёт гостю все возможности физического процессора, включая векторные расширения.
qemu-system-x86_64 \
-enable-kvm -cpu host -m 4096 -smp 2 \
-drive file=/var/lib/vms/web01.qcow2,if=virtio,format=qcow2 \
-cdrom /isos/debian-12-netinst.iso \
-boot d -vga virtio
После установки уберите -cdrom и -boot d, иначе машина снова попытается загрузиться с диска. Для серверов без монитора добавляйте -display none -serial stdio: консоль гостя уходит в терминал, а лог загрузки остаётся видимым.
Работа без графики
На сервере графическая подсистема не нужна. Режим -nographic перенаправляет видео и последовательный порт в текущий терминал, выход из гостя выполняется сочетанием Ctrl+A, затем X. Для фонового запуска используйте -daemonize и сокет монитора.
# консоль в терминал, выход: Ctrl+A X
qemu-system-x86_64 -enable-kvm -m 2048 -smp 2 \
-drive file=web01.qcow2,if=virtio -nographic
# запуск в фоне и монитор через unix-сокет
qemu-system-x86_64 -enable-kvm -m 2048 \
-drive file=web01.qcow2,if=virtio -display none -daemonize \
-monitor unix:/run/web01-mon.sock,server,nowait
# отправить команду монитору и прочитать ответ
echo "info status" | socat - UNIX-CONNECT:/run/web01-mon.sock
Монитор понимает savevm для снимка состояния, change для подмены диска на лету и stop для останова гостя. Для автоматизации подключайтесь к тому же сокету в режиме QMP и отправляйте JSON-команды: так управлять машиной сможет ваш скрипт.
Сеть: режим пользователя и проброс портов
По умолчанию QEMU работает в режиме slirp: гость ходит в сеть через пользователя и не виден снаружи. Для веб-сервера достаточно проброса порта, а для доступа по адресу локальной сети понадобится мост.
# проброс внешнего 8080 на порт 80 гостя
-netdev user,id=net0,hostfwd=tcp::8080:-80 \
-device virtio-net-pci,netdev=net0
# проверка с хоста
curl -I http://127.0.0.1:8080
# мост для адреса локальной сети
sudo ip link add br0 type bridge
sudo ip link set br0 up
Мост bridge даёт гостю собственный адрес в локальной сети: трафик идёт напрямую, без преобразования адресов. Создание моста лучше описать в systemd-networkd, чтобы он поднимался после перезагрузки вместе с физическим интерфейсом.
Автозапуск и сохранение состояния
Для постоянных машин заведите скрипт запуска и юнит systemd: так виртуальная машина переживёт перезагрузку сервера и будет перезапускаться после падения процесса.
#!/bin/sh
# /usr/local/sbin/start-web01.sh
exec qemu-system-x86_64 -enable-kvm -cpu host -m 4096 -smp 2 \
-drive file=/var/lib/vms/web01.qcow2,if=virtio \
-netdev user,id=net0,hostfwd=tcp::8080:-80 \
-device virtio-net-pci,netdev=net0 \
-display none -daemonize -pidfile /run/web01.pid
В юните укажите Restart=on-failure и After=network-online.target, а сам скрипт поместите в ExecStart. Перед обновлениями сохраняйте состояние через монитор: loadvm восстановит машину за секунды, если обновление окажется неисправным.
Клонирование и перенос машины
Перенос на другой хост сводится к копированию образа диска и правильной команде запуска. Перед копированием выключайте гостя: снимок работающей файловой системы восстанавливается не всегда. После переноса проверьте, что пути в скрипте запуса указывают на новый каталог, иначе машина стартует с пустым диском.
# конвертация в отдельный файл для переноса
qemu-img convert -f qcow2 -O qcow2 /var/lib/vms/web01.qcow2 /tmp/web01-copy.qcow2
# синхронизация каталога с образами
rsync -aH --progress /var/lib/vms/ /backup/vms/
# проверка структуры образа до запуска
qemu-img check /tmp/web01-copy.qcow2
Утилита qemu-img check находит повреждения структуры qcow2 до того, как с ними столкнётся гость. Для шаблонов удобен другой порядок: создаёте эталон, превращаете его в базовый образ и разворачиваете копии через backing-файл, который никогда не изменяется. Так обновление конфигурации шаблона автоматически попадает во все новые машины.
Диагностика проблем
- Ошибка «Could not access KVM kernel module» — нет прав на /dev/kvm: добавьте пользователя в группу kvm или настройте udev-правило.
- Машина стартует и сразу гаснет — проверьте, что файл из -drive существует и формат указан верно.
- Гость не видит сеть — должны быть оба элемента: netdev и устройство с параметром netdev=net0.
- Слабая производительность — убедитесь, что не запущена вложенная виртуализация и указан -enable-kvm.
- Нет консоли — при -display none используйте -serial stdio или подключайтесь к монитору по сокету.
Итог
QEMU без графической оболочки — полноценный инструмент: qcow2 решает задачи снапшотов, -nographic и сокет монитора дают полный контроль, а hostfwd покрывает типовые сетевые схемы. Начните с образа диска и запуска в фоне, затем добавьте проброс портов и systemd-юнит. Такой подход проще масштабируется, чем ручные действия в интерфейсе.