目录

最近新买的服务器上安装了 ESXi v6.7.0 update 2,想把手上的一块显卡配起来在虚拟机中使用,查了官方资料发现可以使用直通(PassThrough)模式让虚拟机直接使用显卡。配置 ESXi 的过程还是基本顺利的,可是在把显卡分配给 Ubuntu 18.04 虚拟机时却碰到了意想不到的问题。

ESXi 配置显卡直通(PassThorugh)模式

这里主要列出配置的关键点不展开说明。配置的方法过程可以参考这篇文档:

https://blogs.vmware.com/apps/2018/04/how-enable-compute-accelerators-vsphere-6-5-machine-learning-hpc-workloads.html

如果使用 vGPU 的模式进行配置时需要在 ESXi 中安装对应的驱动,如果是NVidia显卡可以从这里下载,不过多数家用级的 GPU 本身不支持这种模式,所以安装之前最好确认一下。

https://www.nvidia.com/drivers/results/116135

另外,服务器的 BIOS 需要进行正确设置,主要是查看 VT-D / IOMMU / SR-IOV 相关的设置

安装虚拟机

安装完 Ubuntu 18.04 后问题就接踵而至。

第一个坑:虚拟机类型

原本按照默认的 ESXi 6.7 类型创建虚拟机但无论后面怎么设置都无法让驱动跟显卡正常工作,这里一定要选择 ESXi 6.7 U2 类型的机器。

VM type U2

第二个坑:内存预留

创建虚拟机时的默认配置不会将虚拟机的内存选项设置成“预留所有客户机内存 (全部锁定)”,但在使用 GPU PassThrough 的情况下需要把这个选项打开才行。

memory reserve

第三个坑:添加参数 hypervisor.cpuid.v0 = “FALSE”

一定要添加这个参数,让驱动把虚拟机当做物理机来处理。

hypervisor-cpuid

第四个坑:Ubuntu 18.04 虚机升级系统后重启黑屏

这个问题折腾了很久才弄明白是由于升级 Intel CPU 的微代码固件(Meltdown安全漏洞)造成的,为了能够使用虚拟机只能放弃这个固件的升级:

$ sudo apt-mark hold intel-microcode

该问题的讨论可以参考这个帖子:https://askubuntu.com/questions/1155634/intel-microcode-package-upgrade-in-ubuntu-18-04-leads-to-unbootable-system

第五个坑:系统自带 nouveau 驱动造成 nvidia 驱动无法加载

在虚拟机中安装 NVidia 驱动后重启系统后,正常情况可以看到系统正常加载 nvidia 驱动。

安装 NVidia 驱动方法:

$ sudo apt install gcc g++ make

$ sudo apt-get install nvidia-driver-410 xserver-xorg-video-nvidia-410 libnvidia-compute-410 libnvidia-decode-410 libnvidia-encode-410 libnvidia-ifr1-410 libnvidia-fbc1-410 libnvidia-gl-410 xorg-video-abi-23

但重启虚拟机后会发现有时系统会正常加载 nvidia.ko 驱动,有时会加载 nouveau.ko 驱动,造成无法正常使用显卡。

驱动加载的确认方法可以用 ‘lsmod | grep nvidia’ 或 ‘lsmod | grep nouveau’ 命令。

可以用下面这个比较暴力的方法禁用 nouveau 驱动:

sudo mv /lib/modules/4.18.0-25-generic/kernel/drivers/gpu/drm/nouveau/nouveau.ko /lib/modules/4.18.0-25-generic/kernel/drivers/gpu/drm/nouveau/nouveau.ko.disabled

这里多说一些禁用 nouveau 驱动过程中碰到的坑:

失败经历1:在 grub 及系统加载模块中禁用 nouveau

使用这个方法我发现在 Ubuntu 18.04 虚机启动后有时会正确加载 nvidia 驱动,有时却依然会加载 nouveau,确认的方法可以用 ‘lsmod | grep nvidia’ 或 ‘lsmod | grep nouveau’ 命令来确认。

在此把这个方法记录下来,也可能对别的虚拟机有效。

第一步:在 grub 中禁止 nouveau

先把下面的配置添加到 /etc/default/grub 文件中

GRUB_CMDLINE_LINUX="nouveau.blacklist=1"

然后更新 grub:

$ sudo update-grub

第二步:禁用 modprobe

创建文件 ‘/etc/modprobe.d/nvidia-graphics-drivers.conf’,在其中添加下面内容:

blacklist nouveau
blacklist lbm-nouveau
alias nouveau off
alias lbm-nouveau off
options nouveau modeset=0

Then update initrd:

$ sudo update-initramfs -u
$ sudo reboot

**失败经历2:在 gdm 中禁用 Wayland **

参考了这个讨论后尝试后问题依然存在 https://askubuntu.com/questions/1031511/cant-disable-nouveau-drivers-in-ubuntu-18-04

查看 gdm 是否使用 wayland 模式的方法:

 $ loginctl
 SESSION     UID  USER     SEAT     TTY             
       2    1000  velix    seat0    tty2            
      c2    1000  velix                                             
      c1     120  gdm      seat0    tty1
The command loginctl show-session <session-n> -p Type show the session type:

$ loginctl show-session c1 -p Type
Type=Wayland

在 gdm 配置文件 /etc/gdm3/custom.conf 中禁用的方法是添加下面一行配置后重启系统:

WaylandEnable=false.

趟过去上面几个坑之后就可以正常的在 Ubuntu 18.04 虚拟机中使用显卡直通模式了。

$ nvidia-smi
Thu Aug  8 17:31:13 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.48                 Driver Version: 410.48                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  Off  | 00000000:03:00.0 Off |                  N/A |
|  0%   50C    P8    18W / 250W |   1001MiB / 11178MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      4913      C   /conda/envs/cudf/bin/python                  191MiB |
|    0     10664      C   /home/jupyter/testing-libgdf                 203MiB |
|    0     10871      C   /conda/envs/cudf/bin/python                  191MiB |
|    0     11730      C   /conda/envs/cudf/bin/python                  203MiB |
|    0     11826      C   /conda/envs/cudf/bin/python                  203MiB |
+-----------------------------------------------------------------------------+