1. 为什么要手动装网卡驱动:那些“系统装好了但没网”的瞬间
装 CentOS 7 时最让人血压升高的场景,不是分区报错,不是 GRUB 引导失败,而是系统安装完成后,敲ip addr发现只有 lo 回环接口,eth0压根不存在;或者明明插着网线,交换机端口灯也亮着,但ping www.baidu.com就是不通。排除了网线、交换机、路由器这些物理因素之后,大概率就是网卡驱动没加载上。
这类问题在 CentOS 7 上尤其容易出现。CentOS 7 用的是 3.10.x 内核,这个内核版本本身就有些年头了,对新出的网卡芯片支持不完整。你拿着最新的主板、最新的网卡去装 CentOS 7,系统自带的内核驱动里很可能没有对应硬件的驱动模块,或者有模块但匹配不上。另一个常见场景是装了双网卡甚至四网卡,系统只认出来其中一张,另一张新加的网卡完全没有被识别。还有一种是服务器网卡损坏需要更换,换上去的是一块老系统不认识的卡。
这种时候就得手动下载网卡驱动源码包,自己编译安装。用一句话概括:系统默认驱动是给大多数硬件用的通用方案,你的硬件如果不在它的“熟人名单”里,就需要你自己把驱动“请”进来。
需要手动装网卡驱动的人主要有这么几类:
- 用较新硬件的个人电脑或工作站装 CentOS 7,板载网卡未被识别。
- 给老服务器扩网口,新加的网卡型号较新,系统驱动列表里查无此卡。
- 使用特定厂商网卡(比如某国产品牌的 PCIe 千兆/万兆网卡),官方只提供 Linux 源码驱动,没有直接打进 CentOS 7 内核。
- 需要调整网卡驱动参数(如队列数、中断合并策略等),默认驱动不带这些可调项,只能换成源码驱动自己编译。
这篇文章不是简单的命令罗列,而是把整个流程背后的原理和排查思路讲透。你会弄清楚:怎么确认网卡型号、怎么判断系统到底缺没缺驱动、怎么找到对应内核版本的源码包、编译时那些参数是什么意思,以及装完之后网卡还是起不来该怎么查。整套流程踩过的坑我都会指出来,你可以照着操作,也可以根据自己的网卡型号灵活调整。
2. 动手之前的硬件侦察:先搞清楚你面对的是什么网卡
很多人在编译驱动这一步反复失败,往往是因为第一步就走错了:没有确认网卡的准确芯片型号就盲目下载驱动源码包。这一步马虎不得,芯片型号认错了,后面全白干。
2.1 用 lspci 确认网卡芯片型号
网卡的物理信息可以通过 PCI 设备列表查看。终端执行:
lspci | grep -i ethernet输出类似这样:
02:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)这就很明确了:英特尔 I210 千兆网卡,PCI 地址是 02:00.0。这里要特别强调,看的是芯片型号,不是品牌。同样是某品牌的网卡,不同批次可能用完全不同的芯片,比如有的用 Intel I210,有的用瑞昱 RTL8111,驱动完全不通用。
如果lspci输出里设备名显示为Ethernet controller: XXX Corporation Device 1234这种格式,说明系统也不认识这块卡,但至少能看出厂商 ID 和设备 ID(比如 1234 就是十六进制的设备编号)。这时候可以把厂商 ID 和设备 ID 记下来,去网上搜一下对应的芯片型号。
2.2 通过 ethtool 查看现有驱动的加载情况
如果网卡已经能被识别,只是驱动不太对或者版本太老,可以用ethtool查看驱动信息:
ethtool -i eth0输出示例:
driver: igb version: 5.2.5 firmware-version: 1.64, 0x8000 bus-info: 0000:02:00.0这里的driver就是当前加载的驱动模块名,version是驱动版本。这个信息在后续判断“需不需要换驱动”时很有用。比如 igb 驱动的 5.2.5 版本,如果你确认有更新版本修复了某个 bug,或者你需要开启某个新特性,就可以考虑手动更新。
如果ethtool -i eth0直接报错说 “No such device”,说明设备虽然存在但驱动根本没绑定上,这就要重点检查驱动加载了。
2.3 系统到底有没有识别到网卡设备
驱动故障分两种:一种是设备初始化失败,另一种是驱动压根没加载。要区分这两种情况,看dmesg日志最直接:
dmesg | grep -i eth dmesg | grep -i net如果看到类似igb 0000:02:00.0: failed to load because ...的信息,说明系统已经发现了设备,但驱动初始化时报错了。如果 dmesg 里完全没有和这个 PCI 设备相关的网络信息,那就是设备还没被驱动认领。
用lsmod | grep igb可以确认驱动模块是否已加载。再用ls /sys/bus/pci/drivers/igb可以看驱动是否绑定到了设备上。
这里有个经验:如果 dmesg 里能看到网卡设备,但报错信息比较晦涩,优先考虑换驱动版本;如果 dmesg 里完全没有这个设备,优先检查 BIOS 里有没有把网卡禁用,或者 PCIE 插槽是否接触良好。
3. 准备编译环境与下载驱动源码:不只解压那么简单
确认了芯片型号,下一步是准备编译环境。这一步看着简单,但坑特别多——尤其是内核头文件版本对不上,会导致编译时报出一大堆找不到头文件的错误。
3.1 确认内核版本与架构
编译内核模块必须和当前运行的内核版本严格对应。先执行:
uname -r比如输出3.10.0-1160.el7.x86_64,这说明内核版本是 3.10.0-1160,架构是 x86_64。后面的编译过程,所有内核模块都要针对这个版本进行。
还要确认系统版本:
cat /etc/redhat-release输出类似CentOS Linux release 7.9.2009 (Core)。CentOS 7.9 是 7 系列最终的版本,大多是 7.6 到 7.9 之间。内核版本会因为 yum update 而有差异,所以务必以uname -r的实际输出来核配,不要只看系统版本号。
3.2 安装编译工具链:gcc、make 和内核开发包
CentOS 7 最小化安装往往不带编译工具,需要手动安装。执行:
yum install -y gcc make kernel-devel kernel-headers这一条命令装了三样东西:
gcc:C 语言编译器,网卡驱动源码基本都是 C 写的。make:构建工具,负责按照 Makefile 文件自动编译。kernel-devel:内核开发包,包含编译内核模块所需的头文件和 Makefile 片段。
kernel-devel 的版本必须和 uname -r 输出的内核版本一致,这是最容易出问题的地方。CentOS 7 的 yum 源里 kernel-devel 默认可能比你当前内核版本旧或新。如果不一致,编译时会出现类似/lib/modules/3.10.0-1160.el7.x86_64/build: No such file or directory的报错。
检查版本是否匹配:
ls /usr/src/kernels/正常会看到一个以当前内核版本命名的目录,比如3.10.0-1160.el7.x86_64。如果这个目录不存在,或者名字和 uname -r 不一致,就得手动装对应版本:
yum install -y kernel-devel-$(uname -r)有些时候 yum 源里没有完全对应的 kernel-devel,可以先用yum list available | grep kernel-devel看看有哪些版本。如果源里没有,就需要去镜像站下载对应 RPM 包,手动安装。
顺带提一下kernel-headers和kernel-devel的区别。headers 提供的是用户空间编译时需要的头文件,而 devel 提供的是内核模块编译需要的头文件和 build 目录结构。编译内核模块,必须用到 kernel-devel 而不是 kernel-headers。
3.3 去官方网站下载对应型号的驱动源码包
这一步取决于芯片厂商:
- Intel 网卡:去 Intel 官网下载中心,搜索对应芯片型号,找到 Linux 下的驱动源码包,通常是
.tar.gz格式。Intel 的 e1000e 系列、igb 系列、ixgbe 系列驱动包命名很直观,比如igb-5.7.2.tar.gz。 - 瑞昱(Realtek)网卡:瑞昱官网提供的 Linux 驱动源码包名字一般包含芯片型号,比如
r8168-8.049.02.tar.bz2或r8125-9.006.00.tar.bz2。下载时看清是哪个芯片的。 - Atheros/Qualcomm 网卡:部分 ath 系列在 Linux 内核里已有支持,但如果用官方源码包,可以去对应支持页面下载。
- 其他品牌:建议直接从网卡的 ODM/OEM 官网或者芯片原厂官网获取,避免在第三方站点下载到被修改过的源码包。源码包下载后,先校验一下文件完整性,比如用
md5sum对比官网公布的校验值。
下载完成后,把压缩包放到一个专门的目录下,比如/opt/drivers。不建议放 /root 或 /tmp 之外的太随意位置,免得后面找不着。
3.4 解压源码包并查看说明文档
mkdir -p /opt/drivers cd /opt/drivers tar -zxvf igb-5.7.2.tar.gz解压后进入目录,第一件事是看README或INSTALL文件:
cd igb-5.7.2 ls -l cat READMEREADME 里会写明:支持哪些芯片型号、最低内核版本要求、编译前需要哪些依赖、安装步骤。很多编译失败的问题,在 README 里都有提示。比如有的驱动要求内核版本至少某版本以上,如果你当前内核太老,就需要先升级内核再编译驱动。
另外有些驱动包里其实带了几个不同的驱动模块,需要看清楚你要用的是哪一个。比如 Intel 的 igb 驱动下载包里,实际编译出来的是 igb.ko,对应的是 Intel 82575/82576/I350 等系列千兆网卡,不是 e1000e。
4. 源码编译安装实操:每一步的原理都要知道
编译安装这类第三方驱动,步骤看起来就三件事:make、make install、modprobe。但每一步的细节和可能遇到的问题,是需要认真对待的。
4.1 编译前的常见配置选项
在运行make之前,可以先查看 Makefile 里的配置项:
make help不同驱动包的 Makefile 不太一样,但通常支持以下选项:
make:默认编译当前内核版本对应的模块。make install:把编译出来的.ko文件安装到/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/下对应的子目录。make clean:清理编译产生的临时文件,重新编译前建议执行一次。- 有些驱动还支持
make menuconfig或者直接编辑Makefile调整编译参数。
多数情况直接make就行。如果 README 里有特别说明需要调整什么参数(比如使用DESTDIR指定安装路径、设置KSRC指定内核源码目录),再按说明操作。
这里有个关键点:编译时 Makefile 会自动调用/lib/modules/$(uname -r)/build这个软链接指向的内核源码目录。如果kernel-devel装好了,这个软链接就存在。可以用ls -l /lib/modules/$(uname -r)/build验证一下它是否能正常解析。
4.2 执行编译:make 命令的完整过程
在源码目录下执行:
make如果一切正常,屏幕会滚动很多编译输出,最后生成.ko后缀的内核模块文件,比如igb.ko。编译过程是在调用 gcc 编译每个源文件,然后链接成内核模块。
如果编译报错,需要仔细看第一条 error 信息,不是看最后的 error 汇总。常见错误有两类:
第一类:找不到头文件。报错形如fatal error: linux/xxx.h: No such file or directory。这个大概率是 kernel-devel 没装或者版本不对。重新检查/usr/src/kernels下的目录名与uname -r是否一致。
第二类:语法错误或类型不匹配。这个通常是源码包太老,不兼容当前内核版本的 API。比如有些老驱动用了已在新内核中删除的函数。解决办法:换新版本驱动,或者给源码打补丁。有些厂商会在官网上提供针对特定内核版本的补丁文件。
4.3 安装驱动模块:make install 做了什么
编译成功后执行:
make install这条命令会把.ko文件复制到内核模块目录:
/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/intel/igb.ko这个路径结构是有讲究的:kernel/drivers/net/ethernet/是内核源码里网络驱动的标准位置,不同的网卡芯片厂商会有各自的子目录,比如 intel、realtek、broadcom 等。装到这里之后,depmod 工具才能正常扫描到驱动模块的依赖关系。
4.4 刷新模块依赖并加载驱动
模块安装到系统目录后,需要刷新模块依赖关系:
depmod -adepmod会扫描/lib/modules/$(uname -r)/kernel/下所有的模块,生成modules.dep和modules.alias等文件。这一步很重要,少了它,modprobe igb可能提示找不到模块,因为系统还不知道新模块的存在。
然后加载驱动:
modprobe igbmodprobe和insmod的区别在于:modprobe会自动处理模块依赖,而且会从标准模块目录查找;insmod需要你指定模块文件的完整路径,且不处理依赖。所以一律推荐用modprobe。
加载后验证:
lsmod | grep igb输出里有igb 123456 0这样的字样,说明模块已经加载成功。此时再执行ethtool -i eth0,应该能看到 driver 变成了 igb。
如果modprobe报错说FATAL: Module igb not found,先跑一遍depmod -a再试。如果还不行,确认模块文件真的存在于/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/intel/下。
4.5 让驱动开机自动加载
这里要分情况讨论。如果你的网卡设备能被系统正常识别,且驱动模块已复制到标准路径,那么通常不需要手动配置开机加载。因为 udev 在系统启动时会检测硬件设备,如果驱动模块存在于标准路径,它会自动被加载。
但有一种情况需要手动配置:驱动模块和设备 ID 的匹配关系没有被系统识别。部分第三方网卡的设备 ID 不在驱动的默认支持列表里,或者驱动加载顺序有问题,就会导致开机后设备没被驱动绑定。
这时需要在/etc/modules-load.d/下创建一个配置文件:
echo "igb" > /etc/modules-load.d/igb.conf这样系统启动时就会强制加载 igb 模块。再者要在/etc/modprobe.d/下加配置,告诉系统该驱动支持哪些设备,比如:
alias eth0 igb不过这种写法在 CentOS 7 里其实很少用到,因为 udev 会基于 PCI 设备 ID 自动匹配模块。更多时候是在/etc/modprobe.d/igb.conf里写模块参数:
options igb InterruptThrottleRate=1,14.6 关于网卡接口命名的变化:从 eth0 到 eno16777736
CentOS 7 默认使用biosdevname或者 systemd 的命名规则,网卡接口名可能不是传统的eth0,而是类似eno1、ens33、enp2s0这样的名字。装了新驱动后,新网卡的接口名更可能是enp3s0(PCI 地址决定)或eno1(BIOS 固件决定),而不是 eth0。执行ip addr确认实际的接口名,再配置网络。
如果你习惯传统 ethX 命名方式,可以在/etc/default/grub的GRUB_CMDLINE_LINUX里加上net.ifnames=0 biosdevname=0,然后重新生成 grub 配置:
grub2-mkconfig -o /boot/grub2/grub.cfg重启后网卡会恢复成 eth0 这种命名。但要注意,这个改动会影响所有网卡的命名,不只是你新装的这块。
5. 驱动加载不上、系统没网:这些坑我帮你试过了
编译安装这个环节顺利通过的话,后面还有几个高频问题。我在实际处理中遇到过不少次,列出来给大家参考。
5.1 模块加载成功但网卡还是没 IP
这种情况特别典型:lsmod看到模块加载了,但ip link看不到网卡设备。排查思路:
第一步,确认驱动和设备 ID 是否匹配:
lspci -nn | grep -i ethernet输出里会带[8086:1533]这样的格式,方括号里就是 PCI vendor ID 和设备 ID,8086是 Intel 的 vendor ID,1533是设备 ID。再查这个设备 ID 是否在驱动的支持列表里。有些第三方网卡虽然用的芯片是 I210,但设备 ID 可能被改成了厂商自己的 ID,不在驱动白名单里,驱动就拒绝绑定。
解决办法:把设备 ID 加到驱动的MODULE_DEVICE_TABLE里重新编译,或者用modprobe igb force_vendor=...之类的参数绕过检测。具体可用的参数要看驱动文档。这个操作有点麻烦,但网络上搜索一下“网卡设备ID不识别”有大量方案可参考。
第二步,查看内核是否识别了网卡设备:
dmesg | grep -i igb如果有类似igb: probe of 0000:03:00.0 failed with error -5的信息,说明驱动探测硬件时失败。原因可能是硬件故障、PCIe 链路不稳、或者设备 ID 不被支持。
5.2 网卡驱动编译时报找不到内核源码目录
错误信息类似:
The file /lib/modules/3.10.0-1160.el7.x86_64/build does not exist.这个几乎是 kernel-devel 没装或装错版本。先看/usr/src/kernels/下有什么:
ls -la /usr/src/kernels/如果为空,说明没装成功。如果目录名和 uname -r 不一致,就需要手动装对应版本。CentOS 7 可以通过yum install kernel-devel-$(uname -r)精确匹配。
还有一种特殊情况:你之前升级过内核,现在跑的是新内核,但 kernel-devel 还停留在旧版本。这时 uname -r 和新内核版本一致,但 /usr/src/kernels 下是旧的。直接卸载旧 kernel-devel,然后装对应版本的即可。
5.3 系统更新内核后驱动消失了
这是个比较隐蔽的问题。如果你后来执行了yum update,内核升级到了新版本,那么/lib/modules/新版本/kernel/drivers/net/ethernet/intel/igb.ko这个路径下的模块还是之前编译时的旧版本模块,它仍然存在,但和新内核可能不兼容。更糟糕的情况是,新内核自带的 igb 模块覆盖了手动安装的模块,或者新内核的 API 变化导致旧模块无法加载。
处理办法:更新完内核后,重新编译一次驱动:
cd /opt/drivers/igb-5.7.2 make clean make make install depmod -a再重启或者 modprobe 一次。养成习惯:每当内核更新,都要重编第三方驱动。
5.4 固件文件缺失:firmware not found
部分网卡驱动在加载时需要额外的固件文件(microcode),比如一些 Intel 万兆网卡和瑞昱的网卡。如果缺失,dmesg 会显示:
igb 0000:02:00.0: firmware: failed to load igb/xxx.bin (-2)解决办法是去驱动包里的firmware目录找,或者从网卡厂商官网下载对应的固件文件,放到/lib/firmware/下对应子目录,然后重新触发驱动加载:
modprobe -r igb modprobe igb记得先确认是否需要存放子目录。有些固件要求放在/lib/firmware/intel/下,有些要求直接放在/lib/firmware/下,具体看驱动文档的要求。
5.5 驱动装好了网卡也认了,但 NetworkManager 不配合
CentOS 7 默认由 NetworkManager 管理网络。如果网卡设备已经存在,但 NetworkManager 没有自动创建配置文件,就会出现设备 visible 但没有 IP 的情况。
解决办法:
nmcli dev status查看网卡设备是否处于disconnected状态。如果是,手动创建一个 connection profile:
nmcli con add type ethernet con-name ens33 ifname ens33 nmcli con up ens33或者直接把网卡加入 NetworkManager 托管:
nmcli device set ens33 managed yes如果不想用 NetworkManager,也可以直接用传统的方式,在/etc/sysconfig/network-scripts/ifcfg-ens33里写配置:
DEVICE=ens33 BOOTPROTO=dhcp ONBOOT=yes写完后systemctl restart network。但注意 CentOS 7 里 service network 和 NetworkManager 同时启用的话可能会打架,建议二选一。对于服务器场景,我一般直接停用 NetworkManager,用 network.service 的传统方式,减少干扰。
5.6 模块加载顺序导致的冲突
系统里可能同时存在内核自带的驱动和手动安装的驱动,比如内置的 igb 和手动装的 igb 同名。这种情况下modprobe igb加载的是哪个版本,取决于模块目录的搜索顺序。
/lib/modules/$(uname -r)/updates/目录优先级更高,如果你把模块装到updates目录下,它会优先于kernel目录下的同名模块加载。有些驱动的make install会装到 updates 下,有些不会,所以要注意确认模块到底装到了哪里。
查看模块实际路径:
modinfo igb如果 modinfo 显示的路径不是你安装的那个,说明加载时用的是另一个同名模块。这时候可以手动把新模块放到 updates 目录,再跑一遍 depmod:
mkdir -p /lib/modules/$(uname -r)/updates/drivers/net/ethernet/intel/ cp /opt/drivers/igb-5.7.2/src/igb.ko /lib/modules/$(uname -r)/updates/drivers/net/ethernet/intel/ depmod -a5.7 编译出现 Werror 把警告当错误处理
有些驱动源码包在编译时启用了-Werror,把警告当错误处理。内核版本较新时,某些旧的驱动代码会产生新的警告,编译就直接失败。报错信息往往很长,但核心是那些warning: ...被当成了 error。
这种情况没法简单地关掉 Werror,因为 Makefile 里写死了编译选项。一个临时方案是手动修改 Makefile,把-Werror去掉,或者直接在编译命令里追加CFLAGS += -Wno-error。不过更推荐的做法是找新版本的驱动,或者按报错提示修改源码中触发警告的代码行。
实际处理时,我看到不少人卡在编译这一步就放弃了,其实把 Makefile 里的EXTRA_CFLAGS加上-Wno-error或者删掉-Werror就能过去,代价是可能遗留一些小问题但通常不影响驱动运行。
6. 验证驱动安装成功的完整检查清单
驱动装完,别急着欢呼,按这个清单走一遍,确认没问题才算真正搞定。
6.1 检查驱动模块是否正确加载
lsmod | grep 驱动名确认模块存在。注意,如果有多个同名模块,lsmod 只会显示加载的那个。
6.2 检查设备是否被驱动绑定
lspci -k | grep -A 3 -i ethernet输出里一般会有Kernel driver in use: igb这样的信息。如果没有这一行,说明设备没有被任何驱动绑定。
6.3 检查网络接口是否存在
ip link确认网卡接口(比如 ens33)状态是UP或者可以手动启用:
ip link set ens33 up6.4 测试链路连通性
先看链路状态:
ethtool ens33重点看Link detected: yes。如果显示 no,说明物理链路不通,问题可能出在线缆、交换机端口或对端设备。
链路通了之后,用 DHCP 获取地址或者配置静态 IP,然后 ping 网关和公网地址。
ping -c 4 192.168.1.1 ping -c 4 8.8.8.8能通就算大功告成。如果 ping 不通但链路显示 connected,检查 IP、路由、防火墙(CentOS 7 默认 firewalld 可能挡了 ICMP):
systemctl stop firewalld systemctl disable firewalld6.5 检查驱动参数是否生效
部分驱动支持模块参数调整。用ethtool -i和ethtool -l看队列数、中断设置等参数是否正确:
ethtool -i ens33 ethtool -l ens33比如 Intel 的 igb 驱动默认多队列功能,可以用ethtool -L ens33 combined 4设置队列数量,具体要看网卡支持的队列上限。
7. 一个典型实操案例:某品牌服务器加装新网卡的全过程
上面讲的都是方法和原理,这里用一个我实际处理过的案例串起来走一遍完整流程,方便你对照参考。
场景还原:某公司一台旧服务器,装的 CentOS 7.6,之前一直用的板载千兆网卡。后来业务量上来,需要加装一张新的 PCIe 千兆网卡,是某品牌的千兆电口卡。插上卡、开机,系统起来后发现新网卡完全没被识别,lspci能看到设备但系统里就是没有对应的网络接口。
处理步骤:
- 查芯片型号。
lspci -nn | grep -i ethernet输出:
04:00.0 Ethernet controller [0200]: Device [8086:1533] (rev 03)这说明新网卡实际使用的是 Intel I210 芯片,设备 ID 是 1533,vendor 是 8086。虽然品牌是某第三方,但芯片是 Intel 的,驱动得用 Intel 官方 igb 驱动。
- 确认内核版本和编译环境:
uname -r输出3.10.0-1160.el7.x86_64。检查/usr/src/kernels/下有对应目录,说明 kernel-devel 已就绪。
去 Intel 官网下载 igb 最新版源码包,放到 /opt/drivers 下解压。注意到 igb 5.7.2 版本要求内核至少 2.6.18,CentOS 7 的内核 3.10 完全满足。
编译前先看 README,确认支持 I210 芯片。然后执行:
cd /opt/drivers/igb-5.7.2/src make编译顺利,生成了 igb.ko。
- 安装模块:
make install depmod -a modprobe igb- 验证:
lsmod | grep igb看到 igb 已加载。ip link看到了新的接口enp4s0,状态 DOWN。
- 配置网络。由于该服务器计划给新网卡配静态 IP,直接在
/etc/sysconfig/network-scripts/下创建ifcfg-enp4s0:
DEVICE=enp4s0 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.20.10 NETMASK=255.255.255.0 GATEWAY=192.168.20.1 DNS1=8.8.8.8然后systemctl restart network。注意服务器上原有网卡 eth0 的配置不能受影响。实测下来新网卡 IP 正常,ping 网关通,访问外网正常。
这个案例里最关键的判断就是:网卡品牌是第三方,但芯片是 Intel I210,所以用的是 igb 驱动而不是品牌官网上的同名驱动。很多人在这里走弯路,跑去第三方品牌官网下载驱动,结果下载包里用的还是 Intel 的源代码,只是改了名字而已。认清芯片本质,很多问题都好解决。
另一个细节:新网卡的接口名默认是 enp4s0 不是 eth0,因为 CentOS 7 遵循的是 PCI 总线地址命名的规则。如果想要 eth0 这种名字,可以改 grub 参数,也可以不改,直接用 enp4s0 也没问题,只是自己心里要有数。
8. 驱动维护与后续注意事项
驱动装好只是开始,系统后续的更新维护里还有一些坑要留意。
8.1 内核升级后必须重编第三方驱动
这个前面已经强调过,内核从 3.10.0-1160 升级到 3.10.0-1160.el7.x86_64 的新小版本,第三方驱动的.ko文件也要重新编译。尤其是那种从 3.10 跳到 4.x 的大版本升级,旧驱动模块基本必挂。
建议把驱动源码包统一放在/opt/drivers/下,每次内核更新后跑一遍:
cd /opt/drivers/igb-5.7.2/src make clean make make install depmod -a有条件的可以写成脚本,配合 yum 的 kernel 更新钩子自动执行,省得每次都手动操作。
8.2 多块网卡时注意接口绑定顺序
如果服务器上有多块同型号网卡,驱动加载后接口名的分配顺序不一定和物理插槽顺序一致。CentOS 7 的 udev 会根据 PCI 地址和设备 ID 生成稳定的接口名,但如果你更换过插槽位置,接口名可能跟着变。多网卡场景下,建议通过ifcfg-ens33里的HWADDR(MAC 地址)字段来固化配置,而不是依赖接口名。
8.3 备份驱动模块
编译好的驱动模块是个二进制文件,重装系统后就没了。建议把编译好的.ko文件单独备份一份到 U 盘或内网存储,省得下次装系统后又要重新编译。备份的版本要和新内核匹配,内核大版本变了就不适用了。
8.4 关于第三方驱动和 SELinux 的兼容性
CentOS 7 默认开启 SELinux,在加载第三方驱动模块时,SELinux 对内核模块的加载限制实际上比较宽松,一般不会阻止 root 用 modprobe 加载驱动。但如果你手动把模块文件放到非标准目录下,或者从自定义路径加载,有可能触发 SELinux 的 AVC 拒绝记录。如果驱动加载失败,可以查一下/var/log/audit/audit.log,看到 AVC 相关记录再针对性处理。
大多数情况下,把模块安装到标准目录、用 modprobe 加载,SELinux 不会干预。
8.5 关注厂商驱动的新版本动态
芯片厂商的驱动会持续修复 bug 和兼容性问题。特别是新内核出来后,旧驱动往往需要更新才能支持。建议定期看看网卡芯片官方的驱动发布记录,有更新的版本时评估一下要不要升级。生产环境尽量少动,但如果当前版本有问题,升级前记得先备份旧模块,升级后多留意 dmesg 有没有新报错。
我的几点实操体会
写到这里,整个 CentOS 7 网卡驱动的安装流程就完整了。最后分享几个我自己的体会:
第一,网卡驱动安装的难点不在编译本身,而在定位“系统为什么不认这块卡”。lspci 和 dmesg 这两个命令用熟了,问题就解决了一半。
第二,编译之前一定要确认 kernel-devel 和当前内核版本一致。我见过太多人在这一步栽跟头,装了一堆依赖之后编译还是报错,最后发现是 kernel-devel 版本对不上。
第三,CentOS 7 的这个老内核确实让不少新硬件用户头疼。如果条件允许,不如直接考虑用更新版本的系统,硬件兼容性会好很多。但如果业务系统已经锁定在 CentOS 7,手动装驱动这条路还是得会。
第四,给服务器配置网络时,尽量把网卡 MAC 地址和接口名的对应关系记下来,特别是多网卡设备。免得哪次重启之后接口顺序变了,发现业务断了却找不到原因。
这几条经验是我多次处理网卡问题后沉淀下来的,希望对你有帮助。如果实际操作中遇到没覆盖到的情况,先沉住气看日志,网卡驱动的问题没有一个是无解的。