HOOOS

N100核显SR-IOV虚拟化:PVE 8.x下Jellyfin与Plex开启QSV硬解保姆级教程

0 15 极客折腾笔记 PVE 8Intel N100SR-IOV
Apple

在 PVE 8.x 下,Intel N100 凭借其极低的功耗和出色的 QSV 解码能力,成为了家用 NAS/All-in-One 路由器的明星 CPU。传统的核显直通(Passthrough)只能将核显分给单一虚拟机,而通过 SR-IOV(Single Root I/O Virtualization) 技术,我们可以将 N100 的核显(UHD Graphics)虚拟出最多 7 个独立通道(VF),同时分给多个虚拟机(VM)或 LXC 容器。

本文将演示如何在 PVE 8.x 宿主机下开启 SR-IOV,并将其分配给 LXC 容器(Jellyfin/Plex 常用载体)或 Docker 虚拟机,最终完美开启 Intel Quick Sync Video(QSV)硬件解码。


准备工作

  • PVE 版本:Proxmox VE 8.x (内核版本 6.2/6.5/6.8 均适用)
  • 硬件:Intel N100 (Alder Lake-N) 宿主机
  • 网络:宿主机能够正常连接互联网(需要拉取 GitHub 仓库和编译依赖)

第一步:PVE 宿主机编译与安装 i915-sriov-dkms 驱动

由于 Intel 官方尚未将 Alder Lake-N 的 SR-IOV 驱动完全合入 Linux 主线内核,我们需要使用社区维护的 i915-sriov-dkms 驱动。

1. 安装 PVE 内核头文件和编译依赖

在 PVE 网页端打开 Shell,或者通过 SSH 连接,执行以下命令:

apt update
# 安装当前内核对应的头文件和编译工具
apt install -y pve-headers-$(uname -r) dkms git build-essential sysfsutils

2. 克隆并安装 DKMS 驱动

目前较稳定的项目是 strongtz/i915-sriov-dkms。我们将其克隆到本地并进行编译安装:

cd /usr/src
git clone https://github.com/strongtz/i915-sriov-dkms.git i915-sriov-2.14
# 进入目录,如果是更高版本的内核(如 6.5/6.8),建议拉取项目最新的分支,或手动确认代码兼容性
cd i915-sriov-2.14

# 注册并编译 DKMS 模块
dkms add .
dkms install -m i915-sriov -v 2.14

注:如果执行 dkms install 成功,说明驱动已成功注入当前内核。若报错,请检查 pve-headers 是否与当前运行的内核版本严格一致。

3. 配置内核参数(Grub / Systemd-boot)

我们需要开启 IOMMU 并允许驱动加载 GuC/HuC 固件(N100 硬解关键)。

编辑 Grub 配置文件(若系统使用 grub 引导):

nano /etc/default/grub

找到 GRUB_CMDLINE_LINUX_DEFAULT 这一行,修改为:

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt i915.enable_guc=3 i915.max_vfs=7"

注:i915.max_vfs=7 表示启用最大 7 个虚拟核显。

更新 Grub:

update-grub

(如果 PVE 使用的是 systemd-boot,需要编辑 /etc/kernel/cmdline,在末尾添加上述参数,然后执行 proxmox-boot-tool refresh)

4. 强制启用虚拟功能 (VFs)

创建 udev 规则或使用 sysfsutils 在系统启动时自动创建虚拟显卡。这里推荐使用 sysfs

编辑 /etc/sysfs.conf

nano /etc/sysfs.conf

在文件末尾追加以下内容(假设主核显在 PCI 域 0000:00:02.0,可用 lspci | grep VGA 确认):

devices/pci0000:00/0000:00:02.0/sriov_numvfs = 7

配置完成后,重启 PVE 宿主机

reboot

5. 验证 SR-IOV 是否开启成功

重启后,登录 PVE 运行:

lspci | grep VGA

如果输出中除了 00:02.0 VGA compatible controller 主卡外,还多了 7 个 00:02.100:02.7VGA compatible controller(或 Mobile Instrument),说明 SR-IOV 虚拟成功。

通过 ls /dev/dri 查看设备节点:

ls -la /dev/dri

应该能看到 card0card7 以及 renderD128renderD135。其中 renderD128 通常是主显卡,renderD129 ~ renderD135 是虚拟出来的 VF 显卡。


第二步:将核显 VF 分配给容器或虚拟机

这里推荐两种最主流的方案:LXC 容器(轻量、高效)KVM 虚拟机(如运行 OpenMediaVault/Unraid/Ubuntu Docker)

方案 A:分配给 LXC 容器(推荐 Jellyfin 用户)

LXC 容器直接共享宿主机内核,不需要在容器内安装复杂的显卡驱动,只需做设备挂载。

假设我们要分配 renderD129(即第一个虚拟 VF)给 ID 为 101 的 LXC 容器。

  1. 在 PVE 宿主机上,查看 renderD129 和对应 card1 的组 ID(GID):

    ls -l /dev/dri
    

    输出可能类似于:

    crw-rw---- 1 root video  226,   1 Oct 24 10:00 card1
    crw-rw---- 1 root render 226, 129 Oct 24 10:00 renderD129
    

    请记录主设备号和次设备号:card1226, 1renderD129226, 129

  2. 编辑 LXC 容器配置文件(/etc/pve/lxc/101.conf):

    nano /etc/pve/lxc/101.conf
    

    在文件末尾添加以下配置,允许容器访问该显卡节点:

    # 允许容器挂载对应的字符设备
    lxc.cgroup2.devices.allow: c 226:1 rwm
    lxc.cgroup2.devices.allow: c 226:129 rwm
    
    # 将设备节点 bind mount 进容器内
    lxc.mount.entry: /dev/dri/card1 dev/dri/card1 none bind,optional,create=file
    lxc.mount.entry: /dev/dri/renderD129 dev/dri/renderD129 none bind,optional,create=file
    

    保存并关闭。

方案 B:分配给 KVM 虚拟机(虚拟机内跑 Docker)

如果你在 PVE 内开了一台 Linux VM(如 Debian/Ubuntu),并想在 VM 里的 Docker 容器运行 Jellyfin/Plex:

  1. 进入 PVE 网页控制台,选择你的虚拟机 -> 硬件(Hardware) -> 添加(Add) -> PCI 设备(PCI Device)
  2. 在设备列表里,选择其中一个虚拟出来的核显(例如 0000:00:02.1)。
  3. 勾选 All Functions,并将 Primary GPU 保持不勾选(避免抢占虚拟终端显示)。
  4. 保存,并启动虚拟机。虚拟机将把这个 VF 当作一个物理 PCIe 显卡直接读取。

第三步:容器/系统内权限与依赖环境配置

分配完显卡后,我们需要确保容器内的 Jellyfin 或 Plex 能够拥有读写显卡节点的权限。

1. 解决 LXC 容器内的权限问题

进入 LXC 容器(例如通过 PVE 网页端的 101 容器控制台):

检查 /dev/dri 目录:

ls -la /dev/dri

你应该能看到 card1renderD129。但是,容器内运行 Jellyfin 的用户(通常是 jellyfin,UID/GID 一般是 109110)必须有权访问 render 组。

在容器内将 jellyfin 用户加入到 rendervideo 组:

usermod -aG video,render jellyfin

如果不确定,可以直接在容器内给显卡赋予 666 权限(临时排查或家用方便方案):

chmod 666 /dev/dri/card1 /dev/dri/renderD129

(注意:每次容器重启后权限可能会重置,可以通过在容器的 /etc/rc.local 中加入上述 chmod 命令来固化)

2. 安装 Intel 驱动依赖(LXC 与 虚拟机均需要)

无论是 LXC 容器还是 VM,系统都需要 intel-media-va-driver-non-free 驱动来支持 QSV 解码。

以 Debian/Ubuntu 系统为例(容器内或 VM 内):

apt update
apt install -y va-driver-all vainfo intel-media-va-driver-non-free

安装完成后,运行 vainfo 检查是否成功识别核显:

# 如果在 LXC 容器内,可能需要指定设备路径
vainfo --device /dev/dri/renderD129

若输出类似以下内容,则说明硬件解码驱动完全就绪:

libva info: VA-API version 1.17.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_17
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.17 (libva 2.17.0)
...
vainfo: Supported profile and entrypoints
      VAProfileH264Main               :	VAEntrypointVLD
      VAProfileH264Main               :	VAEntrypointEncSliceLP
      VAProfileHEVCMain               :	VAEntrypointVLD
      VAProfileHEVCMain               :	VAEntrypointEncSliceLP
      VAProfileAV1Profile0            :	VAEntrypointVLD

(注:出现 EncSliceLP 代表支持 Low-Power 模式编码,这对于 N100 QSV 极为重要)


第四步:Jellyfin / Plex 开启 QSV 硬解

1. Jellyfin 配置

  1. 登录 Jellyfin 网页后台,进入 控制台 -> 播放 -> 转码
  2. 硬件加速:选择 Intel QuickSync (QSV)
  3. Intel QuickSync 选项
    • 勾选 H.264HEVCMPEG2VC1VP9AV1 的解码支持(N100 完整支持 AV1 解码)。
  4. 启用硬件编码:勾选。
  5. 启用低功率 H.264 硬件编码 / 启用低功率 HEVC 硬件编码(Enable Low-Power H.264/HEVC hardware encoding):
    • 必须勾选。N100(Alder Lake-N)的核显架构依赖 Low-Power 模式进行硬塑,不勾选此项可能导致转码失败。
  6. 保存设置。

2. Plex Pass 配置 (需要会员)

如果你使用的是 Plex,并且拥有 Plex Pass:

  1. 打开 Plex 网页端,进入 设置 -> 转码器
  2. 勾选 Use hardware acceleration when available(启用硬件加速)。
  3. 勾选 Use hardware-accelerated video encoding(启用硬件加速视频编码)。
  4. Hardware transcoding device:在下拉列表中选择带有 Alder Lake-NIntel UHD Graphics 标志的虚拟显卡。
  5. 保存。

避坑与调优指南

Q1: 运行 vainfo 报错 VA-API error: unknown libva error

  • 原因:通常是 GuC/HuC 固件未在宿主机正确加载。
  • 解决方法:在 PVE 宿主机上运行 dmesg | grep i915。检查是否有 GuC/HuC firmware load failed 相关的错误。如果提示固件丢失,需要前往 Linux Firmware 官网下载对应 Alder Lake 的 glk_huc.bintgl_guc_*.bin 固件并放入 /lib/firmware/i915/ 目录下,然后重新制作 initramfs:update-initramfs -u -k all

Q2: 宿主机升级 PVE 内核后,SR-IOV 失效了

  • 原因:PVE 升级内核(例如从 6.5 升级到 6.8)后,原先编译的 DKMS 驱动没有自动应用到新内核。
  • 解决方法
    在新内核下重新执行编译与安装:
    apt install -y pve-headers-$(uname -r)
    dkms autoinstall
    
    并检查 /etc/sysfs.conf 里的显卡 PCI 地址是否因硬件变动而发生改变。

Q3: Jellyfin 播放视频出现绿屏、花屏或提示“客户端不支持此媒体”

  • 原因:Jellyfin 的官方 Docker 镜像或系统的 va-driver 冲突。或者是由于未勾选“低功率(Low-Power)”转码。
  • 解决方法
    • 进入 Jellyfin 容器内,确认 intel-media-va-driver-non-free 是激活状态,而非开源的 mesa 驱动。
    • 如果是 Docker 部署,确保将 /dev/dri 映射进容器,并且 Docker 运行用户有读写 /dev/dri 的权限(可以通过设置 user: 0:0 或分配正确的 group_add 解决)。

点评评价

captcha
健康