OpenStack Pike版本+KVM+Passthrough+NVIDIA显卡1060透传

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 卡住,建议安装显卡对应的驱动。

pci_stub vfio vfio_iommu_type1 vfio_pci kvm kvm_intel
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页