Skip to content

Virtualization on Debian

andyceo edited this page Aug 4, 2026 · 1 revision

Virtualization on Debian

Подготовка хост-системы

Настройка BIOS и ядра

Выполнить (для Intel): sudo dmesg | grep -e DMAR -e IOMMU

Вы должны увидеть строки вроде DMAR: IOMMU performance counters supported.

Выполнить (для AMD): dmesg | grep -e AMD-Vi -e IOMMU

Должно быть что-то вроде AMD-Vi: IOMMU performance counters supported.

Если ничего нет: Зайдите в BIOS/UEFI вашего компьютера и включите опции VT-d (для Intel) или IOMMU / SVM Mode (для AMD).

После этого, нужно добавить в параметры запуска ядра в GRUB следующие параметры:

  • для Intel: intel_iommu=on iommu=pt
  • для AMD: amd_iommu=on iommu=pt

Параметр iommu=pt включает режим "passthrough", что немного ускоряет работу.

Пример итоговой строки для Intel: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt". Таким образом:

  • sudo nano /etc/default/grub: открыть настройки GRUB
  • поправить параметры запуска ядра
  • сохранить изменения
  • sudo update-grub: обновить GRUB
  • sudo reboot: перезагрузка

Установка необходимых для проброса PCI-устройств модулей ядра

Декларирование, какие модули ядра следует загрузить для виртуализации, и их настройка осуществляется путем подкладывания файлов в две разных директории:

Характеристика /etc/modules-load.d /etc/modprobe.d
Основная функция Что загрузить Как загрузить
Кто обрабатывает systemd-modules-load.service modprobe (kmod)
Формат файлов Список модулей Директивы (options, blacklist, alias)
Применение Ранний этап загрузки Любое время при вызове modprobe

Для проброса PCI-устройств в виртуальную машину, понадобятся следующие модули:

vfio
vfio-pci
vfio_iommu_type1

Еще иногда советуют добавить модуль vfio_virqfd, но он больше не существует как отдельный модуль в ядре Linux версии 6.2 и новее. Его функциональность была объединена напрямую в корневой модуль vfio, и больше не нужно явно загружать или ссылаться на него.

Поэтому, создайте и сохраните файл с перечисленными выше модулями: sudo nano /etc/modules-load.d/vfio.conf

Поиск и идентификация PCI-устройств для проброса

Теперь, нужно указать, какие устройства нужно пробросить в виртуальные машины (и соответственно будут изолированы на хост-системе)

Найдем интересующие нас видеокарты: lspci -nn | grep -E 'VGA|3D|Display' или lspci -nn | grep -i nvidia. Получим примерно следующее:

01:00.0 VGA compatible controller [...]: NVIDIA Corporation [...] [10de:2504] (rev a1)
01:00.1 Audio device [...]: NVIDIA Corporation [...] [10de:228e] (rev a1)

Также можно использовать подробный древовидный вывод: lspci -tvnn, для лучшего ориентирования среди устройств

Найдем соответствующую устройству IOMMU-группу:

find /sys/kernel/iommu_groups/ -type l | grep 0e:00.0

Получим:

/sys/kernel/iommu_groups/32/devices/0000:0e:00.0

Посмотрим какие еще устройства есть в этой группе:

ls -l /sys/kernel/iommu_groups/32/devices/

Получим:

lrwxrwxrwx 1 root root 0 авг  4 22:05 0000:08:06.0 -> ../../../../devices/pci0000:00/0000:00:1c.2/0000:07:00.0/0000:08:06.0
lrwxrwxrwx 1 root root 0 авг  4 22:05 0000:0e:00.0 -> ../../../../devices/pci0000:00/0000:00:1c.2/0000:07:00.0/0000:08:06.0/0000:01:00.0
lrwxrwxrwx 1 root root 0 авг  4 22:05 0000:0e:00.1 -> ../../../../devices/pci0000:00/0000:00:1c.2/0000:07:00.0/0000:08:06.0/0000:01:00.1

Часто в группе с видеокартой находится её звуковое устройство (HDMI Audio). Его тоже нужно будет пробросить, иначе в виртуалке не будет звука. Если там есть что-то лишнее (например, USB контроллер, который нужен хосту), проброс может быть невозможен без дополнительных трюков.

Допустим, мы обнаружили, что видеокарта представлена двумя устройствами, как показано выше: собственно VGA контроллер с идентификатором [10de:2504] и HDMI Audio с идентификатором [10de:228e]. Теперь припишем эти два устройства к драйверу vfio, тем самым запретив их использование на хост-системе, и одновременно открыв возможность использовать их в виртуальных машинах:

  • sudo nano /etc/modprobe.d/vfio.conf: откроем файл настройки для модуля ядра vfio
  • перечислим там идентификаторы устройств, которые мы хотим пробрасывать в виртуальные машины: options vfio-pci ids=10de:2504,10de:228e
  • сохранить файл
  • sudo reboot: перезагрузиться

После загрузки проверьте командой lspci -vnn | grep -A 12 -i "nvidia", что вместо драйвера nvidia или amdgpu у пробрасываемой карты стоит vfio-pci. Также можно использовать команду lspci -nnk -s 01:00.0:

Kernel driver in use: vfio-pci

Установка kvm-виртуализации

  1. Обновление системы:

     sudo apt update && sudo apt upgrade
    
  2. Установка необходимых пакетов:

     sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager virtinst virtiofsd
    

Почему так много пакетов? - qemu-kvm — основной гипервизор KVM - libvirt-daemon-system — демон для управления ВМ - libvirt-clients — командные утилиты (virsh) - bridge-utils — настройка сетевых мостов - virt-manager — графический интерфейс для управления - virtiofsd — для проброса файловых систем в виртуальную машину (если это не планируется, можно не ставить)

Можно просто: sudo apt install virt-manager - установит практически те же пакеты

Основное тут - это библиотека libvirt, которая управляет виртуальными машинами.

  1. Добавим пользователя в группы kvm. libvirt:

     sudo adduser <your_user> kvm
     sudo adduser <your_user> libvirt
    

Посмотреть группы текущего пользователя можно командой: groups

  1. Перезагрузить компьютер или перезайти в систему, чтобы права применились. Перезагрузка обязательна, чтобы изменения вступили в силу.

  2. Проверка:

     # Проверка загрузки модулей KVM
     lsmod | grep kvm
    
     # Проверка статуса службы libvirt
     sudo systemctl status libvirtd
    
     # Проверка поддержки виртуализации процессором, если ответ больше нуля, поддержка есть
     egrep -c '(vmx|svm)' /proc/cpuinfo
    

Настройка конкретной виртуальной машины

  1. Создать виртуальную машину (через графический интерфейс virt-manager или через virsh)

    • Нажмите "Create a new virtual machine"
    • Выберите "Local install media (ISO file or CDROM)"
    • Укажите путь к ISO-образу ОС
    • Настройте память (рекомендуется 2-4 GB) и процессоры (1-2 ядра)
    • Для процессора режим host-passthrough пробрасывает реальный процессор в виртуальную машину
    • Для памяти, очень полезна настройка "Включить разделяемую память": в основном используется для virtiofs, но также позволяет задействовать механизмы Kernel Samepage Merging (KSM) и IVSHMEM.
    • Создайте виртуальный диск (минимум 20 GB)
    • Запустите установку
  2. После создания (а можно и во время создания) вирутальной машины, добавить пробрасываемые устройства в оборудование виртуальной машины:

    • Откройте Менеджер виртуальных машин (virt-manager).
    • Выключите целевую виртуальную машину
    • Откройте настройки ВМ (иконка лампочки) и нажмите Добавить оборудование (Add Hardware)
    • Выберите PCI-устройство узла (PCI Host Device)
    • Найдите в списке ID вашего устройства (из шага 2) и нажмите Готово (Finish)
    • повторить для каждого устройства
  3. Установить Debian (или другую операционную систему) в виртуальную машину. После выполнения установки:

    • обновить пакеты: sudo apt update && sudo apt upgrade
    • поставить нужный софт: sudo apt install htop mc curl git
    • перезагрузить
  4. Автозапуск при старте системы

Это простая галочка в Настройках в разделе Параметры загрузки: "Запускать виртуальную машину при включении компьютера"

  1. Добавить репозиторий Nvidia для Debian 12, т.к. только он содержит 580 ветку драйверов:

    • добавить ключ: curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/3bf863cc.pub | sudo tee /etc/apt/keyrings/nvidia-3bf863cc.pub > /dev/null

    • добавить сам репозиторий: cat /etc/apt/sources.list.d/nvidia.sources:

      Architectures: amd64
      Types: deb
      Suites: /
      URIs: https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64
      Signed-By: /etc/apt/keyrings/nvidia-3bf863cc.pub
      
    • настроим sequoia принимать sha1 (иначе дебиан не хочет проверять подпись):

      sudo mkdir -p /etc/crypto-policies/back-ends
      sudo cp /usr/share/apt/default-sequoia.config /etc/crypto-policies/back-ends/apt-sequoia.config
      
    • поправить файл sudo nano /etc/crypto-policies/back-ends/apt-sequoia.config:

      [hash_algorithms]
      sha1.second_preimage_resistance = 2030-01-01    # Extend the expiry for legacy repositories
      sha224 = 2026-02-01
      
    • обновить пакеты: sudo apt update && sudo apt upgrade

    • установить пакет, который ограничивает устанавливаемые драйверы к версии 580: sudo apt install nvidia-driver-pinning-580

    • установить заголовки ядра, инструменты сборки и dkms: sudo apt install linux-headers-$(uname -r) build-essential dkms

    • установить драйвера: sudo apt install cuda-drivers

    • установить CUDA Toolkit версии 12.9 (чтобы поддерживалась архитектура Pascal): sudo apt install cuda-toolkit-12-9 (занимает 9Гб!)

  2. Патчинг CUDA для работы под Debian 13 с новым компилятором

Основная информация здесь: https://github.com/ggml-org/llama.cpp/blob/master/docs/build.md#fixing-compatibility-issues-with-old-cuda-and-new-glibc

Суть: чтобы можно было компилировать CUDA 12.9 новым gcc-компилятором, который поставляется с Debian 13, нужно пропатчить CUDA. Патч для версии 12.9 (сохранить его в файл /tmp/cuda.patch:

--- math_functions.h.bak	2025-05-27 13:17:25.000000000 +0300
+++ math_functions.h	2026-08-04 18:43:54.136214458 +0300
@@ -594,7 +594,7 @@
  *
  * \note_accuracy_double
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 rsqrt(double x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 rsqrt(double x) noexcept (true);
 
 /**
  * \ingroup CUDA_MATH_SINGLE
@@ -618,7 +618,7 @@
  *
  * \note_accuracy_single
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  rsqrtf(float x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  rsqrtf(float x) noexcept (true);
 
 #if defined(__QNX__) && !defined(_LIBCPP_VERSION)
 namespace std {
@@ -2553,7 +2553,7 @@
  *
  * \note_accuracy_double
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 sinpi(double x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 sinpi(double x) noexcept (true);
 /**
  * \ingroup CUDA_MATH_SINGLE
  * \brief Calculate the sine of the input argument 
@@ -2576,7 +2576,7 @@
  *
  * \note_accuracy_single
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  sinpif(float x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  sinpif(float x) noexcept (true);
 /**
  * \ingroup CUDA_MATH_DOUBLE
  * \brief Calculate the cosine of the input argument 
@@ -2598,7 +2598,7 @@
  *
  * \note_accuracy_double
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 cospi(double x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 cospi(double x) noexcept (true);
 /**
  * \ingroup CUDA_MATH_SINGLE
  * \brief Calculate the cosine of the input argument 
@@ -2620,7 +2620,7 @@
  *
  * \note_accuracy_single
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  cospif(float x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  cospif(float x) noexcept (true);
 /**
  * \ingroup CUDA_MATH_DOUBLE
  * \brief  Calculate the sine and cosine of the first input argument 
@@ -5983,13 +5983,13 @@
 
 #endif /* _WIN32 */
 
-__func__(double rsqrt(double a));
+__func__(double rsqrt(double a)) noexcept(true);
 
 __func__(double rcbrt(double a));
 
-__func__(double sinpi(double a));
+__func__(double sinpi(double a)) noexcept(true);
 
-__func__(double cospi(double a));
+__func__(double cospi(double a)) noexcept(true);
 
 __func__(void sincospi(double a, double *sptr, double *cptr));
 
@@ -6003,13 +6003,13 @@
 
 __func__(double erfcx(double a));
 
-__func__(float rsqrtf(float a));
+__func__(float rsqrtf(float a)) noexcept(true);
 
 __func__(float rcbrtf(float a));
 
-__func__(float sinpif(float a));
+__func__(float sinpif(float a)) noexcept(true);
 
-__func__(float cospif(float a));
+__func__(float cospif(float a)) noexcept(true);
 
 __func__(void sincospif(float a, float *sptr, float *cptr));

Затем, применить его:

cd /usr/local/cuda/targets/x86_64-linux/include/crt/
patch -p0 math_functions.h < /tmp/cuda.patch

Для справки: патч создан следующей командой:

diff -u original_file.txt patched_file.txt > diff.patch
  1. Настройка общих с хостом папок

На хосте должен быть установлен пакет virtiofsd (см. выше). Затем в GUI:

  • Выключите гостевую виртуальную машину полностью
  • Нажмите "Добавить аппаратное обеспечение" внизу левой панели
  • Выберите Filesystem из списка аппаратных средств
  • Измените тип драйвера на virtiofs
  • Укажите путь Source в директорию на вашем хост-машине (например, /home/user/shared)
  • Укажите путь Target в простой строковый метку монтирования (например, hostshare). Не используйте здесь абсолютный гостевой путь; это просто идентификатор-тег
  • Нажмите Finish

Затем, после добавления в файловой системы в оборудование виртуальной машины, включим ее. Внутри виртуальной машины выполнить:

sudo mkdir -p /mnt/shared  # если папка отсутствует внутри виртуальной машиины
sudo mount -t virtiofs hostshare /mnt/shared

Можно добавить в fstab, чтобы сделать это постоянным:

hostshare /mnt/shared virtiofs defaults 0 0

Управление виртуальной машиной

# Список всех ВМ
virsh list --all

# Запуск ВМ
virsh start <имя_вм>

# Остановка ВМ
virsh shutdown <имя_вм>

# Принудительное выключение
virsh destroy <имя_вм>

# Перезагрузка ВМ
virsh reboot <имя_вм>

# Подключение к консоли ВМ
virsh console <имя_вм>

Работа с дисками

  • конвертировать qcow2 -> raw

    qemu-img convert -f qcow2 -O raw input_image.qcow2 output_image.raw
    
  • увеличение размера диска на хосте (виртуальная машина должны быть выключена):

    qemu-img resize /путь/к/образу/disk.qcow2 +20G
    
  • расширение диска в гостевой ОС

    sudo apt install cloud-guest-utils
    sudo growpart /dev/vda 1
    sudo resize2fs /dev/vda1
    

Настройка сети (опционально)

По умолчанию используется NAT-сеть. Для мостовой сети:

# Проверка сетевого интерфейса
ip a

# Редактирование конфигурации сети
sudo nano /etc/network/interfaces

Добавьте конфигурацию моста (замените enp0s3 на ваш интерфейс):

auto br0
iface br0 inet dhcp
    bridge_ports enp0s3
    bridge_stp off
    bridge_waitport 0
    bridge_fd 0

Ссылки

Sidebar is under construction

Clone this wiki locally