openstack 配置GPU直通(pci_passthrough)

參考:OpenStack下利用透傳技術(passthrough)對GPU實現虛擬化

參考:centos 7.3下爲虛擬機透傳GPU

bios配置確認

首先要確定主板和CPU都支持虛擬化技術,在BIOS將VT-d、VT-x設置成enable。

以Intel爲例,需要將下面兩項設置爲enable:

VT: Intel Virtualization Technology
VT-d: Intel VT for Directed I/O

操作系統配置

開啓iommu

使用如下命令確認是否支持iommu

cat /proc/cmdline | grep iommu

如果沒有輸出,說明不支持iommu,需要手動開啓。編輯/etc/default/grub,在GRUB_CMDLINE_LINUX中添加intel_iommu=on配置項:

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="intel_iommu=on crashkernel=auto rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

更新grub,並重啓設備:

grub2-mkconfig -o /boot/grub2/grub.cfg
shutdown -r now

重啓以後如下確認是否正常:

#使用下面命令
dmesg | grep -i iommu
#如果輸出類似下面的內容,說明正確
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-3.10.0-862.6.3.el7.x86_64 root=UUID=4e83b2b5-5ff1-4b1b-af0f-3f6a7f8275ea ro intel_iommu=on crashkernel=auto rhgb quiet
[    0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-3.10.0-862.6.3.el7.x86_64 root=UUID=4e83b2b5-5ff1-4b1b-af0f-3f6a7f8275ea ro intel_iommu=on crashkernel=auto rhgb quiet
[    0.000000] DMAR: IOMMU enabled
[    0.257808] DMAR-IR: IOAPIC id 3 under DRHD base  0xfbffc000 IOMMU 0
[    0.257810] DMAR-IR: IOAPIC id 1 under DRHD base  0xd7ffc000 IOMMU 1
[    0.257812] DMAR-IR: IOAPIC id 2 under DRHD base  0xd7ffc000 IOMMU 1

虛擬化支持確認

egrep -c '(vmx|svm)' /proc/cpuinfo

如果輸入非0,則說明支持

配置vfio

檢查當前顯卡設備信息

[root@ostack-228-26 ~]# lspci -nn | grep NVID
06:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1e04] (rev a1)
06:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f7] (rev a1)
06:00.2 USB controller [0c03]: NVIDIA Corporation Device [10de:1ad6] (rev a1)
06:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device [10de:1ad7] (rev a1)
83:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1e04] (rev a1)
83:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f7] (rev a1)
83:00.2 USB controller [0c03]: NVIDIA Corporation Device [10de:1ad6] (rev a1)
83:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device [10de:1ad7] (rev a1)

可以看到,其實我的這臺設備上有兩個個vga設備(就是我們服務器上的2080),這兩個pci設備一共有4個硬件:VGA、Audio、USB、Serial bus

確認驅動

由於我們的物理服務器操作系統,並沒有安裝NVIDIA顯卡驅動,所以我們會發現如下信息。其中USB設備使用了xhci_hcd驅動,這個驅動是服務器自帶的。

lspci -vv -s 06:00.0 | grep driver 
lspci -vv -s 06:00.1 | grep driver 
lspci -vv -s 06:00.2 | grep driver 
	Kernel driver in use: xhci_hcd
lspci -vv -s 06:00.3 | grep driver

如果我們安裝了NVIDIA驅動的話, 可能會獲得如下輸出:

lspci -vv -s 06:00.0 | grep driver 
	Kernel driver in use: nvidia
lspci -vv -s 06:00.1 | grep driver 
	Kernel driver in use: snd_hda_intel
lspci -vv -s 06:00.2 | grep driver 
	Kernel driver in use: xhci_hcd
lspci -vv -s 06:00.3 | grep driver 

配置vfio

因爲我們想要把VGA設備透傳到虛擬機中,首先我們需要將設備從物理機上分離(可能分離的 說法並不準確,暫且這麼認爲),實現的方法是將設備使用的默認驅動禁用,然後將設備加入到vfio模塊,讓設備使用vfio驅動。

在上面,我們已經查到了,理論上 ,由於我們並沒有裝NVIDIA驅動,我們只需要將xhci_hcd禁用即可,但是爲了以防萬一,我們可以將其他nvidia驅動也加到禁止名單。

這裏我們將GPU帶的4個設備的驅動都配置成vfio的一個原因是:默認情況下,統一pci端口的不同設備,會被分配到同一個iommu組,同一組的設備,只能同時被分配到一個虛擬機使用。假設,我們只講VGA設備分離,其他三個不分離的話,會導致創建虛擬機的時候報錯如下錯誤:Please ensure all devices within the iommu_group are bound to their vfio bus driver.。這時候有2中解決辦法:

  • 將同一iommu組的所有設備都直通給同一個虛擬機(本章的方案)
  • 將同一pci端口的不同設備分到不通的iommu組(等待探索)

禁用默認顯卡

爲了保證設備不被宿主機使用,我們建議將上面查到的兩個驅動禁用,編輯/etc/modprobe.d/blacklist.conf,添加如下配置(似乎並不需要此步驟):

blacklist xhci_hcd
blacklist nvidia
blacklist snd_hda_intel
#下面是網上看到的,有可能不需要
blacklist nvidiafb

配置系統加載模塊

配置加載vfio-pci模塊,編輯/etc/modules-load.d/vfio-pci.conf,添加如下內容:

vfio-pci
#下面的內容也是參考網上的配置,有可能不需要
pci_stub
vfio
vfio_iommu_type1
kvm
kvm_intel

配置vfio加載的設備

配置使用vfio驅動的設備(這裏的設備就是上面我們查到的設備的)編輯/etc/modprobe.d/vfio.conf,添加如下配置:

# GTX 2080Ti and its audio controller
options vfio-pci ids=10de:1e04,10de:10f7,10de:1ad6,10de:1ad7

重新生成內核並重啓

重新生成內核文件之前,我們先備份已有的:

mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r)-nouveau.img

重新生成:

dracut /boot/initramfs-$(uname -r).img $(uname -r)

重啓設備:

shutdown -r now

確認

查看啓動信息,確認vfio模塊是否加載

dmesg | grep -i vfio
[    6.755346] VFIO - User Level meta-driver version: 0.3
[    6.803197] vfio_pci: add [10de:1b06[ffff:ffff]] class 0x000000/00000000
[    6.803306] vfio_pci: add [10de:10ef[ffff:ffff]] class 0x000000/00000000

重啓以後,我們查看設備使用的驅動,都顯示vfio說明正確

lspci -vv -s 06:00.0 | grep driver
	Kernel driver in use: vfio-pci
lspci -vv -s 06:00.1 | grep driver
	Kernel driver in use: vfio-pci
lspci -vv -s 06:00.2 | grep driver
	Kernel driver in use: xhci_hcd
lspci -vv -s 06:00.3 | grep driver
	Kernel driver in use: vfio-pci

openstack配置

控制節點配置

主要配置2個塊,filter_scheduler和pci

[filter_scheduler]
available_filters = nova.scheduler.filters.all_filters
#主要在末尾添加:PciPassthroughFilter
enabled_filters = RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,RamFilter,CoreFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,PciPassthroughFilter
[pci]
#alias是能夠直通設備的信息,多個設備多條記錄,我們希望GPU上的4個設備都直通到虛擬機,所以將4個設備信息都寫上
alias = {"name":"nv2080vga","product_id":"1e04","vendor_id":"10de","device_type":"type-PCI"}
alias = {"name":"nv2080aud","product_id":"10f7","vendor_id":"10de","device_type":"type-PCI"}
alias = {"name":"nv2080usb","product_id":"1ad6","vendor_id":"10de","device_type":"type-PCI"}
alias = {"name":"nv2080bus","product_id":"1ad7","vendor_id":"10de","device_type":"type-PCI"}

配置完成以後,重啓nova 相關服務(nova-api和nova-scheduler:

systemctl restart openstack-nova-api.service openstack-nova-scheduler.service

配置計算節點

計算節點,主要配置pci部分

[pci]
#alias可以配置多條,對應多個設備
alias = {"name":"nv2080vga","product_id":"1e04","vendor_id":"10de","device_type":"type-PCI"}
alias = {"name":"nv2080aud","product_id":"10f7","vendor_id":"10de","device_type":"type-PCI"}
alias = {"name":"nv2080usb","product_id":"1ad6","vendor_id":"10de","device_type":"type-PCI"}
alias = {"name":"nv2080bus","product_id":"1ad7","vendor_id":"10de","device_type":"type-PCI"}
#passthrough_whitelist配置該計算節點可用於直通的設備
passthrough_whitelist = [{ "vendor_id": "10de", "product_id": "1e04" },
			             { "vendor_id": "10de", "product_id": "10f7" },
                         { "vendor_id": "10de", "product_id": "1ad6" },
                         { "vendor_id": "10de", "product_id": "1ad7" }]

重啓計算服務:

ystemctl restart openstack-nova-compute

創建帶有顯卡直通信息的flavor

openstack flavor create --public --ram 2048 --disk 20 --vcpus 2 m1.large

openstack flavor set m1.large --property pci_passthrough:alias='nv2080vga:2,nv2080aud:2,nv2080usb:2,nv2080bus:2'
  • pci_passthrough:alias是固定格式,標識用alias方篩選pci設備
  • nv2080vga:2標識2塊名爲 nv2080vga的設備,多個設備英文逗號隔開

    以上步驟可以dashboard上操作

隱藏虛擬機的hypervisor id

因爲NIVIDIA顯卡的驅動會檢測是否跑在虛擬機裏,如果在虛擬機裏驅動就會出錯,所以我們需要對顯卡驅動隱藏hypervisor id。在OpenStack的Pile版本中的Glance 鏡像引入了img_hide_hypervisor_id=true的property,所以可以對鏡像執行如下的命令隱藏hupervisor id:

openstack image set [IMG-UUID] --property img_hide_hypervisor_id=true

通過此鏡像安裝的instance就會隱藏hypervisor id。

可以通過下邊的命令查看hypervisor id是否隱藏:

cpuid | grep hypervisor_id
hypervisor_id = "KVMKVMKVM   "
hypervisor_id = "KVMKVMKVM   "

上邊的顯示結果說明沒有隱藏,下邊的顯示結果說明已經隱藏:

cpuid | grep hypervisor_id
hypervisor_id = "  @  @    "
hypervisor_id = "  @  @    "

創建實例

這時候,我們使用上面的flavor和image來創建虛擬機就可以了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章