Отсутствуют данные о PCI-устройствах в nova-compute
При создании виртуальной машины с GPU или при изменении шаблона конфигурации ВМ на шаблон с GPU возникает ошибка вида Нет свободных хостов для размещения.
При этом GPU доступны в операционной системе гипервизора, но в логах сервиса nova-compute в списке pci_stats они не отображаются:
INFO nova.compute.resource_tracker [req-...] Final resource view: name=<ГИПЕРВИЗОР> phys_ram=...MB used_ram=...MB phys_disk=...GB used_disk=100GB total_vcpus=96 used_vcpus=42 pci_stats=[]
Доступность GPU в ОС гипервизора и пустой список pci_stats говорят о том, что Nova не анонсирует GPU как доступные PCI-устройства.
Причин может быть несколько:
- неправильный драйвер для GPU;
- БД
novaсодержит устаревшие данные об аллокациях для PCI-устройств на этом гипервизоре.
Проблема может возникнуть, если гипервизор был некорректно выведен из кластера, а затем добавлен обратно с тем же именем.
-
Проверьте, какие PCI-устройства доступны в операционной системе гипервизора:
$ lspci -nn | grep -i nvidiaПример ожидаемого вывода:
17:00.0 3D controller [0302]: NVIDIA Corporation Device [<КОД_ПРОИЗВОДИТЕЛЯ>:<КОД_УСТРОЙСТВА>] (rev a1)Здесь:
17:00.0— слот, в который подключено PCI-устройство;<КОД_ПРОИЗВОДИТЕЛЯ>— код производителя PCI-устройства, например10de;<КОД_УСТРОЙСТВА>— код PCI-устройства, например20b5.
-
Проверьте текущие настройки загрузки ядра. Для этого на гипервизоре выполните команду:
$ cat /proc/cmdlineПример ожидаемого вывода:
rd.driver.pre=vfio-pci vfio-pci.ids=<КОД_ПРОИЗВОДИТЕЛЯ>:<КОД_УСТРОЙСТВА> rd.driver.blacklist=nouveau nouveau.modeset=0 intel_iommu=on iommu=pt -
Убедитесь, что в выводе есть параметры:
intel_iommu=onилиamd_iommu=onв зависимости от производителя CPU;iommu=pt— режим passthrough для IOMMU;rd.driver.pre=vfio-pci— тип драйвера GPU для QEMU;vfio-pci.ids=<КОД_ПРОИЗВОДИТЕЛЯ>:<КОД_УСТРОЙСТВА>— код производителя и код PCI-устройства;rd.driver.blacklist=nouveau— обязательное отключение модуля ядра для GPU-драйвераnouveau;nouveau.modeset=0— обязательное отключение GPU-драйвераnouveau.
Если параметров нет:
-
Добавьте параметры в переменную
GRUB_CMDLINE_LINUXв файле/etc/default/grub:intel_iommu=on iommu=pt rd.driver.pre=vfio-pci vfio-pci.ids=<КОД_ПРОИЗВОДИТЕЛЯ>:<КОД_УСТРОЙСТВА> rd.driver.blacklist=nouveau nouveau.modeset=0 -
Пересоберите
grub:$ grub2-mkconfig -o /boot/grub2/grub.cfg$ dracut -f -
Перезагрузите гипервизор:
$ reboot
-
Проверьте, что запрещена загрузка драйвера
nouveau. В файле/etc/modprobe.d/blacklist-nouveau.confдолжно быть указано:blacklist nouveauoptions nouveau modeset=0 -
Убедитесь, что в файле
/etc/modprobe.d/vfio.confуказано PCI-устройство, для которого нужно загружать модульvfio-pci:options vfio-pci ids=<КОД_ПРОИЗВОДИТЕЛЯ>:<КОД_УСТРОЙСТВА> -
Проверьте, что модуль
vfio-pciзагружается:$ lsmod | grep vfioПример ожидаемого вывода:
vfio_pci 16384 0vfio_pci_core 73728 1 vfio_pcivfio_virqfd 16384 1 vfio_pci_corevfio_iommu_type1 45056 0vfio 49152 3 vfio_pci_core,vfio_iommu_type1,vfio_pciirqbypass 16384 2 vfio_pci_core,kvm -
Убедитесь, что GPU привязан к модулю
vfio-pci:-
Выполните команду:
lspci -nnk -s 17:00.0Здесь
17:00.0— слот, в который подключено PCI-устройство.Пример ожидаемого вывода:
17:00.0 3D controller [0302]: NVIDIA Corporation GA100 [A100 PCIe 80GB] [10de:20b5] (rev a1)Kernel driver in use: vfio-pciKernel modules: nouveau -
Убедитесь, что в выводе в параметре
Kernel driver in useуказан драйверvfio-pci. -
Проверьте символическую ссылку:
ls -l /sys/bus/pci/devices/0000:17:00.0/driverЗдесь
17:00.0— слот, в который подключено PCI-устройство.Пример ожидаемого вывода:
/sys/bus/pci/devices/0000:17:00.0/driver -> ../../../bus/pci/drivers/vfio-pci -
Убедитесь, что в выводе указан драйвер
vfio-pci. -
Если указан другой драйвер, привяжите GPU к модулю
vfio-pciпринудительно:$ modprobe vfio-pciecho "0000:17:00.0" > /sys/bus/pci/devices/0000:17:00.0/driver/unbindecho vfio-pci > /sys/bus/pci/devices/0000:17:00.0/driver_overrideecho "0000:17:00.0" > /sys/bus/pci/drivers_probeЗдесь
17:00.0— слот, в который подключено PCI-устройство.
-
-
Проверьте, что включен IOMMU (Input-Output Memory Management Unit):
$ dmesg -T | grep -iE 'iommu|dmar|vfio'Пример ожидаемого вывода:
DMAR: IOMMU enablediommu: Default domain type: Passthrough (set via kernel command line)VFIO - User Level meta-driver version: 0.3vfio_pci: add [10de:20b5[ffffffff:ffffffff]] class 0x000000/00000000 -
Проверьте IOMMU-группы:
ls -l /sys/bus/pci/devices/0000:17:00.0/iommu_group/devices/Здесь
17:00.0— слот, в который подключено PCI-устройство. -
Проверьте, что
libvirtвидит GPU:$ virsh nodedev-list | grep 17$ virsh nodedev-dumpxml pci_0000_17_00_0Пример корректного
dumpxml:<driver><name>vfio-pci</name></driver><capability type='pci'><product id='0x20b5'>GA100 [A100 PCIe 80GB]</product><vendor id='0x10de'>NVIDIA Corporation</vendor> -
Проверьте настройки в
nova.conf:$ grep -nE '^\[pci\]|alias|passthrough_whitelist|pci_passthrough_whitelist' /etc/nova/nova.confПример корректной настройки в
nova.conf:[pci]alias = {"vendor_id": "<КОД_ПРОИЗВОДИТЕЛЯ>", "product_id": "<КОД_УСТРОЙСТВА>", "device_type": "type-PF", "name": "<ИМЯ_УСТРОЙСТВА>"}passthrough_whitelist = [{"vendor_id": "<КОД_ПРОИЗВОДИТЕЛЯ>", "product_id": "<КОД_УСТРОЙСТВА>"}] -
Проверьте, появились ли в логах сервиса
nova-computePCI-устройства:$ grep -i pci_stats /var/log/nova/nova-compute.log | tail -20В списке
pci_statsдолжно быть указано описание всех GPU сcount=1. -
Если PCI-устройства не появились в логах сервиса
nova-compute:-
На управляющем узле с ролью MariaDB подключитесь к БД
nova:$ mysql -S /srv/mysql/nova/socket/nova.sock nova -
Получите из таблицы
pci_devicesинформацию о PCI-записях проблемного гипервизора:SELECT id, address, vendor_id, product_id, status, instance_uuid, compute_node_idFROM pci_devicesWHERE compute_node_id IN (SELECT id FROM compute_nodes WHERE hypervisor_hostname = '<ГИПЕРВИЗОР>') AND product_id = '<КОД_УСТРОЙСТВА>';Здесь:
<ГИПЕРВИЗОР>— имя проблемного гипервизора;<КОД_УСТРОЙСТВА>— код PCI-устройства, например20b5.
Пример вывода:
+--------+-------------+-----------+------------+-----------+---------------+-----------------+| id | address | vendor_id | product_id | status | instance_uuid | compute_node_id |+--------+-------------+-----------+------------+-----------+---------------+-----------------+| 143 | 0000:17:00.0| 10de | 20b5 | available | NULL | <ГИПЕРВИЗОР> || 146 | 0000:17:00.0| 10de | 20b5 | allocated | 4a1811c7-8b1f | <ГИПЕРВИЗОР> |+--------+-------------+-----------+------------+-----------+---------------+-----------------+ -
Получите идентификатор актуального (не удаленного) гипервизора:
SELECT id FROM compute_nodes WHERE hypervisor_hostname = '<ГИПЕРВИЗОР>' AND deleted=0;Это поможет определить, какие записи из предыдущего запроса относятся к актуальному гипервизору.
-
Убедитесь, что ВМ, идентификатор которой указан в
instance_uuid, находится на другом гипервизоре. Тогда эта PCI-запись является устаревшей (stale allocation). -
На проблемном гипервизоре остановите сервис
openstack-nova-compute:# systemctl stop openstack-nova-compute -
На управляющем узле с ролью MariaDB сделайте резервную копию всех БД Nova:
$ cd /srv/backup$ bash +x ./backup_xtra_nova.sh -
На управляющем узле с ролью MariaDB подключитесь к БД
nova:$ mysql -S /srv/mysql/nova/socket/nova.sock nova -
Удалите устаревшие PCI-записи:
DELETE FROM pci_devicesWHERE id IN (<ЗАПИСЬ_1>[, <ЗАПИСЬ_2>, ...]);Здесь
<ЗАПИСЬ_1>[, <ЗАПИСЬ_2>, ...]— идентификаторы устаревших PCI-записей. -
На проблемном гипервизоре перезапустите сервис
libvirtd:# systemctl restart libvirtd -
На проблемном гипервизоре запустите сервис
openstack-nova-compute:# systemctl start openstack-nova-compute -
Убедитесь, что в логах сервиса
nova-computeпоявились PCI-устройства:$ grep -i pci_stats /var/log/nova/nova-compute.log | tail -20В списке
pci_statsдолжно быть указано описание всех GPU сcount=1.
-