首页 / 资讯中心 / 文章详情

CentOS7网卡识别不到:lspci、dmesg与驱动编译全链路排查

CentOS7网卡识别不到:lspci、dmesg与驱动编译全链路排查 ★ FEATURED ARTICLE
CentOS7 网络问题里识别不到网卡大概是最让人上火的一类机器就摆在眼前网口灯也亮着插了线敲下ip addr却只看到一个 lo 回环eth0 或者 ens33 连影子都没有。更气人的是同样一块卡装在别的系统上活蹦乱跳偏偏在 CentOS7 上像没插一样。这个问题横跨物理层、总线枚举、内核驱动、固件、udev 命名、NetworkManager 接管好几个层面任何一个环节断了你在用户态看到的结果都是没网卡。这篇就把我这些年在这件事上攒下的排查路径、驱动编译方法、以及各种克隆机、虚拟机、新硬件上的坑完整地摊开说一遍。不管你是刚装完 CentOS7 发现上不了网的新手还是接手了一堆老服务器、被 25G 网卡和新无线网卡折磨的老运维都能从里面找到能直接抄的步骤。文章偏实操命令基本可以照敲参数我会说明为什么这么定不讲空话。1. 先分清网卡不存在和网卡没启用这两件事1.1 从内核到 nmcli网卡要走过四道关卡很多人一上来就改 ifcfg 文件、重启 network 服务其实方向从一开始就错了。一块网卡能被你正常用起来中间要经过四个独立阶段每道关卡挂掉的表现都叫没网卡但修法完全不同。第一道是 PCI 总线枚举。主板或虚拟化平台把设备挂到总线上内核在启动早期扫描 PCI 配置空间这一步过了lspci才能看到设备的厂商 ID 和设备 ID。第二道是驱动 probe内核找到匹配的驱动模块绑定上去创建一个net_device结构这一步过了才会有eth0这种网络接口。第三道是 udev 重命名systemd-udevd 根据一致性命名规则把内核给的临时名字改成ens33、enp3s0这类可预测名字。第四道才是用户态管理工具NetworkManager 或者老的 network-scripts 把它拉起来、配上 IP。这四道关卡里前两道断了ip link里连设备都没有第三道断了设备在但名字和你 ifcfg 文件对不上第四道断了设备在、名字对但状态是 DOWN 或者 unmanaged。判断清楚卡在哪一层后面就不用瞎试了。1.2 三步定位法三条命令锁定问题层级我习惯用三条命令做第一轮筛选基本十秒钟就能知道该往哪个方向走。# 第一层内核有没有枚举到这个设备 lspci -nn | grep -i -E ethernet|network controller # 第二层内核日志里驱动有没有绑定成功 dmesg -T | grep -iE eth|enp|firmware|link is | tail -30 # 第三层用户态接口状态 ip -br link show nmcli device status把结果对照下面这张表看基本就定位了。现象问题层级主要排查方向lspci 完全看不到设备硬件/虚拟化层插槽、供电、虚拟机网卡型号、PCI 直通配置lspci 能看到但没有 Kernel driver in use驱动层内核太老、驱动未编译、被 blacklist、固件缺失有网卡但叫 eth1 而不是 ens33命名层udev 规则残留、MAC 变化、ifcfg 文件不匹配名字正确但状态是 DOWN/unmanaged配置层ONBOOT、NM_CONTROLLED、NetworkManager 接管状态ip link里有但nmcli里没有服务层NetworkManager 未运行或该设备被标记 unmanaged提示nmcli device status这一条特别值得看它会直接告诉你设备是 connected、disconnected 还是 unmanaged。unmanaged 基本就是 NetworkManager 不认它去翻/etc/NetworkManager/NetworkManager.conf里的no-auto-default或者 ifcfg 里的NM_CONTROLLEDno。1.3 一个绕不开的前提CentOS7 已经停止维护了这件事必须先说因为太多人卡在第一步。CentOS 7 在 2024 年 6 月 30 日结束了生命周期官方的 mirrorlist 已经不再更新你直接yum install kernel-devel大概率一堆 404。而编译网卡驱动偏偏必须要 kernel-devel还是必须和当前内核版本严格一致的那个版本。所以动手之前先把源改到 vaultsed -i s/^mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-*.repo sed -i s|^#baseurlhttp://mirror.centos.org|baseurlhttp://vault.centos.org|g /etc/yum.repos.d/CentOS-*.repo yum clean all yum makecache改完先验证一下yum repolist能列出包再去装编译环境。这一步看着琐碎但它能省掉你后面一大半为什么 make 报错找不到头文件的困惑。顺带说一句如果你的场景不急实在没必要在新硬件上死磕 CentOS7 的 3.10 内核换更新内核的发行版会轻松很多但如果是存量老系统不能动那就老老实实往下看。2. 从总线开始确认硬件到底有没有被系统看见2.1 lspci 加 -nn把厂商 ID 和设备 ID 都揪出来排查任何网卡问题我第一步永远是lspci -nn。加-nn是为了同时看到数字 ID比如[8086:15b8]前面是厂商 ID8086 是 Intel后面是设备 ID。这两个数字是你后面查驱动、查兼容性的唯一可靠依据。lspci -nn | grep -i -E ethernet|network # 03:00.0 Ethernet controller [0200]: Intel Corporation I210 Gigabit Network Connection [8086:1533]看到设备了接着看驱动有没有挂上lspci -k | grep -A 3 -i ethernet正常输出里会有两行关键信息Kernel driver in use: igb表示驱动已经绑定成功Kernel modules: igb表示内核里存在这个驱动模块。如果只有Kernel modules没有Kernel driver in use说明模块存在但没绑定上常见原因是驱动版本不匹配、固件加载失败或者设备被别的驱动抢占了。如果lspci里压根看不到设备那问题就不在操作系统层面了。物理机去检查插槽、电源、BIOS 里的 PCIe 开关虚拟机去检查虚拟网卡是不是被删了、型号是不是选得太离谱。2.2 dmesg 是真相现场别只盯着 lspcilspci只告诉你设备在总线上dmesg才告诉你内核对这个设备做了什么。我一般这么过滤dmesg -T | grep -iE eth|enp|net|firmware|probe | less重点找三类信息。第一类是驱动 probe 成功会有igb 0000:03:00.0: added PHY / Intel(R) Gigabit Ethernet Network Connection。第二类是固件失败会明确写firmware: failed to load或者Direct firmware load for xxx.bin failed。第三类是资源冲突比如BAR 0: cant reserve这种一般是主板 BIOS 分配问题或者虚拟化平台的 PCI 直通没配好。注意dmesg -T的时间戳依赖系统时钟如果是刚开机、时间还没同步显示的时间会很怪别被误导看内容就行。2.3 虚拟机里的网卡型号选错了神仙难救CentOS7 跑在虚拟机里识别不到网卡九成是网卡型号和 Guest 内核的匹配问题。这块我用一张表整理一下常见组合省得每次翻文档。虚拟化平台网卡型号选项Guest 驱动模块说明VMware ESXi / Workstatione1000ee1000e兼容性最好CentOS7 原生支持VMwarevmxnet3vmxnet3半虚拟化性能好CentOS7 内置支持KVM / QEMUvirtiovirtio_net首选CentOS7 内置KVM / QEMUe1000e1000兼容模式性能一般Hyper-V网络适配器默认hv_netvscCentOS7 内置需要较新版本Proxmox VEVirtIO (半虚拟化)virtio_net装机时选它注意有些老 ISO 装完不认Proxmox VEIntel E1000e1000e最稳实在不行先用它装完系统再换真实踩坑最多的是 Proxmox VE。有人用 VirtIO 装 CentOS7装完ip addr只有一个 lo去虚拟机硬件里一看网卡是 VirtIO可系统里的 virtio_net 模块没加载。这时候要么把虚拟机网卡临时改成 Intel E1000 先把系统救回来要么解开模块。modprobe virtio_net echo virtio_net /etc/modules-load.d/virtio-net.conf至于 Hyper-VCentOS7 需要确认内核里带了 hv_netvsc 和 hv_utils老版本镜像可能没有得升级一次内核。3. 驱动与固件这才是大多数识别不到的真正原因3.1 内核模块加载机制先搞懂再动手Linux 网卡驱动本质是一个内核模块放在/lib/modules/$(uname -r)/kernel/drivers/net/下面。模块之间有依赖关系这些依赖记录在modules.dep文件里由depmod命令生成。你手动编译了一个驱动装进去如果不跑depmod -amodprobe就找不到依赖加载会失败。另外还有个关键点是 initramfs。如果你的根文件系统在网络存储上网卡驱动必须在 initramfs 阶段就加载否则系统起不来。普通场景下用 dracut 重新生成一次就行dracut -f --regenerate-all还有一个隐蔽的坑是 blacklist。有些发行版为了规避驱动冲突会在/etc/modprobe.d/下写黑名单比如把 r8169 拉黑好让 r8168 生效。你新装的驱动加载不上先查一下是不是被拉黑了。grep -rn blacklist /etc/modprobe.d/3.2 CentOS7 的 3.10 内核天生不认识很多新网卡CentOS7 用的是 3.10 内核虽然有大量 backport但面对近几年出的硬件确实力不从心。下面这些是平时问得最多的几类。网卡类型驱动模块CentOS7 3.10 是否内置建议方案Realtek RTL8111/8168 千兆r8169 / r8168r8169 内置但稳定性一般装 r8168 厂商驱动并拉黑 r8169Realtek RTL8125 2.5Gr8169新版默认不支持装厂商驱动或升级内核Intel I210/I350 千兆igb支持直接可用Intel X520/X540 万兆ixgbe支持直接可用Intel X710/E810 万兆i40e / icei40e 部分支持ice 不支持装厂商驱动或 elrepo 内核Intel AX200/AX201 无线iwlwifi不支持内核版本过低需 5.x 内核建议换系统Mellanox ConnectX-4/5 25Gmlx5_core7.3 以后部分支持更新系统或装厂商驱动Netronome Agilio CX 25Gnfp不支持主线 4.10 才进必须用厂商驱动看到这张表你应该能理解为什么有人拿着刚买的 AX201 无线网卡装 CentOS7折腾一整天都搞不定——不是操作问题是内核底子不支持。这种情况下硬扛的意义不大要么上 elrepo 的 kernel-ml要么换个系统。对于 Realtek 千兆这类elrepo 里有现成的 kmod 包能省掉自己编译的麻烦rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm yum --enablerepoelrepo install -y kmod-r8168装完它会自动处理 blacklist重启后lsmod | grep r8168能看到模块就对了。3.3 离线编译网卡驱动的完整流程厂商官网下载的驱动一般是 tar 包里面带 Makefile。编译最经典的两个失败原因是kernel-devel版本对不上以及缺少elfutils-libelf-devel。完整的流程我按顺序写一遍。# 1. 确认当前内核版本 uname -r # 3.10.0-1160.el7.x86_64 # 2. 装编译依赖注意 kernel-devel 必须跟 uname -r 完全一致 yum install -y gcc make \ kernel-devel-$(uname -r) \ kernel-headers-$(uname -r) \ elfutils-libelf-devel # 3. 验证 /lib/modules/$(uname -r)/build 软链接存在 ls -ld /lib/modules/$(uname -r)/build ls -d /usr/src/kernels/$(uname -r) # 4. 解压并编译 tar -xvf driver.tar.gz cd driver/src make clean make -j$(nproc) # 5. 安装并更新依赖 make install depmod -a # 6. 加载模块 modprobe igb lsmod | grep igb如果第 2 步报没有可用软件包 kernel-devel-3.10.0-xxx说明 vault 源里没有这个精确版本通常是因为你系统更新过内核但没重启运行内核和已安装内核不一致。解决办法是重启到当前已安装的最新内核再装对应版本。3.4 用 DKMS 让驱动跟着内核升级走手动make install有个后遗症内核一升级老模块就失效了你还得重新编译一遍。生产环境更推荐 DKMS 方式它会在内核更新时自动重新编译。yum install -y epel-release yum install -y dkms # 把驱动源码放到规范目录 mkdir -p /usr/src/mydriver-1.0 cp -r driver/* /usr/src/mydriver-1.0/ # 在源码根目录写一个 dkms.conf指定模块名和版本 cat /usr/src/mydriver-1.0/dkms.conf EOF PACKAGE_NAMEmydriver PACKAGE_VERSION1.0 BUILT_MODULE_NAME[0]igb DEST_MODULE_LOCATION[0]/kernel/drivers/net/ethernet/intel/igb AUTOINSTALLyes EOF dkms add -m mydriver -v 1.0 dkms build -m mydriver -v 1.0 dkms install -m mydriver -v 1.0 dkms statusdkms status显示 installed 就成功了。这套流程在批量部署时特别省心不用每次内核更新都去重编。3.5 固件缺失dmesg 里那句 failed to load 千万别跳过有些网卡驱动模块加载成功了设备也出现了但功能不正常。这时候去 dmesg 里搜 firmware经常能看到Direct firmware load for iwlwifi-xxx.ucode failed with error -2。这表示驱动缺少固件文件固件放在/lib/firmware/目录下。处理方式有两种。系统自带的固件包直接装yum install -y linux-firmware厂商单独提供的固件文件手动拷进去再重新加载模块cp xxx.bin /lib/firmware/ modprobe -r igb modprobe igb提示modprobe -r卸载模块前先确认没有接口在用接口是 UP 状态会卸不掉。先ip link set ens33 down再卸载。4. 网卡明明在为什么 ip addr 里没有命名与配置的坑4.1 一致性网络设备命名规则到底在改什么CentOS7 默认启用了 Consistent Network Device Naming网卡名字不再是简单的 eth0而是根据 PCI 位置、固件索引等信息生成比如 eno1板载、ens33PCI 热插拔槽位、enp3s0PCI 总线位置。这套规则由 systemd-udevd 在启动时执行具体逻辑在/usr/lib/udev/rules.d/下的 net_id 相关文件里。问题是这个名字是算出来的硬件位置一变名字就变。虚拟机克隆、物理机换插槽、主板固件更新都可能导致 ens33 变成 ens34。而你的 ifcfg 文件还叫ifcfg-ens33系统里又没这个设备NetworkManager 自然拉不起来你看到的就是没网卡。另外还有一种情况是从 CentOS6 升级或者用了某些第三方镜像系统里残留了/etc/udev/rules.d/70-persistent-net.rules。RHEL7 以后这个机制已经被 systemd 取代残留文件会和新规则打架通常直接删掉就行。ls /etc/udev/rules.d/70-persistent-net.rules rm -f /etc/udev/rules.d/70-persistent-net.rules4.2 改回传统 eth0 命名的操作有些老脚本、老监控系统硬编码了 eth0改不动。这时候可以在内核启动参数里关掉一致性命名。# 编辑 /etc/default/grub在 GRUB_CMDLINE_LINUX 里加上 # net.ifnames0 biosdevname0 # BIOS 引导 grub2-mkconfig -o /boot/grub2/grub.cfg # UEFI 引导 grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg reboot重启后网卡就变回 eth0 了。但要注意改名前先把原来的 ifcfg 文件重命名不然新名字没有配置文件还是上不了网。4.3 ifcfg 文件和 NetworkManager 的配合网卡名字对了还得配置对。一个能用的 ifcfg 文件大概长这样TYPEEthernet BOOTPROTOstatic DEVICEens33 ONBOOTyes IPADDR192.168.1.100 PREFIX24 GATEWAY192.168.1.1 DNS1223.5.5.5 NM_CONTROLLEDyes几个容易出错的点。ONBOOTyes决定开机是否拉起很多人复制模板的时候忘了改结果每次重启都没网。HWADDR和UUID这两个字段在克隆场景下会引发问题因为新虚拟机的 MAC 和 UUID 都变了配置里还写着旧的NetworkManager 匹配不上就跳过。我的建议是如果不是有特殊需求直接把这两行删掉让系统按 DEVICE 名字匹配。改完重载nmcli connection reload nmcli connection up ens33 ip addr show ens334.4 服务状态和开机自启别忽略CentOS7 里有两套网络管理服务NetworkManager 和老的 network。默认用 NetworkManager但两套同时开着会互相打架。先确认状态systemctl status NetworkManager systemctl status network如果 NetworkManager 没启动systemctl enable --now NetworkManager如果发现 network 服务也在跑建议停掉并禁用避免冲突systemctl stop network systemctl disable networknmcli device status里如果显示 unmanaged除了 ifcfg 里的NM_CONTROLLEDno还要检查/etc/NetworkManager/NetworkManager.conf里是不是有no-auto-default之类的配置把设备排除了。5. 几个真实场景的复盘5.1 场景一VMware 克隆 CentOS7 后网卡消失这个场景太经典了。用模板克隆出来的虚拟机开机后ip addr只有一个 lolspci能看到 e1000enmcli device status里有个 ens33 但是 disconnected甚至有的直接显示 ens34。根因是两条。第一克隆后虚拟机 MAC 变了ifcfg 里残留的HWADDR跟新 MAC 对不上NetworkManager 直接跳过这个连接。第二如果模板里还有 70-persistent-net.rulesudev 会按旧规则给新网卡重新编号。处理步骤# 1. 定位 nmcli device status ip -br link show # 2. 看看实际接口名是不是变了 ls /etc/sysconfig/network-scripts/ifcfg-* # 3. 如果接口名变了重命名配置文件 mv /etc/sysconfig/network-scripts/ifcfg-ens33 \ /etc/sysconfig/network-scripts/ifcfg-ens34 # 4. 编辑文件删掉 HWADDR 和 UUID把 DEVICE 改成新名字 # 5. 重载 nmcli connection reload nmcli connection up ens34实操心得做虚拟机模板的时候养成一个习惯——封装前把/etc/sysconfig/network-scripts/ifcfg-*里的 HWADDR、UUID 删干净把/etc/udev/rules.d/70-persistent-net.rules删掉把 ifcfg 里的 ONBOOT 设成 yes。这三步做完的模板克隆出来基本百分之百能直接用。5.2 场景二物理机换 PCIe 插槽后接口名变了有一台老服务器机箱清理的时候把网卡从 PCIe x8 槽挪到了另一个槽开机后运维反馈网卡没了。lspci能看到设备驱动也挂了但接口名从 enp3s0 变成了 enp5s0。这就是一致性命名的正常行为——名字里带了总线位置。解决办法要么改配置文件名字要么用 udev 规则把名字固定住。生产环境更推荐固定名字位置怎么变都不影响。# 查 MAC ip link show enp5s0 # 写一条固定命名规则 cat /etc/udev/rules.d/80-net-name-slot.rules EOF SUBSYSTEMnet, ACTIONadd, ATTR{address}00:25:90:xx:xx:xx, NAMElan0 EOF # 重新生成 initramfs 并重启 dracut -f固定命名之后ifcfg 文件统一用 lan0以后再动硬件就不用改了。5.3 场景三Proxmox VE 上跑 CentOS7桥接配好了但虚拟机里没网卡Proxmox VE 本身基于 Debian桥接配置在宿主机侧。虚拟机里看不到网卡八成是虚拟机网卡型号和 CentOS7 镜像的匹配问题。我见过最多的组合是虚拟机网卡选 VirtIO但用的 CentOS7 最小化安装镜像里 virtio_net 没被自动加载因为安装了精简内核。排查顺序是先在宿主机确认桥接正常# PVE 宿主机 cat /etc/network/interfaces ip -br link show vmbr0确认 vmbr0 存在且绑定了物理网卡。然后在虚拟机里检查模块lsmod | grep virtio modprobe virtio_net如果加载后接口出现就把它写进模块自动加载配置里。实在折腾不出来就把虚拟机网卡临时换成 Intel E1000先让系统能联网再用 yum 补装 virtio 相关的包。5.4 场景四给老服务器装了一块新的 25G 网卡25G、40G 这类高速网卡在 CentOS7 上识别不到的概率非常高因为驱动往往是后进主线的。以常见的情况来看Mellanox 的 ConnectX-4/5 需要 mlx5_coreNetronome 的 Agilio CX 需要 nfp 驱动这两个在 3.10 内核里要么没有要么版本太老。这类场景我的建议很直接不要在原系统上硬塞驱动。两条路一是升级到 elrepo 的 kernel-ml代价是系统内核大变可能影响上面跑的数据库和中间件二是找厂商要适配 CentOS7 的驱动包用 DKMS 方式装进去。yum --enablerepoelrepo-kernel install -y kernel-ml # 装完把默认启动项切到新内核 grub2-set-default 0 grub2-mkconfig -o /boot/grub2/grub.cfg换内核之前一定要做快照或者备份尤其是跑着业务的机器。6. 排查速查表与避坑清单6.1 现象、原因、处理对照表现象最可能的原因处理方式lspci 看不到设备插槽/供电/虚拟机网卡被删检查物理连接、BIOS、虚拟化平台硬件列表lspci 有但无驱动绑定内核无对应驱动编译厂商驱动或换内核dmesg 报 firmware failed固件缺失装 linux-firmware 或手动拷贝固件接口名与配置文件名不符一致性命名变化重命名 ifcfg 或固定 udev 规则接口存在但 nmcli 显示 unmanagedNM_CONTROLLEDno 或 NM 配置排除改 ifcfg、检查 NetworkManager.conf重启后网卡消失ONBOOTno改成 yes 并重载连接克隆机网卡全没MAC/UUID 残留、udev 规则残留删 HWADDR/UUID删 70-persistent-net.rules模块加载报未知符号驱动与内核版本不匹配用 uname -r 对应版本的 kernel-devel 重编6.2 我自己踩过的几个坑第一kernel-devel装完之后/lib/modules/$(uname -r)/build软链接还是断的。原因通常是 update 过内核但没重启uname -r还是旧内核而 yum 装的是新内核的 devel。这时候重启一次让运行内核和已安装内核对齐问题就没了。第二编译 Realtek 驱动的时候忘了拉黑 r8169装完 r8168 也没生效因为 r8169 先一步抢占了设备。正确做法是在/etc/modprobe.d/下加一行blacklist r8169再重新生成 initramfs。这个坑我至少踩过三次。提示modprobe -r r8169卸载当前模块后立刻modprobe r8168可以先验证新驱动能不能起来确认没问题再写黑名单和重建 initramfs避免配置写错导致彻底没网。第三虚拟机里改完配置忘了nmcli connection reload直接用systemctl restart network结果因为 network 服务被禁用了配置根本没重新读。CentOS7 里 NetworkManager 和 network 服务混用的场景特别容易出这种问题统一用 nmcli 操作会省很多事。第四网卡驱动装好了、IP 也配上了但 ping 不通最后一查是接口被设置成混杂模式没关或者交换机侧端口配置了端口安全。识别不到网卡和连不通是两回事前者看的是ip link后者要看ip addr、路由表和交换机侧配置。再补一个排查顺序上的建议永远从下往上查先lspci再dmesg再ip link最后才动配置。我见过太多人直接从改 ifcfg 开始改了半天发现网卡根本没被内核识别到白忙活。层级判断清楚了每一步都是有的放矢。最后还是说句掏心窝的话CentOS7 这套老内核配新硬件本身就是逆水行舟。如果你手头的机器是近几年新采购的尤其是带 2.5G 以上网卡、新无线网卡的能换系统就换别把时间浪费在驱动编译和内核 backport 上。真正需要死守 CentOS7 的往往是跑着老业务、不能停机的那批机器那种场景下我会先做完整快照再把驱动和黑名单一点点调宁可慢也不要一次改动太大把机器搞到彻底上不了网——毕竟远程运维的时候网卡一断你就只能去机房了。
阅读完成 · 觉得有帮助?
咨询建站