在某定制AMI和定制内核版本的CentOS上调查ENA驱动版本低导致的EC2不能运行在6系列机型的问题

一、背景

从IDC导入的CentOS 7.4系统,没有使用系统自带的3.10内核,而是定制了4.11内核。之前安装包含EC2需要的ENA网卡驱动,在5系列机型上可启动,在6系列机型上启动时候健康检查停留在1/2的不正常状态。查看EC2运行状态截图和EC2串口控制台,发现是网络启动失败,也就是没有识别到网卡。

本文描述了排查过程如下。

二、步骤

1、用5系列开机并设置root用户密码

首先在m5系列上开机,通过Userdata设置root密码。因为稍后EC2网络启动失败时候,通过EC2控制台的串口连接是可以登录到EC2的。此时必须要有root用户密码才可以登录。

此外需要注意,Userdata脚本必须在EC2能加载网络的环境上才有效,因为Userdata脚本是通过Meta信息被EC2加载的,因此EC2网络如果不通,也就无法运行Userdata。

#!/bin/bash
echo -e "KusksLsUfqd12" | passwd --stdin root

这样开机完毕,就获得了root密码。

2、检查ENA驱动现有版本

检查当前网卡(本机为ens5):

ethtool -i ens5

返回结果如下:

driver: ena
version: 1.1.2
firmware-version:
expansion-rom-version:
bus-info: 0000:00:05.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

执行如下查看驱动命令:

lsmod | grep ena
modinfo ena

输出结果如下:

filename:       /lib/modules/4.11.1-1.el7.elrepo.x86_64/kernel/drivers/net/ethernet/amazon/ena/ena.ko
version:        1.1.2
license:        GPL
description:    Elastic Network Adapter (ENA)
author:         Amazon.com, Inc. or its affiliates
srcversion:     108100869D86D6F6E1396A3
alias:          pci:v00001D0Fd0000EC21sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd0000EC20sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd00001EC2sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd00000EC2sv*sd*bc*sc*i*
depends:
intree:         Y
vermagic:       4.11.1-1.el7.elrepo.x86_64 SMP mod_unload modversions
parm:           debug:Debug level (0=none,...,16=all) (int)
[root@ip-172-31-10-235 yum.repos.d]#

由此可看到ENA版本低于2.0版本,低于使用6系列的最低要求。接下来安装新版本驱动。安装驱动需要kernel-devel、gcc等软件包。

3、从备份文件恢复官方Yum的Repo并更新系统

回复之前备份的源文件:

cd /etc/yum.repos.d
rm *.repo
cp bak/*.repo .

更新系统:

yum update -y
reboot

4、检查特殊版本的内核和库文件

检查当前内核版本:

rpm -qa | grep kernel

返回结果如下:

kernel-debuginfo-common-x86_64-2.6.32-696.el6.x86_64
kernel-tools-libs-3.10.0-1160.102.1.el7.x86_64
kernel-devel-3.10.0-693.el7.x86_64
kernel-ml-4.11.1-1.el7.elrepo.x86_64
kernel-3.10.0-1160.102.1.el7.x86_64
kernel-tools-3.10.0-1160.102.1.el7.x86_64
kernel-devel-3.10.0-1160.102.1.el7.x86_64
kernel-debuginfo-2.6.32-696.el6.x86_64
kernel-headers-3.10.0-1160.102.1.el7.x86_64
kernel-3.10.0-693.el7.x86_64

可看到本机使用了非官方的内核,即kernel-ml-4.11.1。仅调查,内核来自:

https://elrepo.org/tiki/HomePage

由此,为了安装ENA驱动,还需要匹配的内核开发包,因此用如下的命令下载和安装:

wget https://mirrors.gigenet.com/gigenet/elrepo-archive/kernel/el7/x86_64/RPMS/kernel-ml-devel-4.11.1-1.el7.elrepo.x86_64.rpm
rpm -ivh kernel-ml-devel-4.11.1-1.el7.elrepo.x86_64.rpm

5、安装ENA驱动

执行如下命令安装编译工具(上一步已经安装了特定版本的Kernel-devel包,因此这里不用在安装系统默认版本的kernel-devel包了)。以下命令均以root身份执行:

sudo -i
yum install gcc git -y
git clone https://github.com/amzn/amzn-drivers
cd amzn-drivers/kernel/linux/ena
make
mkdir /etc/modules-load.d/
touch /etc/modules-load.d/ena.conf
echo "ena" > /etc/modules-load.d/ena.conf
cp ena.ko /lib/modules/4.11.1-1.el7.elrepo.x86_64/
depmod
sed -i '/^GRUB\_CMDLINE\_LINUX/s/\"$/\ net\.ifnames\=0\"/' /etc/default/grub
dracut -f -v
grub2-mkconfig -o /boot/grub2/grub.cfg

安装完毕后,执行modprobe ena查看新载入内核的驱动:

filename:       /lib/modules/4.11.1-1.el7.elrepo.x86_64/ena.ko
version:        2.10.0g
license:        GPL
description:    Elastic Network Adapter (ENA)
author:         Amazon.com, Inc. or its affiliates
srcversion:     5932F35841490D87DD186D5
alias:          pci:v00001D0Fd0000EC21sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd0000EC20sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd00001EC2sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd00000EC2sv*sd*bc*sc*i*
alias:          pci:v00001D0Fd00000051sv*sd*bc*sc*i*
depends:
vermagic:       4.11.1-1.el7.elrepo.x86_64 SMP mod_unload modversions
parm:           debug:Debug level (-1=default,0=none,...,16=all) (int)
parm:           rx_queue_size:Rx queue size. The size should be a power of 2. Depending on instance type, max value can be up to 16K
 (int)
parm:           force_large_llq_header:Increases maximum supported header size in LLQ mode to 224 bytes, while reducing the maximum TX queue size by half.
 (int)
parm:           num_io_queues:Sets number of RX/TX queues to allocate to device. The maximum value depends on the device and number of online CPUs.
 (int)
parm:           enable_bql:Enable BQL.
 (int)
parm:           lpc_size:Each local page cache (lpc) holds N * 1024 pages. This parameter sets N which is rounded up to a multiplier of 2. If zero, the page cache is disabled. Max: 32
 (uint)

可看到版本已经升级到2.10.0g版本。

注意此时还不能重启Linux,因为有多个内核环境,启动内核版本不正确的话,加载的ENA驱动也是不正确的。因此要先修改启动顺序。

6、针对存在定制内核场景调整Grub启动顺序

本镜像系统默认的CentOS7的内核是3.10系列,但后安装了来自elrepo.org的kernel-ml-4.11-1内核。因此要安装完毕驱动后,经过了重新构建initramfs和grub文件,还需要重新指定grub启动顺序。

首先查询当前启动清单。

awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg

返回结果如下:

0 : CentOS Linux (3.10.0-1160.102.1.el7.x86_64) 7 (Core)
1 : DaokeOS Linux (4.11.1-1.el7.elrepo.x86_64) 7 (Core)
2 : DaokeOS Linux (3.10.0-693.el7.x86_64) 7 (Core)
3 : DaokeOS Linux (0-rescue-6676d1cb1aae48809a7cc0468b180f23) 7 (Core)

由此可看到,序号为1的是刚才安装ENA驱动对应的内核版本和内核启动文件。复制其名称,执行如下命令:

执行如下命令修改默认 (代入序号为1的启动项,两头加单引号):

grub2-set-default 'DaokeOS Linux (4.11.1-1.el7.elrepo.x86_64) 7 (Core)'
grub2-editenv list

命令执行的返回结果可看到,默认启动项已经改成了版本是4.11的内核。

安装完毕。执行reboot命令重启测试。

7、在5系列上测试新版驱动

执行reboot命令,测试安装成功的驱动,在5系列上也可以正常使用。

重启完成后,登录到EC2,执行uname -a命令确认内核启动的是正确的版本。返回结果如下:

Linux ip-172-31-10-235.ap-southeast-1.compute.internal 4.11.1-1.el7.elrepo.x86_64 #1 SMP Sun May 14 11:54:29 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux

确认了启动的是自定义的4.11版本的内核。接下来检查网卡驱动是否正常加载。执行ifconfig命令查看网卡的名称,例如网卡名称是ens5,那么执行如下命令驱动加载情况:

ethtool -i ens5

返回结果如下:

driver: ena
version: 2.10.0g
firmware-version:
expansion-rom-version:
bus-info: 0000:00:05.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: yes

由此看到驱动版本和前文从Github下载安装的版本一致。接下来即可从5系换到6系机型测试。

三、更换机型

先停止EC2。然后修改其类型为m6i.large或者m6a.large,分别测试Intel处理器和AMD处理器兼容性。

启动后,分别执行如下命令:

  • 执行lscpu命令,检查cpu是否是最新机型6系对应的处理器
  • 执行uname -a命令,检查启动的内核是否是定制的kernel-ml-4.11-1版本
  • 执行modinfo ena命令,检查内核模块ENA驱动版本是否是最新安装的2.10.0g
  • 执行ip link show命令,检查网卡名称是否是ens5`
  • 执行ethtool -i ens5命令,检查网卡使用的ENA驱动版本是否是最新安装的2.10.0g

通过以上检查,可确认ENA网卡升级成功,6系EC2实例运行正常。

四、参考文档

What do I need to do before migrating my EC2 instance to a sixth generation instance

https://repost.aws/knowledge-center/migrate-to-gen6-ec2-instance

Enable enhanced networking on Linux

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking-ena.html#test-enhanced-networking-ena