OpenStack显卡透传主要分两部分:
1、KVM PassThrough Nvidia1060,并制作透传显卡的OpenStack镜像
2、配置OpenStack环境
折腾大半个月,主要解决的问题:NVIDIA显卡透传,臭名昭著error43问题。
注意:文章中的超链接,需要翻墙才能正常访问
显卡型号:NVIDIA1060 驱动版本:388(2017年)
一、KVM 显卡透传:
注意:建议你有双显卡,一个显卡会透传给虚拟机使用,另外一个显卡你物理机使用。
本文的KVM显卡透传主要是基于点击打开链接此篇文档:相比原文档的启动脚本,为了便于调试,去掉了-vga none \
-nographic \
#!/bin/bash
vmname="windows10vm"
if ps -A | grep -q $vmname; then
echo "$vmname is already running." &
exit 1
else
# use pulseaudio
export QEMU_AUDIO_DRV=pa
export QEMU_PA_SAMPLES=8192
export QEMU_AUDIO_TIMER_PERIOD=99
export QEMU_PA_SERVER=/run/user/1000/pulse/native
cp /usr/share/OVMF/OVMF_VARS.fd /tmp/my_vars.fd
qemu-system-x86_64 \
-name $vmname,process=$vmname \
-machine type=q35,accel=kvm \
-cpu host,kvm=off \
-smp 4,sockets=1,cores=2,threads=2 \
-m 8G \
-mem-path /run/hugepages/kvm \
-mem-prealloc \
-balloon none \
-rtc clock=host,base=localtime \
-serial none \
-parallel none \
-soundhw hda \
-usb -usbdevice host:045e:076c -usbdevice host:045e:0750 \
-device vfio-pci,host=02:00.0,multifunction=on \
-device vfio-pci,host=02:00.1 \
-drive if=pflash,format=raw,readonly,file=/usr/share/OVMF/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=/tmp/my_vars.fd \
-boot order=dc \
-drive id=disk0,if=virtio,cache=none,format=raw,file=/media/user/win.img \
-drive file=/home/user/ISOs/win10.iso,index=1,media=cdrom \
-drive file=/home/user/Downloads/virtio-win-0.1.140.iso,index=2,media=cdrom \
-netdev type=tap,id=net0,ifname=vmtap0,vhost=on \
-device virtio-net-pci,netdev=net0,mac=00:16:3e:00:01:01
exit 0
fi
上面的脚本:强调一下,作者主机上有两个显示器、两个键盘、两个鼠标,因此我不但将显卡透传给虚拟机了,并且还将其中一个鼠标、键盘透传给虚拟机,因此脚本中的鼠标和键盘如下,如果你没有则可以去掉
-usb -usbdevice host:045e:076c -usbdevice host:045e:0750
前置条件:
(1)确认显卡支持透传,检查你gpu rom的完整性,点击打开链接参考此点击打开链接(此网址是git上的一个检查gpu rom完整性的小程序)。如果gpu rom完整,则运行后如下
# ./rom-parser evga_gtx970.dump
Valid ROM signature found @0h, PCIR offset 1a0h
PCIR: type 0 (x86 PC-AT), vendor: 10de, device: 13c2, class: 030000
PCIR: revision 0, vendor revision: 1
Valid ROM signature found @f400h, PCIR offset 1ch
PCIR: type 3 (EFI), vendor: 10de, device: 13c2, class: 030000
PCIR: revision 3, vendor revision: 0
EFI: Signature Valid, Subsystem: Boot, Machine: X64
Last image
(2)出现error43,参考点击打开链接中这部分内容Error 43: Driver failed to load" on Nvidia GPUs passed to Windows VMs
(3)透传的安装镜像最好选择Windows10,Windows10对uefi启动支持比较好。
(4)编辑/etc/default/grub 不确定是否有效,不过建议加上
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on video=vesafb:off,efifb:off"
(5)若出现
vfio-pci 0000:09:00.0: BAR 3: cannot reserve [mem 0xf0000000-0xf1ffffff 64bit pref]
则需要,0000:00:03.1是你显卡的PciId
# echo 1 > /sys/bus/pci/devices/0000\:00\:03.1/remove
# echo 1 > /sys/bus/pci/rescan
二、配置OpenStack主要参考文档点击打开链接
(1)将标题一中用KVM制作的windows10.raw镜像文件转换为qcow2格式,上传至OpenStack(事实上,后续经过验证发现,制作的OpenStack win10镜像只需支持uefi启动即可,也就意味着你在用virt-manager制作镜像时,启动方式采用uefi方式,当然你需要安装ovmf);
1.如果你的计算节点仅仅只有一张显卡,并且你计算节点使用的操作系统为桌面版本的Ubuntu,此时你需要在控制台配置透传,并关闭桌面服务,以免显卡被占用,卡住。
(2)配置透传(物理机最好不要安装显卡驱动)
1、在BIOS中enable VT-x, VT-d, Onboard VGA. Onboard VGA 的enable可以避免一些错误的出现,具体参考Not only for miners GPU integration in Nova environment。
2、编辑文件 /etc/default/grub
intel芯片:GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on"
amd芯片:GRUB_CMDLINE_LINUX_DEFAULT="iommu=pt iommu=1"
3、编辑文件 /etc/modules,开机自启动相关模块
pci_stub
vfio
vfio_iommu_type1
vfio_pci
kvm
kvm_intel
4、将下列模块加入黑名单blacklist,以避免显卡被占用,编辑文件/etc/modprobe.d/blacklist.conf
blacklist snd_hda_intel
blacklist amd76x_edac
blacklist vga16fb
blacklist nouveau
blacklist rivafb
blacklist nvidiafb
blacklist rivatv
5、如果你的ubuntu系统是ubuntu桌面版本,则需要停止桌面服务,进入命令行界面执行(如果你仅仅只有一张显卡),以免显卡被占用
快捷键 Ctrl+Alt+F1 //从图形界面切换到控制台
sudo service lightdm stop
6.查看显卡id
sudo lspci -nn | grep NVIDIA
7.如果已经安装显卡驱动,则解绑(物理机没安装驱动,则跳过)
echo 0000:01:00.0 > /sys/bus/pci/devices/0000\:01\:00.0/driver/unbind
echo 0000:01:00.1 > /sys/bus/pci/devices/0000\:01\:00.1/driver/unbind
8.
挂载VFIO驱动
echo 10de 1c03 > /sys/bus/pci/drivers/vfio-pci/new_id
echo 10de 10f1 > /sys/bus/pci/drivers/vfio-pci/new_id
9、检查VIFO驱动是否挂载成功
lspci -nnk -d 10de:1c03
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1c03] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:3609]
Kernel driver in use: vfio-pci
lspci -nnk -d 10de:10f1
01:00.1 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:10f1] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:3609]
Kernel driver in use: vfio-pci
(3)配置OpenStack
1. 配置nova-scheduler (controller节点),编辑文件 /etc/nova/nova.conf
[DEFAULT]
scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler
scheduler_available_filters=nova.scheduler.filters.all_filters
scheduler_available_filters=nova.scheduler.filters.pci_passthrough_filter.PciPassthroughFilter
scheduler_default_filters=RamFilter,ComputeFilter,AvailabilityZoneFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,PciPassthroughFilter
2、重启nova-scheduler 服务
sudo service nova-scheduler restart
3、配置nova-api (controller节点),编辑文件 /etc/nova/nova.conf:
[PCI]
alias = { "name": "nvidia1060", "product_id": "1c03", "vendor_id": "10de", "device_type": "type-PCI" }
4、重启nova-api服务
sudo service nova-api restart
5. 配置nova-compute(compute 节点),编辑文件/etc/nova/nova.conf:
[PCI]
passthrough_whitelist = { "vendor_id": "10de", "product_id": "1b06" }
alias = { "name": "nvidia1060", "product_id": "1c03", "vendor_id": "10de", "device_type": "type-PCI"}
6. 重启nova-compute服务
sudo service nova-compute restart
7. 安装ovmf,支持windows uefi启动(compute 节点)
sudo apt-get install ovmf
8.创建及设置flavor,将显卡透传给虚拟机:
openstack flavor set m1.large --property "pci_passthrough:alias"="nvidia1060:1"
9.上传的OpenStack镜像(支持GPU透传),属性配置如下
注意:上传的镜像一定是uefi启动的镜像(通常Windows10镜像(uefi启动))
. admin-openrc
openstack image list
+--------------------------------------+----------------+--------+
| ID | Name | Status |
+--------------------------------------+----------------+--------+
| e9b84d5c-941e-41d5-b847-4cb62d9679d8 | cirros | active |
| 5dbfbc57-b76b-409f-bb16-02c5fa72d34b | cirros2 | active |
| f5d8b581-96d5-4249-ba88-0e4cc22e98c3 | testgpu | active |
| a6b10c13-40d4-443c-b8ee-5c60f62ffa9d | win10_uefi_80g | active |
+--------------------------------------+----------------+--------+
openstack image set UUID --property os_type=windows
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property os_type=windows
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property hw_cpu_cores=4
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property hw_cpu_threads=2
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property hw_cpu_sockets=4
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property hw_firmware_type=uefi
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property hw_machine_type=q35
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property img_hide_hypervisor_id=true
openstack image set a6b10c13-40d4-443c-b8ee-5c60f62ffa9d --property os_secure_boot=required
(3)完成后,仍然可能出现error43,此时需要,更改OpenStack 计算节点的源代码,
cd /etc/libvirt/qemu
vim instance.xml
查看虚拟机启动配置文件,若出现
<features>
<acpi/>
<apic/>
<hyperv>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
</hyperv>
<kvm>
<hidden state='on'/>
</kvm>
</features>
则正常,但实际上,由于NVIDIA显卡后期的显卡驱动拒绝在虚拟机运行,此时,你需要在更改OpenStack的源代码,保证生成的虚拟机启动xml中存在,以使显卡驱动正常使用
<vendor_id state='on' value='1234567890ab'/>
<features>
<acpi/>
<apic/>
<hyperv>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
<vendor_id state='on' value='1234567890ab'/>
</hyperv>
<kvm>
<hidden state='on'/>
</kvm>
</features>
因此在nova/virt/libvirt/config.py文件的2076行
原:
def format_dom(self):
root = super(LibvirtConfigGuestFeatureHyperV, self).format_dom()
if self.relaxed:
root.append(etree.Element("relaxed", state="on"))
if self.vapic:
root.append(etree.Element("vapic", state="on"))
if self.spinlocks:
root.append(etree.Element("spinlocks", state="on",
retries=str(self.spinlock_retries)))
return root
现为
def format_dom(self):
root = super(LibvirtConfigGuestFeatureHyperV, self).format_dom()
if self.relaxed:
root.append(etree.Element("relaxed", state="on"))
if self.vapic:
root.append(etree.Element("vapic", state="on"))
if self.spinlocks:
root.append(etree.Element("spinlocks", state="on",
retries=str(self.spinlock_retries)))
root.append(etree.Element("vendor_id", state="on",
value="1234567890ab"))
return root
并重新将config.py文件重新编译,并替换原有的config.pyc文件
python -m py_compile config.py
重新启动虚拟机,此时显卡应该能正常使用
总结:
在我的上一篇文章
Ubuntu14.04+OpenStackMitaka版本+PCIpassthrough(透传)的GPU直通之路
配置完成后,还是会出现error43错误
不过,有些问题仍然具有参考价值,当你 执行
echo 10de 10f1 > /sys/bus/pci/drivers/vfio-pci/new_id 卡住,建议安装显卡对应的驱动。