银河麒麟高级服务器V10 SP2上装Intel E810-C 100G网卡,这个事听起来就是“下载源码、make、install”三步走,但真干起来才知道坑在哪。我前两天刚在自己负责的服务器上把这套流程完整跑通,从系统不认卡到驱动装完跑满100G线速,中间踩了不少坑,今天把整个过程整理出来,给同样在国产系统上折腾高速网卡的朋友一个参考。
这个场景其实很典型:银河麒麟V10 SP2作为服务器操作系统,搭配Intel E810-C这种100G网卡,常见于数据中心、高性能计算、视频处理和高速存储网络环境。E810-C本身是Intel的百G网卡,底层驱动叫ice,内核模块是ice.ko。但银河麒麟V10 SP2自带内核里的ice驱动版本往往比较旧,对新固件和某些特性支持不全,甚至在某些情况下会直接识别不到网卡。所以说白了,装驱动这事,本质上是在解决“系统内核和网卡固件之间的适配问题”。
这篇东西适合谁看?两类人:一类是刚接触国产服务器操作系统、被驱动问题卡住的新手,照着步骤抄作业就行;另一类是在生产环境里做网络基础设施的老手,可以参考一下我在性能调优和固件匹配上的处理思路,少走点弯路。
1. 开始之前:先把场景和前置条件说清楚
1.1 银河麒麟V10 SP2和E810-C是什么组合
银河麒麟高级服务器操作系统V10 SP2,是麒麟软件面向服务器场景推出的企业级Linux发行版,内核基于4.19版本,x86架构下对CentOS 8 / RHEL 8的二进制兼容性做得比较好,很多为RHEL 8编译的软件包可以直接在它上面运行。这一点很重要,因为后面找依赖包、找驱动,很多都能从el8的源里找到线索。ARM架构的飞腾、鲲鹏版本也有,但Intel E810网卡主要用在大规模x86服务器上,所以本文以x86_64环境为基准展开,ARM版的操作思路类似,但工具链和包管理器细节会略有差异。
Intel E810-C是Intel 800系列以太网控制器家族的一员,属于面向数据中心和云计算的100G网卡。常见型号有E810-CQDA1双口和E810-CQDA2四口等变体,物理接口通常是QSFP28,支持100G/50G/25G/10G多种速率自适应。它的驱动叫ice,由Intel官方维护,主线内核里也有自带版本,但自带的版本更新慢,对新固件和高级特性的支持不全。更关键的是,E810-C这种网卡依赖固件(NVM)和驱动紧密配合,固件太旧、驱动太新,或者反过来,都会出现链路起不来、报错风暴这类问题。
1.2 系统可能识别不到网卡的几个原因
很多朋友拿到机器,插上网卡,发现ip link里根本没有新网卡,第一反应就是驱动没装。但驱动没装上只是表面现象,底下的原因有几个层次。
第一,内核里确实没有对应的ice驱动模块。银河麒麟V10 SP2默认内核虽然带了ice驱动,但有些定制内核或最小化安装环境下,相关模块可能没被编译进去。第二,系统里有ice模块,但版本太老,而网卡固件已经更新过,两者不匹配,导致驱动加载失败或网卡初始化异常。第三,更隐蔽的问题——PCIe枚举阶段没认出设备,这往往跟BIOS设置、PCIe槽位带宽、或者SR-IOV、电源管理等选项有关。
我在实际排障中遇到过一种情况:网卡插在PCIe插槽上,lspci能看见设备ID,但dmesg里报ice: probe failed,这种八成就是NVM固件和驱动对不上。所以在动手装驱动之前,先把“系统看没看到硬件”这件事弄清楚,能省掉后面一大半的排查时间。
1.3 驱动安装的整体思路和选型
说下整体思路。银河麒麟V10 SP2上装E810-C驱动,不推荐直接改内核源码重新编译,也不推荐用那种“万能驱动安装包”。正确路线是:确认系统版本和内核版本,确认网卡在PCIe层能被识别,准备好编译环境,然后从Intel官方获取ice驱动源码和最新NVM固件更新工具,编译安装驱动、核对固件版本,最后做链路验证和中断队列调优。
至于为什么选编译源码而不是用rpm包,我个人的经验是:银河麒麟虽然兼容RHEL 8,但毕竟不是100%的克隆,直接用RHEL 8的kmod包偶尔会遇到内核模块版本校验不一致的情况。源码编译虽然多花几分钟,但可控性高,出了问题也容易定位。
2. 安装前的环境准备:这几步不做好,后面全是坑
2.1 确认系统版本、内核版本和网卡识别状态
先别急着下载驱动,把系统信息摸清楚。需要确认三样东西:操作系统版本、内核版本、网卡是否在PCIe层被识别到。命令分别如下:
cat /etc/os-release uname -r lspci | grep -i ethernetcat /etc/os-release的输出会显示系统是Kylin V10 SP2,uname -r会给出当前内核版本,比如4.19.90-52.22.v2207.ky10.x86_64。而lspci | grep -i ethernet这行最关键,如果能看到类似Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP的设备项,说明硬件层面已经被识别了,后面只要搞定驱动就行。如果这里什么都看不到,那就先别急着装驱动,回BIOS里看PCIe设备是否启用、插槽是否工作正常。
我遇到过一个有意思的情况:网卡插在PCIe x16插槽上,但BIOS里这个槽被设置成拆分模式,导致网卡只能以x4链路训练,虽然能识别但跑不满速。这种硬件配置层面的问题,不是驱动能解决的,提前检查能避免后面做白工。
2.2 准备编译环境和内核开发包
编译ice驱动需要gcc、make,以及和当前运行内核完全匹配的kernel-devel。这一步看起来简单,但踩坑率特别高。很多朋友直接yum install kernel-devel,装出来的是仓库里默认版本,跟当前uname -r的内核版本不一致,结果编译时头文件路径对不上,报一堆奇奇怪怪的错误。
正确做法是指定版本安装:
yum install -y gcc make yum install -y kernel-devel-$(uname -r)注意,执行完uname -r后,要确认kernel-devel-$(uname -r)这个包在源里真实存在。如果提示找不到,先执行yum list available | grep kernel-devel看看有哪些版本可用,再手动指定。装完之后务必验证一下:
ls /usr/src/kernels/$(uname -r)如果这个目录存在,且里面有include、Makefile这些文件,说明开发环境就绪。还有个小坑:银河麒麟的默认源里kernel-devel的包名有时叫kernel-devel,有时叫kernel-headers,后者是头文件包,不能替代前者,别搞混了。
2.3 关闭可能会干扰安装的组件
编译安装驱动期间,有些系统组件可能会捣乱。比如dkms,如果系统里装了dkms并且自动管理内核模块,可能会出现新旧模块混用的情况。还有modprobe的黑名单机制,如果/etc/modprobe.d/下有人把ice加入了黑名单,那驱动编译好也加载不上。
建议装驱动之前先查一下:
ls /etc/modprobe.d/ grep -r "blacklist ice" /etc/modprobe.d/ 2>/dev/null如果发现黑名单文件里有ice相关条目,直接把对应行注释掉或删掉,否则后面modprobe ice会静默失败,特别坑。另外,如果系统里已经加载了老版本的ice驱动,先记下它的版本,后面装新版本的时候需要先卸载或者覆盖,这在第4章会详细讲。
3. 驱动安装实操:从头到尾完整跑一遍
3.1 获取驱动源码和固件更新工具
这一步是很多人卡住的点。Intel的驱动源码在官方支持网站有下载,搜索“Intel Ethernet Adapter Complete Driver Pack”或者直接在下载中心找ice驱动对应的Linux版本。下载下来是一个tar.gz包,文件名通常是ice-x.y.z.tar.gz这样的格式。解压:
tar zxvf ice-*.tar.gz cd ice-*这里强调一下:E810-C的驱动和固件是两个东西。驱动是ice内核模块,负责数据通路;固件(NVM)运行在网卡内部,负责物理层协商和管理。Intel官网有专门的NVM更新工具,针对E810系列的是nvmupdate,也需要一并下载。旧固件搭配新驱动,最常见的现象是链路能起来,但跑几十分钟就断一次,dmesg里报Link Down事件。
另外留意一下网卡具体型号,E810-CQDA1和E810-CQDA2在固件包上可能有区分,下载时选对型号,别用错固件。
3.2 编译安装ice驱动
解压后进到源码目录,先看README,然后按标准流程编译安装:
cd src make make install编译过程中如果没有报错,make install会把ice.ko安装到/lib/modules/$(uname -r)/updates/目录下。安装完成后,执行:
depmod -a modprobe icedepmod -a会重建模块依赖关系,这一步千万别省。加载成功后,用lsmod | grep ice确认模块已加载,再用dmesg | tail -50看看有没有异常报错。正常的日志会显示ice: Intel(R) Ethernet Connection E810-C successfully loaded之类的字样,并打印出网卡的固件版本。
这里有个常见问题:如果系统之前加载过旧的ice模块,modprobe ice可能会因为模块已被占用而加载失败。稳妥的做法是先卸载旧模块再加载新的:
rmmod ice modprobe ice如果rmmod提示Module ice is in use,说明有网卡接口正被系统占用,需要先把对应的网卡接口down掉,比如ip link set enp3s0 down,再执行rmmod。
3.3 固件(NVM)核对与更新
驱动装好后,第一时间核对固件版本。用ethtool -i查看驱动和固件信息:
ethtool -i enp1s0输出里会显示driver: ice、version: x.y.z、firmware-version: x.x.x。去Intel官网查一下当前网卡最新的NVM版本,如果固件版本落后太多,建议更新固件。NVM更新工具的用法一般是解压后以root权限运行:
tar zxvf nvmupdate_100g_linux_x64_*.tar.gz cd nvmupdate_100g_linux_x64_* ./nvmupdate64e工具会扫描系统里的Intel网卡,列出当前固件版本,然后提示是否更新。更新过程中千万别断电,也别重启,否则网卡可能变砖。更新完成后需要关机断电再开机,只重启不一定生效,这是Intel网卡的惯例。
E810-C这个卡还有个值得注意的地方:100G速率下对PCIe带宽要求很高,如果插在PCIe 3.0 x8的槽位上,带宽只有约64Gbps,跑不满100G线速。固件更新工具和ethtool -p都能确认链路宽度,建议顺手检查一下:
lspci -vvv -s 01:00.0 | grep -E "LnkCap|LnkSta"看到LnkSta: Speed 16GT/s, Width x16就说明PCIe链路是OK的。如果只是x8,那物理层面的带宽瓶颈是目前驱动解决不了的。
3.4 加载驱动并完成基础网络配置
驱动加载成功后,ip link应该就能看到新网卡了,接口名一般是enpXsX这种格式。在银河麒麟V10 SP2上配置IP,可以用nmcli也可以用传统配置文件。我用的是nmcli,因为麒麟默认启用了NetworkManager:
nmcli con add type ethernet con-name eth100 ifname enp1s0 ipv4.method manual ipv4.addresses 192.168.10.10/24 nmcli con up eth100要注意,如果这张网卡之前被NetworkManager或者systemd-networkd接管过,直接加连接配置可能会报“设备已被管理”的错。先执行nmcli device status看一下网卡状态,如果显示unmanaged,需要先删掉旧的连接配置或者把/etc/sysconfig/network-scripts/ifcfg-*里对应的文件清理干净。
配置完成后,ping一下对端验证基础连通性。这里有个实用的检查命令:
ip -s link show enp1s0这个命令能看收发包统计。如果发现RX errors、TX errors一直在涨,说明链路质量有问题,可能是光模块、光纤或者固件设置的问题,这个后面会细说。
4. 安装后的验收与性能调优:驱动装上只是开始
4.1 确认链路速率和双工模式
装好驱动、链路起来之后,第一步先确认链路协商的实际速率。E810-C支持100G/50G/25G/10G,实际速率取决于光模块和对端设备。用ethtool查看:
ethtool enp1s0输出里的Speed和Duplex会显示实际的协商结果。比如Speed: 100000Mb/s、Duplex: Full。这里就会暴露很多问题:明明插的是100G模块,链路只协商到25G,常见原因包括光纤跳线类型不对、对端端口速率配置限制、或者光模块本身是拆分的(比如100G通过4x25G breakout模式)。还有一个坑:QSFP28端口上用了一些兼容性不好的第三方模块,链路训练困难,会出现反复up/down。
4.2 队列、中断和环形缓冲区调优
E810-C这种100G网卡,默认配置往往没把性能吃满,特别是CPU核数充足的服务器上,默认只有几个队列在跑,很容易把单个CPU核打满。检查当前队列数:
ethtool -l enp1s0看Combined字段的当前值和最大值。如果当前值远小于最大值,就可以调。我在服务器上普遍把队列数设置成和CPU物理核数一致(注意不是逻辑线程数,要排除超线程)。调整命令:
ethtool -L enp1s0 combined 32调整之后,再看看中断亲和性。ice驱动默认会自动做中断和CPU绑定,但有时候在虚拟机里驱不起来,需要手动设置。还有个关键点:环形缓冲区(ring buffer)大小。默认情况下,ring buffer可能只有1024或者更小,100G流量下丢包会很严重。我一般会调大一点:
ethtool -G enp1s0 rx 4096 tx 4096调完之后用ethtool -S enp1s0 | grep -E "rx_dropped|tx_dropped"观察丢包是否下降。注意,环形缓冲区不是越大越好,太大会增加延迟,对延迟敏感的业务要折中。
4.3 用工具验证实际吞吐
配置全部就绪之后,用iperf3做收发吞吐测试,这是最直观的验收手段。两端各准备一台服务器,一端跑服务端一端跑客户端:
# 服务端 iperf3 -s # 客户端 iperf3 -c 192.168.10.20 -P 8 -t 60-P 8表示用8个并行流。如果两端CPU足够强、PCIe链路正常,吞吐跑到90Gbps以上基本就算达标。注意,iperf3默认单线程可能跑不满100G,必须用多流。另外,如果吞吐明显偏低但链路速率正常,先查CPU中断是不是集中在一个核上,mpstat -P ALL 1看一下,哪颗核软中断占用高,就把网卡中断往那边绑。很多时候,百G网卡跑不满速,不是网卡不行,是CPU处理不过来。
5. 常见问题与排查技巧实录
5.1 编译报错:找不到头文件或版本不匹配
这是最高频的报错。症状是make的时候提示Kernel header files not found或者linux/version.h: No such file or directory。原因基本都是kernel-devel没装对。排查思路是先确认uname -r和/usr/src/kernels/下的目录名是否一致,不一致就给yum install kernel-devel-$(uname -r)。如果源里实在没有对应的版本,还有一个临时方案:修改源码里Makefile,把KSRC路径指到实际存在的内核头文件目录。但这个方案只建议应急测试用,生产环境还是要装匹配的kernel-devel。
另外一个比较容易忽略的点:gcc版本太旧。银河麒麟V10 SP2自带的gcc是8.x,一般够用。但如果是从老系统升级上来的环境,gcc版本可能在4.8左右,新版本ice驱动源码用了C11语法,编译必挂。遇到这种情况,升级gcc或者装高版本的devtoolset工具链就行。
5.2 驱动加载失败:module loading error或probe failed
驱动编译安装好了,但modprobe ice报错,或者加载成功但dmesg里有ice: probe failed,这个就得仔细看日志。probe failed一般是网卡初始化和固件通信失败,原因通常是NVM固件版本和驱动不匹配。处理办法很简单:更新固件到Intel官网上的最新版本,或者反过来,下载和固件版本对应的旧版驱动。
还有一种情况:系统里同时存在多个ice模块。比如自己编译安装了一个,系统自带的也还在,modprobe加载了旧的那个。排查方法:
modinfo ice | grep filename看这个模块到底是从哪个路径加载的。如果路径不是/lib/modules/$(uname -r)/updates/,说明加载的是旧模块,需要手动把旧模块删掉,或者用insmod /path/to/new/ice.ko强制加载新模块。注意:先rmmod再insmod,避免两个模块同时存在的冲突。
5.3 链路反复up/down
装好驱动、配置好IP之后,发现链路一会通一会断,dmesg里刷Link is down、Link is up。这种问题,先怀疑光模块和光纤。E810-C这类数据中心网卡,对光模块的兼容性是有测试列表的,Intel官网上有推荐模块清单。有些杂牌光模块虽然能用,但信号质量差,长距离传输时误码率高,就会导致链路不稳定。
排障时可以试两个操作:一是把速率从100G固定到25G或10G试试,如果低速率下链路稳定,那基本可以确诊是光模块或光纤问题;二是用ethtool -m enp1s0查看光模块的DDM信息,包括光功率、温度、电压等。如果接收光功率在灵敏度临界值附近,大概率是光纤衰耗太大。
5.4 问题速查表
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| lspci看不到网卡 | BIOS未启用PCIe设备、插槽故障 | 进BIOS检查设备状态,换个插槽测试 |
| make报内核头文件缺失 | kernel-devel未安装或版本不匹配 | 安装kernel-devel-$(uname -r),确认路径存在 |
| modprobe ice提示模块占用 | 老版本模块已被使用 | ip link后续down所有ice接口,rmmod后重新加载 |
| 链路只能协商到25G | 光模块类型不匹配、对端端口限制 | 更换Intel兼容模块,检查对端配置 |
| 100G跑不满速 | PCIe带宽不足、CPU中断集中 | 检查PCIe链路宽度,调整队列数和中断亲和性 |
| 丢包严重 | ring buffer太小、CPU软中断瓶颈 | 调大rx/tx ring,调整CPU核绑核 |
| 频繁断连 | 光模块信号质量差、NVM版本旧 | 检查DDM光功率,更新固件到最新 |
5.5 一点独家心得:别忽略“模块签名校验”
银河麒麟V10 SP2有个跟普通CentOS不太一样的地方:内核可能启用了模块签名校验。如果编译安装的驱动模块没有正确签名,加载时会报Required key not available或者Module verification failed。这个坑官方文档提得少,但实际环境里真会遇到。
排查方法很简单:
tail -20 /var/log/messages | grep -i "key"如果看到签名相关的报错,解决方案有两个:一是用系统的签名工具对编译好的ice.ko做签名,二是干脆把Secure Boot关掉(如果是个人测试机的话)。生产环境还是建议走正规签名流程,安全性和合规性都有保障。我见过有人在这上面折腾了大半天,最后发现就是Secure Boot的问题。
还有一个细节:银河麒麟V10 SP2在某些硬件组合下,会因为ACPI表解析问题导致PCIe设备枚举不稳定,表现就是重启后网卡时而认得到时而认不到。这属于平台适配问题,建议先把BIOS和固件都升到官方最新版,再配合最新NVM固件和驱动,一般能解决。
最后再说两句
装E810-C驱动这个事,我前前后后在银河麒麟V10 SP2上折腾了不止一次。整体感受是:驱动本身不难装,难的是摸清系统、固件、硬件三者之间的匹配关系。Intel的网卡在Linux生态里的支持算比较好的,ice驱动更新也勤快,只要你愿意花时间把环境对齐,国产系统上跑100G完全没有问题。
我自己在实操中最深的体会,一是不要跳过固件版本核对这一步,很多隐蔽的链路问题都源于固件和驱动版本错配;二是编译环境一定要用与运行内核完全匹配的kernel-devel,这个能避免八成以上的编译报错。最后,如果生产环境要用,建议先在测试服务器上完整跑一遍驱动安装和压力测试,再上生产,别拿生产环境当实验场。
希望这篇东西能帮你少踩几个坑。如果你在银河麒麟上装E810-C遇到别的奇怪问题,也欢迎交流思路,集思广益总比自己死磕快一点。