1. 装这块卡之前,先弄清环境底细
提到银河麒麟高级服务器V10 SP2,很多从CentOS迁移过来的运维第一反应是“这不就是个换了皮的Linux吗”。这话对了一半,银河麒麟确实基于开源Linux生态构建,但SP2这个版本的内核、用户态组件和硬件兼容矩阵都有自己的脾气,尤其在面对100G这种高性能网卡时,不能想当然地拿Ubuntu那套思路硬套。
先说我这边的环境:一台双路服务器,CPU是Intel Xeon Gold 6330,主板自带PCIe 4.0插槽,系统是银河麒麟高级服务器V10 SP2,内核版本默认是4.19系列(具体小版本号在下面的命令里能看到)。网卡是Intel E810-C,也就是E810-CQDA2这块双口100G QSFP28型号。这块卡用的是Intel的Columbiaville芯片,驱动叫ice,这个驱动的来历和坑,后面会详细说。
在动手之前,我强烈建议你先执行下面这组命令,把环境底细摸清楚,别急着找驱动包:
# 查看系统版本和内核 cat /etc/kylin-release uname -r # 查看PCIe设备识别情况 lspci | grep -i ethernet # 看看内核里是否已经带了ice驱动模块 find /lib/modules/$(uname -r) -name "ice*" 2>/dev/null lsmod | grep ice为什么这一步很重要?因为E810-C这块卡在较新版本的内核里已经内置了ice驱动,如果你的系统内核版本足够新,根本不需要折腾官方驱动,modprobe ice就能直接拉起。但银河麒麟V10 SP2默认内核是4.19.x,这个版本的ice驱动比较老,对E810-C的某些功能支持不完整,而且容易出现加载后链路起不来、或者速率只有25G的怪问题。所以先看内核自带驱动是否存在、版本是多少,再做决定。
从我的实测来看,V10 SP2自带的4.19内核里确实有ice模块,但版本是老的(0.9.x还是1.x我记不清了,但肯定不是Intel官方最新的),而且没有配套的固件文件。这就意味着,就算你加载了模块,网卡也可能无法正常negotiate链路,或者ethtool能识别但发包就丢。这种情况下,老老实实走编译安装官方驱动的路子,反而最稳妥。
还有一点要注意:E810-C是支持RDMA的(RoCEv2),如果你想用InfiniBand类的应用或者需要DPDK,那就必须装Intel官方发布的ice驱动,并且还要配套装irdma模块。如果只是拿来当普通100G网口用,内核自带的驱动也能凑合,但为了性能和稳定性,我还是建议用官方驱动覆盖。
2. 三个可选方案,我为什么最终选了源码编译
针对银河麒麟V10 SP2装E810-C驱动,市面上的方案无外乎三种,我分别试过,这里直接说结论和适用场景。
2.1 方案一:直接用内核自带模块(适合内核≥5.7的系统)
如果你的系统内核已经升级到了5.7以上,那直接modprobe ice就能用。但银河麒麟V10 SP2默认内核是4.19,自带ice太老,而且没有配套的NVM更新工具。我在测试中发现,老版本ice加载后,虽然接口出现了,但是插上光模块后link始终是down的,ethtool看不到速率协商信息,明显是驱动和固件不匹配。这条路在SP2默认环境下基本走不通,除非你额外升级内核,但服务器生产环境升级内核的代价太大,不推荐。
2.2 方案二:用Intel官方预编译的RPM包(适合纯内网、没有编译环境的机器)
Intel官方发布驱动时,除了源码包,也会提供编译好的RPM文件,包括ice、irdma等。理论上你可以直接rpm -ivh装上去。但问题在于,这些RPM包通常面向主流发行版(RHEL、SLES、Ubuntu)编译,依赖的kernel-devel版本很可能和银河麒麟的4.19内核不一致。我在CentOS系的机器上试过可以装,但在麒麟上遇到过依赖冲突,因为麒麟的内核修改过,模块签名校验机制也不一样。
不过,如果现场环境确实不能装编译器(比如说安全要求特别严格的内网机器),你可以尝试用rpm -ivh --nodeps --force的方式强装。但坦白说,这种操作属于能用就行,不建议在关键业务机器上这么干,因为驱动模块和内核版本不匹配,很可能会在运行中出现panic或者内存泄漏。我的建议是:除非万不得已,别用这个方法。
2.3 方案三:从Intel官网下载源码包,本地编译安装(我最终选的路)
这也是本文的核心内容。源码编译虽然看起来麻烦一些,但它对内核版本、系统库的适配性最灵活,而且可以指定安装路径、调整编译参数,出了问题也容易排查。尤其是银河麒麟这种基于CentOS/RHEL生态但又有所修改的系统,源码编译是兼容性最好的方式。
当然,源码编译有个前提条件:你必须能装上build-essential那套工具链,并且系统里有kernel-devel包。银河麒麟V10 SP2的安装镜像里一般自带这些包,或者你可以通过配置好的yum源安装。如果机器完全离线,那需要提前准备好kernel-devel、gcc、make这些包的离线rpm包。后面我会详细说这一步怎么操作。
从原理上说,网卡驱动本质上是内核模块,它需要和内核的API完全匹配。内核版本升级或者打了补丁之后,模块接口可能会变化,所以官方驱动包会对应多个版本分支,选版本时不能只看最新,还要看它的兼容性说明。我之前试过用最新的ice 1.9.x版本在麒麟SP2上编译,结果因为内核头文件定义不一致,直接报编译错误。后来换成Intel官方对4.19内核适配的版本才顺利通过。这个细节在后面章节会展开。
3. 环境准备:kernel-devel、gcc还有那些你必须提前装好的东西
这部分是容易被忽略的坑。很多新手在编译驱动时报错"Kernel header not found"或者"Unable to find kernel source",然后整个人就懵了。其实原因很简单:内核模块编译需要内核头文件,而这些头文件在kernel-devel包里面,默认系统不一定装了。
3.1 确认内核版本和对应的devel包
首先记下你的内核版本:
uname -r假设输出是:4.19.90-23.8.v2101.ky10.x86_64
注意这个后缀"ky10"是麒麟特有的,它对应的是银河麒麟V10系列的内核。这时候你安装kernel-devel,必须精确匹配这个版本号,包括ky10那部分也要对上,否则编译时头文件版本不一致,还是会报错。
安装命令:
# 使用麒麟自带的yum源 yum install -y kernel-devel-$(uname -r)或者如果你能连外网,也可以直接:
yum install -y kernel-devel安装完成后,检查下面这个路径是否存在,并且里面有没有build目录:
ls /usr/src/kernels/$(uname -r)如果能看到build、include这些目录,说明kernel-devel装好了。
3.2 安装编译工具链
yum install -y gcc gcc-c++ make elfutils-libelf-devel这里要特别提一下elfutils-libelf-devel,很多人在编译驱动时遇到缺少"libelf.h"或者"elfutils"相关报错,就是这个包没装。Intel的ice驱动编译脚本在配置阶段会检查这个库,缺了直接configure失败。
另外,如果你打算用RDMA功能,还需要安装rdma-core相关的依赖:
yum install -y rdma-core-devel libibverbs-devel但这里有个注意点:银河麒麟V10 SP2自带的rdma-core版本可能比较老(我记得是28左右的版本),而新版本的ice驱动默认对接的是rdma-core 35以上版本。如果在configure时检测到rdma-core版本太低,它会自动禁用irdma(就是RDMA驱动)的编译,只生成纯ice的模块。这个不算致命错误,但如果需要RDMA功能,就得提前把rdma-core升级。升级的方法有两种:一是用麒麟源里的新版本(如果源里有的话),二是自己去GitHub上编译安装。后者工作量有点大,而且可能会影响系统里其他依赖老版本rdma-core的组件,建议需要RDMA的童鞋提前做好备份和测试,别直接在生产上操作。
3.3 离线环境怎么办?
我遇到过不少内网服务器的场景,银河麒麟的yum源配的是内网镜像,上面不一定有完整的高版本kernel-devel。这时候有个笨办法:找一台同样系统版本、能上外网的机器,把相关的rpm包下载好,拷到内网机器上。
# 在能上网的机器上执行 yum install --downloadonly --downloaddir=/tmp/kernel-rpms kernel-devel-$(uname -r) gcc make elfutils-libelf-devel然后把/tmp/kernel-rpms下所有rpm拷到内网机器,执行:
rpm -ivh /tmp/kernel-rpms/*.rpm如果是完全断网的环境,连依赖匹配都成问题,那我的建议是:把源盘里的kernel-devel包找出来装上。银河麒麟的安装ISO里其实带了kernel-devel的rpm包,用mount挂载ISO后,在Packages目录下能找到。虽然版本可能和实际运行的内核有细微差异(大多数情况下是一致的),但编译ice驱动问题不大。
3.4 验证一下当前系统的构建环境
装完依赖后,别急着下载驱动,先跑一下这个命令,确保内核可以编译模块:
cd /usr/src/kernels/$(uname -r) make oldconfig && make prepare如果这里编译过程中报错,说明工具链还有问题,先解决这一步,否则后面驱动编译一定失败。make prepare这个过程大概几分钟,看机器性能,如果你编译时报错找不到某些头文件,大概率是这一步没做成功。
我遇到过的一种情况是,装完kernel-devel后,/usr/src/kernels目录下的软链接指向不对,导致编译时找不到头文件。解决方法是手动重新建立软链接:
ln -sf /usr/src/kernels/$(uname -r) /lib/modules/$(uname -r)/build这个命令可以反复执行,确保万无一失。
4. 下载Intel官方ice驱动源码:版本选择和文件校验
Intel的网卡驱动都放在官方的一个统一站点上,叫Intel Support。对于E810系列,它的驱动页面会提供icen(rdma)驱动的下载,文件名类似:
- ice-1.11.14.tar.gz
- ice-1.10.13.tar.gz
- 或者更高版本
不同版本号对应的内核兼容性不同。以我踩过的坑为例:我最初下载了ice-1.15.x(印象中是2023年某个版本),在麒麟SP2的4.19内核上编译直接报错,错误信息类似:
error: implicit declaration of function 'in_dev_get'这个函数在新内核里被移除了,而老内核还在用,说明驱动太新,适配的是5.x内核,对4.19反而不友好。后来我换成ice-1.9.7这个版本,编译一次通过。这个经验告诉我:不要盲目追求新版驱动,要和你的内核版本匹配。你的内核越老,驱动的版本也应该跟着用老一些的分支。
下载方式可以用wget,也可以直接浏览器下载后传上去:
wget https://downloadmirror.intel.com/.../ice-1.9.7.tar.gz注意:Intel官方下载链接经常变动,建议直接在Intel官网搜索"E810 ice driver download",进到对应产品页面后选择Linux驱动。
下载完成后,做一个SHA256校验,确保文件完整:
sha256sum ice-1.9.7.tar.gz和官网上公布的checksum比对,一致再解压。这一步虽然看着多余,但你要是经历过下载了半截文件然后编译报各种奇怪错误的场景,就知道这10秒的价值有多大。
解压:
tar -xzf ice-1.9.7.tar.gz cd ice-1.9.7在源码目录里你会看到几个重要的东西:README、src目录、scripts目录、Makefile。Intel的驱动编译方式比较统一,就是标准的make,看README大致就能明白。
还有一个细节:ice驱动源码包里通常还会带一个叫做"ice-firmware"或者"firmware"的目录,里面是NVM(Non-Volatile Memory,网卡固件)文件,一般是.inp或者.phi格式。这个固件文件很重要,如果你的网卡出厂固件太旧,驱动加载后可能会出现特殊现象,比如link就是起不来,或者100G协商不了。如果你确认网卡固件版本过旧,需要单独用Intel的NVMUpdate工具升级固件。
E810-C的固件更新工具需要在Intel官网单独下载,一般叫"Intel Ethernet Adapter Complete Driver Pack"或者"NVMUpdate Package"。这个工具在Linux下有命令行版本,可以烧录最新的固件。但这属于另一个话题了,这里不展开说,只提醒一点:如果网卡link起不来,先看ethtool -i输出的firmware版本,不要上来就认为是驱动问题,很可能只是固件太旧。
5. 编译安装全程实录:configure参数、make的坑和最终加载
5.1 进入源码目录后的第一步,先看configure的帮助
cd ice-1.9.7 ./configure --help你会看到有很多选项,但一般用默认的就行。如果你想指定安装路径,可以用--prefix,但内核模块的安装路径最好保持默认(/lib/modules/$(uname -r)/updates),否则modprobe找不到。
5.2 执行configure
./configure这个阶段会检查系统环境,输出类似"checking for kernel..."的信息。如果你看到以下错误:
configure: error: Kernel /lib/modules/4.19.90/... is not configured说明内核头文件没准备好,回到第3节去解决。如果configure顺利完成,会生成Makefile。
5.3 编译和安装
make make installmake的过程会持续几分钟,具体时间取决于源码版本和机器性能。如果编译过程出现错误,大多数情况是因为内核版本和驱动不匹配。常见错误有:
- 缺少头文件,比如
linux/if_link.h找不到——检查kernel-devel是否安装完整 - 函数名冲突,比如某个函数在新版内核改名了——只能换驱动版本
- 警告当成错误(-Werror)——可以尝试在Makefile里去掉-Werror,但这是下策,不建议
我建议的做法是:编译前先看一下Makefile里的KSRV(内核源码目录)变量,确保它指向正确的路径。如果默认指向/usr/src/linux,而你的内核源码在/usr/src/kernels/xxx,就需要手动指定:
make KSRC=/usr/src/kernels/$(uname -r)这一步很多人不知道,但很关键。
5.4 驱动安装需要root权限,装完后如何正确加载
make install完成之后,ice.ko和irdma.ko(如果编译了)会被拷贝到:
/lib/modules/$(uname -r)/updates/drivers/net/ethernet/intel/ice/接下来要执行depmod,让系统更新模块依赖关系:
depmod -a然后加载内核模块:
modprobe ice如果加载过程中报错,先用dmesg看一下内核日志:
dmesg | grep ice正常情况会在日志里看到类似:
ice: Intel(R) Ethernet Connection E810-C Registered这样的日志,说明驱动加载成功了。
5.5 验证驱动是否真正生效
ethtool -i enp133s0f0这里enp133s0f0是网卡接口名,需要根据你系统实际分配的名称来看,用ip link就能列出来。
输出类似于:
driver: ice version: 1.9.7 firmware-version: 4.20 0x80014b5e注意这个firmware-version很重要,如果它显示不出来或者版本特别老,说明固件没加载,联系第4节说的固件升级问题。
再看一下链路状态:
ethtool enp133s0f0如果插上了光模块和对端设备,正常情况下你会看到:
Speed: 100000Mb/s Duplex: Full这代表网卡已经协商到100G了。
5.6 关于开机自动加载的问题
默认情况下,modprobe ice加载的模块在重启后会重新加载。但为了确保万无一失,最好把ice加入模块加载列表:
echo "ice" >> /etc/modules-load.d/ice.conf然后配置网卡IP,重启验证是否自动生效。这里顺便提一句,银河麒麟V10 SP2的网络配置可以用nmtui(NetworkManager的文本界面工具),也可以用传统的/etc/sysconfig/network-scripts/ifcfg-xxx文件。我个人更推荐用nmtui,因为麒麟的NetworkManager服务默认是启用的,用传统配置文件有时候会冲突。
配置完IP后:
ping <网关IP>确认网络通了,安装才算真正成功。
6. 百G网卡不是插上就能用:链路协商、MTU和中断绑定的排查
驱动装好只是第一步,100G网卡想要稳定跑满带宽,需要做的调优和排查远不止modprobe那么点事。下面这些问题,都是我在E810-C实际使用中逐个踩过并解决的,列出来供你参考。
6.1 链路协商不上去,先分清是光模块问题、线缆问题还是固件问题
100G网卡最常见的问题是插上模块后link起不来。E810-C用的是QSFP28接口,支持100G SR4/LR4等模块。如果对端是100G交换机,模块和光纤都是新的,但link就是down,我建议按这个顺序排查:
- 看ethtool输出中是否有Link detected: no
- 检查光模块是否被识别:ethtool -m enp133s0f0,如果能输出模块信息(SN、温度、光功率),说明模块通信正常
- 执行网卡自环测试(loopback test):ethtool -t enp133s0f0,这个测试会花几十秒,能判断是不是网卡硬件本身的问题
- 检查对端交换机端口的强制速率配置。有些交换机默认是自协商,但100G的自协商在很多设备上默认关闭,对端如果锁死在某个速率,两边就协商不起来
- 最后再看固件版本。E810-C的固件如果低于某个版本,确实会出现某些模块不被识别的问题,这时候就得更新NVM
6.2 MTU要不要改成9000
100G网络里面,绝大多数场景都是跑存储或者高性能计算,这类应用对大包吞吐敏感,所以建议把MTU改成9000(jumbo frame)。
设置命令:
ip link set enp133s0f0 mtu 9000注意:对端设备和交换机也要同时支持并配置MTU 9000,否则会出现ping大包不通的情况。如果你只是跑普通的TCP业务,对端设备不支持大MTU,那就老老实实保持1500,强行改大反而会导致分片和性能下降。
6.3 中断绑定和队列数调优
100G网卡如果不做中断优化,CPU负载会集中在个别核,导致瓶颈。E810支持多队列(RSS),默认情况下驱动会为每个CPU核分配一个队列,但中断可能都跑到CPU0上。你可以通过下面这个脚本把中断绑定到不同核:
# 查看当前中断 cat /proc/interrupts | grep enp133s0f0 # 获取每个队列的中断号 for irq in $(cat /proc/interrupts | grep enp133s0f0 | awk -F: '{print $1}'); do echo "IRQ $irq" done然后把中断亲和性设置到对应的CPU:
echo 1 > /proc/irq/$(irq_number)/smp_affinity更优雅的做法是使用irqbalance服务,但为了极致性能,手动绑定更可靠。另外,E810还支持ADq(Advanced Dynamic Queues)和Flow Director功能,这些都能在大流量场景下优化转发性能,不过需要额外的配置,后面有机会单独开一篇说。
6.4 驱动版本和内核版本的关系,再强调一遍
我在前面写了很多次"版本匹配",这里再赘述。E810的ice驱动和内核版本之间的兼容关系,其实在Intel的Release Notes里有明确说明表。比如ice 1.9.x支持的kernel range是3.10~5.13,ice 1.11.x支持的kernel range是4.18~5.18。如果你用5.15以上的新内核,可以放心用1.11.x或更高;但如果你在4.19上,1.9.x系列是稳妥的选择。不要问我为什么1.11不能编译到4.19上,我也没完全搞明白Intel为啥要设置这么严格的限制,总之实测就是不行。
这个原则对其他驱动也适用。用驱动之前,先花几分钟看Release Notes,能省下后面好几个小时的排错时间。
6.5 RDMA功能要不要开
E810-C这块卡一个很大的卖点是支持RoCEv2,也就是RDMA over Converged Ethernet。如果你要在上面跑高性能计算或者分布式存储,那RDMA很关键。
使用RDMA的前提条件是:
- ice驱动和irdma驱动都成功加载:modprobe irdma
- 系统里有rdma-core用户态组件:ibv_devinfo能看到设备
如果ibv_devinfo输出里能看到E810的设备和端口,说明RDMA功能正常。如果看不到,大概率是rdma-core版本太低,或者驱动编译时irdma没有被编译进去。这时候需要回到下载页面,找到配套的irdma源码包(Intel的驱动页面会提供单独的irdma下载),单独编译安装。
另外一个注意点:RoCEv2对网络质量要求比较高,必须确保链路没有丢包,否则RDMA性能会断崖式下跌。建议在交换机上开启PFC(优先级流控制)和ECN(显式拥塞通知),这些是在使用RDMA前必须搞定的网络配置,不在驱动安装范围内。
6.6 性能测试:别急着说驱动装好了
驱动安装完成后,最后一步是验证性能。我最常用的两个工具是iperf3和qperf。
# 在服务器A上 iperf3 -s # 在服务器B上 iperf3 -c <服务器A的IP> -t 60如果TCP吞吐能跑到90Gbps以上,说明驱动和链路基本没问题。如果只有30Gbps甚至更低,检查一下是不是中断都堆在一个核上,或者网卡协商速率只有25G/40G。
再用ethtool -S看网卡统计信息,看看rx_errors、tx_errors是否有值:
ethtool -S enp133s0f0 | grep -i error如果有errors或dropped,说明链路质量或者驱动配置有问题,需要进一步定位。
这一步做完,你才算真正把这块100G网卡"装好"了。
7. 一些零碎但实用的补充
最后分享几个我自己体会比较深的操作细节,不一定能对上每个人遇到的问题,但都是实打实趟出来的经验。
第一,如果机器上有多个网卡,安装后务必确认模组加载的先后顺序。有些系统会默认加载老的igb/ixgbe模块(如果你之前装过其他Intel网卡),这可能会导致接口命名混乱。比如你新加的E810-C接口名可能是enp133s0f0,而不是常见的eth0。用ip link和ethtool -i验证每个接口对应的确实是你想用的那口物理网卡,避免后续配置把业务网口搞错。
第二,银河麒麟的NetworkManager服务在某些版本上有bug,激活新网卡连接有时会失败,提示"Connection activation failed"。这时候可以先systemctl stop NetworkManager,然后直接用nmcli或者传统ifcfg配置启动。我遇到过一次,用nmcli连E810的接口总是超时,但手动ifup又没问题,后来查了下是NetworkManager的dhcp超时设置太短导致的,改一下/etc/NetworkManager/conf.d/下的配置文件就好了。
第三,Intel官方驱动包里面自带的README真的值得从头到尾读一遍。很多细节比如"NVM update required before loading driver"、某些依赖库的最低版本要求,都会写在里面。虽然现在很多人习惯只看教程不看官方文档,但在企业级硬件的场景下,官方文档往往比教程更全、更准。
最后想说,100G网卡驱动安装这件事,本身的难度并不在于"装驱动"这个动作,而在于你要理解整个链路:从内核API的适配、固件和驱动的匹配,到链路协商、用户态工具链的配合,这些都是一个系统工程。把上面的思路捋顺了,别说E810,以后换其它的新网卡(比如E830、或者别的厂商的100G卡),你也能很快上手。生产环境里面,稳比新重要,快比全重要,这是我一直以来的体会。