拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CentOS 8安装NVIDIA显卡驱动:ELRepo与runfile实战排坑指南

CentOS 8安装NVIDIA显卡驱动:ELRepo与runfile实战排坑指南

1. 先搞清楚:CentOS 8上装显卡驱动难在哪

2021年底CentOS 8停止维护之后,我手里几台GPU服务器的系统就一直没敢动。道理很简单:系统层面一旦折腾,驱动、CUDA、容器运行时这一整条链都得重新捋一遍。但该来的总会来——一次业务窗口期需要重装驱动,前前后后踩了不少坑,这才发现CentOS 8装NVIDIA显卡驱动这件事,和Ubuntu上完全是两个难度等级。

这篇文章就把我在CentOS 8上装显卡驱动的完整思路和踩坑记录整理出来,覆盖从环境检查、方案选型到ELRepo和官方runfile两种主流路线,再往后是nouveau残留、Secure Boot、内核升级导致驱动失效这类高频问题的排查链路。不管你是跑深度学习的训练机器、普通办公工作站,还是刚把系统从CentOS 7迁到8的运维,这套经验应该都能直接抄。

1.1 动手之前,先给机器做个全面体检

很多人上来就找安装命令,结果装到一半各种报错,最后发现是环境没摸清楚。我建议第一步先把下面这几条命令挨个跑一遍,输出截图或者抄下来,后续所有操作都围绕这些信息展开。

cat /etc/redhat-release uname -r lspci | grep -i nvidia lsmod | grep -i -E 'nvidia|nouveau'

这几条命令分别解决四个核心问题:

  • cat /etc/redhat-release:确认系统是CentOS 8还是CentOS Stream 8,或者其实是Rocky Linux/AlmaLinux。这几个系统的源和CentOS 8基本通用,但后续加ELRepo源时不能搞错主版本号。
  • uname -r:当前内核版本,这个必须记死。后面装kernel-devel、DKMS、kmod-nvidia全都依赖这个版本号,版本错一个字符都编译不过。
  • lspci | grep -i nvidia:确认显卡型号和PCI设备ID。这一步能帮你判断该用哪个驱动分支。
  • lsmod | grep -i -E 'nvidia|nouveau':看当前有没有加载NVIDIA或nouveau模块。如果系统里有nouveau残留,后面驱动装了也白装,这是所有安装失败的源头之一。

还有一个容易被忽略的检查项:确认自己的GPU属于哪个架构。比如P100、P40、V100这些Tesla卡属于Pascal/Volta架构,官方支持周期非常长;RTX 2080 Ti、Titan RTX这类Turing卡也还在活跃支持名单里;但如果是GTX 10系及更早的GeForce卡,驱动分支会切到legacy,盲目装最新驱动反而可能得不到支持。动手之前先想清楚:你是在给数据中心卡装驱动,还是在给一张老游戏卡续命,这两者的选型逻辑完全不同。

1.2 三条安装路线,先选对再动手

CentOS 8上没有像Ubuntu那样一条apt install nvidia-driver-xxx就能搞定的官方驱动源,实际可选的就三条路:官方runfile、ELRepo的kmod-nvidia包、RPM Fusion。很多人纠结选哪个,我用一个表格把它们的核心差异列出来。

方案优点缺点适合场景
官方runfile版本自由、可自定义编译参数、CUI/桌面都能装内核更新后要自己维护、卸载不干净容易留残留需要精确控制驱动版本、要覆盖旧驱动
ELRepo kmod-nvidia随内核自动匹配模块、卸载干净、源内维护版本同步稍慢、新卡支持可能滞后生产服务器、跑CUDA、不想折腾
RPM Fusion桌面集成较好、依赖自动处理CentOS 8上后期维护一般、依赖包多装了图形界面的工作站

以我自己的经验来说,如果这台机器是生产服务器,主要用途是跑CUDA和深度学习训练,优先ELRepo;如果是个人工作站,需要最新版驱动或要调试显卡输出,官方runfile更合适。RPM Fusion我在CentOS 8上用的不多,它更适合Fedora系,在RHEL系上总是有些依赖要手动处理,没必要给自己加负担。

2. ELRepo路线:生产服务器最省心的选择

ELRepo是RHEL系第三方源里做内核相关包最成熟的,kmod-nvidia是它的招牌之一。所谓kmod(kernel module)包,意思是这个驱动以内核模块的形式随内核版本一起打包,你升级内核时它会同步更新模块,不用每次手动重装驱动。就冲着这一点,我在GPU服务器上基本无脑选它。

2.1 三步走:加源、探测、安装

第一步是导入ELRepo的GPG密钥并安装源。注意这里有个细节:elrepo-release的版本要明确指定8,对应RHEL 8系,千万别手滑装成el7的包,否则会污染整个源配置。

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm

装完源之后,用ELRepo自带的nvidia-detect工具探测系统推荐的驱动版本。这个工具会读显卡的PCI ID,然后告诉你这台机器该装哪个分支,避免你装了个过老或过新的驱动。

yum --enablerepo=elrepo-search install nvidia-detect nvidia-detect

输出类似下面这样:

Detected NVIDIA GPU: GeForce RTX 2080 Ti [10de:1e07] Recommended driver: nvidia-latest

如果输出推荐的是nvidia-latest,就装通用的kmod-nvidia包;如果提示老卡建议用nvidia-470xx这类legacy分支,就装对应的kmod-nvidia-470xx。我见过有人不看detect结果直接装最新包,结果老卡根本不认,浪费时间。按推荐来,别自作聪明。

安装这一步最简单:

yum --enablerepo=elrepo -y install kmod-nvidia

如果你这台机器还带图形界面,建议顺手把nvidia-x11-drv也装上,否则X11可能起不来。装完之后重启,然后跑nvidia-smi验证。

2.2 ELRepo装完后的验证与隐藏坑

重启后第一件事就是验证驱动是否正常加载:

nvidia-smi cat /proc/driver/nvidia/version

如果nvidia-smi正常输出显卡型号、驱动版本、显存大小,说明这步已经成了。但ELRepo这条路有几个隐藏坑,我一个个说。

第一个坑:ELRepo的kmod-nvidia不会自动帮你禁用nouveau。很多人默认以为源包会自动处理,结果装完重启,NVIDIA模块根本没加载,因为nouveau先占用了设备。解决办法是装包之前就把nouveau黑名单写好,这个操作我后面专门讲。

第二个坑:内核升级后ELRepo源同步有延迟。yum update把内核从4.18.0升级到新版本后重启,如果ELRepo还没发布对应新内核的kmod-nvidia包,驱动就会失效。这不是你的问题,是源同步节奏问题。我的习惯是升级内核前先查一下源里有没有对应版本:

yum --enablerepo=elrepo list kmod-nvidia --showduplicates

如果发现源里还没同步到当前最新内核,就先不升,或者升级后继续用旧内核启动,等源同步了再切。

第三个坑:新内核装上后,模块包虽然装了,但initramfs没更新。有时候重启后lsmod | grep nvidia有输出,但nvidia-smi还是报错,多半是initramfs里没有正确包含新模块。手动重建一次就好:

dracut --force

3. 官方runfile路线:版本自由,但得对自己负责

ELRepo虽然省心,但有些场景它满足不了:你要装一个ELRepo源里还没有的驱动分支,或者你需要精确控制驱动版本和CUDA版本的搭配,这时候官方runfile就是唯一选择。runfile本质上是一个自解压的安装包,里面有完整的驱动源码、编译工具和安装脚本,可以理解成NVIDIA官方给你的一份“手动挡”安装方案。

3.1 下载与禁用nouveau是第一步

先去NVIDIA官网驱动下载页面选择显卡型号和操作系统,拿到.run文件的下载链接。这里插一句:很多人习惯在Windows上先把文件下载好再传到Linux机器上,Windows端用7-Zip解压时报“7-zip crc错误”,其实就是文件在传输或者下载过程中损坏了,跟驱动本身没关系。在Linux这边对应的检查方式是用sha256sum校验文件的完整性:

sha256sum NVIDIA-Linux-x86_64-*.run

把输出的哈希值和官网页面上标注的比对,一致才继续。这一步别省,我见过有人带着损坏的安装包跑了半天,最后每一步都是莫名其妙的报错。

好,文件确认没问题,接下来禁用nouveau,这一步在runfile路线上是硬性条件:

cat > /etc/modprobe.d/blacklist-nouveau.conf <<EOF blacklist nouveau options nouveau modeset=0 EOF

重建initramfs,让黑名单真正生效:

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

重启,确认nouveau已经不在内核里:

lsmod | grep nouveau

如果这条命令还有输出,说明没禁干净。常见的补救办法是在内核启动参数里手动加rd.driver.blacklist=nouveau,具体做法是编辑/etc/default/grub中的GRUB_CMDLINE_LINUX,加上那条参数后执行grub2-mkconfig -o /boot/grub2/grub.cfg再重启。禁用nouveau这一步没做到位的话,后面的安装过程会反复出问题,甚至装完了也跑不起来。

3.2 安装参数、编译过程与内核头文件匹配

runfile安装时会现场编译内核模块,所以先确保编译环境是完整的:

yum groupinstall -y "Development Tools" yum install -y kernel-devel-$(uname -r) gcc make

注意kernel-devel的版本号必须和当前的uname -r完全一致。很多人图省事直接yum install kernel-devel,结果装的是最新内核对应的头文件,当前内核编译时就报“Unable to find the kernel source tree”,这种错误我见过太多次了。

接下来切换到多用户模式,相当于以前的init 3,关闭图形服务,避免X11占用显卡资源:

systemctl isolate multi-user.target

然后执行安装脚本。我一般会带上这几个参数:

./NVIDIA-Linux-x86_64-*.run --no-x-check --no-nouveau-check --dkms

参数含义做一个简单解释:

  • --no-x-check:当前没有运行X服务时避免安装脚本误报。
  • --no-nouveau-check:我们已经禁用了nouveau,跳过它自带的检查。
  • --dkms:把内核模块注册到DKMS里,以后内核更新时DKMS会自动重建模块。这个参数强烈建议加,不加的话每次内核升级都要手动重跑一遍安装脚本。

安装过程中如果报gcc版本问题,先确认系统默认gcc是否可用。CentOS 8自带的gcc是8.x,如果你装了devtoolset或者SCL里的新版本gcc,编译NVIDIA模块时可能出现未知目标平台之类的报错。这时候要么把默认gcc切回系统自带版本,要么在安装时指定CC=/bin/gcc。

安装完成后再切换回图形模式:

systemctl isolate graphical.target

然后验证:

nvidia-smi

如果这时候报“Unable to load the 'nvidia-drm' kernel module”,去/var/log/nvidia-installer.log翻日志,基本都是kernel-devel版本不匹配或nouveau没禁干净造成的,按前面步骤排查即可。

4. 安装过程中最常翻车的四个环节

跑完上面两条路线之后,你会发现真正卡人的往往不是安装步骤本身,而是那些环境层面的细节。我把我碰到过的、以及周围同事高频遇到的问题集中整理一下。

4.1 nouveau残留:症状像“驱动装好了但起不来”

nouveau是Linux内核自带的NVIDIA开源驱动,它最大的问题就是性能差且和官方驱动不兼容。如果你没禁用它就直接装官方驱动,情况通常是这样:安装脚本显示成功,重启后nvidia-smi却报“NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver”,而且dmesg里能看到NVRM: failed to initialize the NVIDIA driver。

原因就是nouveau抢先占用了显卡设备,官方驱动模块加载时发现设备已经被别的驱动绑定了,只能放弃。排查方法也很直接:

lsmod | grep nouveau dmesg | grep -i nvidia

确认nouveau还在,就按前面讲的黑名单步骤处理,重建initramfs,重启后再验证lsmod | grep nouveau没有输出。如果已经进不了图形界面,可以在GRUB启动菜单按e编辑启动项,在linux那一行末尾加rd.driver.blacklist=nouveau,临时绕过去之后再彻底配置黑名单。

4.2 Secure Boot拦路:一个容易被忽略的环节

现在新出厂的服务器很多默认开启了Secure Boot,如果没注意这个,驱动模块会因为未签名被内核拒绝加载。检查方法:

mokutil --sb-state

输出SecureBoot enabled就说明开启了。ELRepo的kmod-nvidia包有些版本自带签名,但不同机器表现不一致;官方runfile配合DKMS安装时,会提示创建MOK密钥并在重启时进行enrollment,这个流程如果跳过了,模块同样起不来。

最稳妥的方案有两个:一是直接在BIOS里关闭Secure Boot,适合纯计算服务器;二是走MOK签名流程,重启时按提示输入密码完成enrollment。对公司生产机器我一般建议直接关掉,毕竟服务器上没必要开这个,省得每次装驱动都折腾签名。

4.3 gcc与kernel-devel版本不一致的连锁反应

这一条在runfile路线和自编译场景下特别常见。内核模块编译时会同时检查三样东西:正在运行的内核源码树、当前gcc版本、以及头文件路径。如果uname -r是4.18.0-477.10.1.el8.x86_64,但你装的kernel-devel是4.18.0-477.27.1.el8,编译出来的模块和当前内核的符号版本就对不上,装上去也会加载失败。

我建议把它固化成一套固定流程:

uname -r yum install -y kernel-devel-$(uname -r) gcc --version

把这三个输出记下来,装驱动时对照检查。特别是升级内核之后,kernel-devel也要跟着升,这个同步关系不维护好,驱动失效只是时间问题。

4.4 下载文件损坏与驱动残留

前面提到过Windows下解压报“7-zip crc错误”,本质是下载文件损坏。Linux这边同样有对应的隐患,但很多人没有校验哈希的习惯,带着一个坏安装包硬跑安装脚本,结果编译到一半各种No space left、unexpected EOF之类的诡异报错。每个官方.run文件都有对应的SHA256值,下载后花两秒钟校验一下,能省掉后面几个小时的排查。

另外就是驱动残留。如果机器之前装过旧驱动,尤其是混用过ELRepo和官方runfile这两种方式,残留的库文件和内核模块会互相干扰。换方案之前先清理干净:

yum remove kmod-nvidia* nvidia-* 2>/dev/null ./NVIDIA-Linux-x86_64-*.run --uninstall

再检查这些路径还有没有遗留:

rpm -qa | grep -i nvidia ls /usr/lib64/libnvidia* ls /usr/lib/modules/*/kernel/drivers/video/nvidia*

清理完再装新的,能避免大量“装了但没完全装”的诡异状态。

5. 装完不等于完事:驱动失效的排查链路

很多人以为nvidia-smi能跑就万事大吉,实际上驱动装完只是开始。服务器跑着跑着,有时候重启一次驱动就没了,这背后的原因和排查路径值得单独梳理。

5.1 nvidia-smi无输出的几种典型状态

nvidia-smi的输出不同,对应的排查方向完全不一样,先看最常见的三类:

输出含义排查方向
command not found驱动根本没装成功或PATH不对卸载重装,检查安装日志
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver内核模块没加载看dmesg、查nouveau残留、检查Secure Boot
Failed to initialize NVML: Driver/library version mismatch内核模块和用户态库版本不一致卸载并重新加载模块,必要时重启

第三种在CentOS 8上出现频率特别高,尤其是你升级过内核或者手动更新过NVIDIA用户态库之后。内核里加载的nvidia.ko还是老版本,但libnvidia-ml.so已经是新版,两者对不上。短平快的处理方式是按顺序把所有NVIDIA相关模块卸载再重新加载:

lsmod | grep nvidia modprobe -r nvidia_uvm nvidia_drm nvidia_modeset nvidia modprobe nvidia nvidia-smi

如果这样还不行,重启通常能解决,因为重启时内核会重新加载所有模块,让版本重新对齐。

5.2 X11黑屏和登录循环的定位思路

装了图形界面的机器,装完驱动后偶尔会出现黑屏或者登录成功后马上跳回登录界面的情况。这时候注意:只要能通过SSH登录,系统就还没坏,只是X服务起不来。

先看日志:

cat /var/log/Xorg.0.log | grep "(EE)"

重点找两样东西:(EE) Failed to load module nvidia或者(EE) NVIDIA: Failed to initialize the NVIDIA kernel module。前者说明X11压根没加载到NVIDIA驱动,后者说明内核模块加载失败。

如果Xorg在试图驱动显卡时报错,可以用nvidia-xconfig重新生成配置并指定总线ID。先查询显卡信息:

nvidia-xconfig --query-gpu-info

然后把查到的BusID写进/etc/X11/xorg.conf。还有一种常见情况是双显卡机器(Intel核显+NVIDIA独显),X11默认用了核显的modesetting驱动,这时候在配置里指定NVIDIA的BusID和驱动名即可。登录循环这个问题,绝大多数情况下是Xorg配置或者Graphics驱动没切干净,顺着(EE)日志走基本都能定位。

5.3 内核升级后驱动失效的标准处理

这台机器只要还在跑yum update,内核就会时不时升级,驱动失效的戏码就会重演。分两种方案讨论。

如果你用的是ELRepo的kmod-nvidia,正常情况上升级内核时kmod包会跟着更新,重启后驱动自动可用。但如果ELRepo源还没同步新内核的包,你升级内核后重启就会失效。我的处理顺序是:

yum --enablerepo=elrepo update -y kmod-nvidia dracut --force reboot

如果源还没同步,暂时切回旧内核启动,等源更新后再升。判断旧内核是否还在,用grub2-set-default切换或者重启时在GRUB菜单里选。

如果你用的是官方runfile且加了--dkms参数,正常情况下内核升级后DKMS会自动重建模块。但DKMS重建依赖新内核的kernel-devel,没装的话重建会失败。所以每次内核升级后我都会手动确认:

dkms status

看到模块状态不是installed,先补装对应当前内核的kernel-devel,再dkms autoinstall,最后重启。如果当初没加--dkms参数,那只能重新把安装脚本跑一遍,这是最痛苦的路线,也是我反复强调一定要加--dkms的原因。

6. 从实践里总结的几条“早知道就好”的经验

驱动装完、验证通过,只是长征走完一半。下面这几条是我在实际运维中反复用到、也反复栽过的经验,提前知道能省掉不少事。

6.1 驱动版本与CUDA版本的匹配关系

很多人装完驱动后才发现CUDA和驱动版本对不上,跑nvcc --version没问题,一跑深度学习框架就提示驱动版本过旧。这里直接给一张常用对应表:

NVIDIA驱动分支对应CUDA版本典型使用场景
470.xCUDA 11.4 - 11.6老卡兼容、数据中心P100/P40等
510.x / 515.xCUDA 11.6 - 11.830系、A100、V100
525.x / 530.xCUDA 12.0 - 12.140系、H100
535.xCUDA 12.2通用新卡
550.xCUDA 12.4+最新驱动分支

注意,这是驱动分支和CUDA toolkit的匹配关系。如果你已经装了CUDA 11.8的toolkit,又花时间升级驱动到535,表面上没问题,但要注意驱动分支对CUDA版本向下兼容,反过来就不一定。我的习惯是:先确定要用什么CUDA版本,再反推驱动版本,最后再决定用ELRepo还是runfile。

6.2 几个能保命的操作习惯

第一,装驱动前做快照。物理机没条件的话,至少备份/boot目录和initramfs,出问题能直接恢复。第二,图形界面开启状态不要直接跑安装脚本,先multi-user.target或者init 3,装完再切回来。第三,所有安装日志都保存在/var/log/nvidia-installer.log、/var/log/Xorg.0.log、/var/log/messages里,排查时第一反应先看日志,别盲目重装。第四,对于CentOS 8这种已经停止维护的系统,稳定压倒一切,驱动版本能选长期分支就不追最新,生产机器上求稳不求新。

6.3 什么时候别用runfile

最后说一个容易被忽略的点:如果你的目标是跑CUDA或者说跑深度学习框架,而不是搞驱动开发,那尽量别用官方runfile。原因很简单,runfile安装的驱动和后续CUDA toolkit里的驱动版本可能会互相打架,而ELRepo的kmod-nvidia方式是纯内核模块管理,和CUDA toolkit完全是两套体系,冲突概率小得多。

我自己的实操习惯是:在所有GPU服务器上,先确保ELRepo的kmod-nvidia装好、nvidia-smi输出正常,再装CUDA toolkit。装完CUDA后不会去动驱动版本,因为CUDA自带驱动容易把ELRepo的驱动搞乱。如果你已经用runfile装了驱动,之后又装了CUDA toolkit,发现版本冲突,那就用nvidia-smi显示的实际驱动版本为准,不要手贱去覆盖驱动文件。

CentOS 8这套体系虽然老,但只要不乱升级内核、不乱混用安装方式,GPU服务器其实非常稳。希望这篇能帮你把装驱动那条路上的坑提前排掉,少走几趟冤枉路。

返回列表