一、背景和挑战
1、需求背景
CentOS 6系列是2016年发布的系统,在2020年已经是比较老的系统,一般建议通过yum update升级版本,最高可升级到6.10。有些特殊的客户环境和应用程序,存在一些库文件版本的依赖,需要精确的用到6.8版本提供的库文件,不能很好的兼容6.9或者最新的6.10版本。例如6.8的从ISO安装后原始内核版本是2.6.32-642,而升级到2.6.10后是2.6.32-754,此外其他一些程序包也存在库文件版本差异。那么上云的时候,就必须提供特定的6.8版本的云上镜像(AMI)的支持。
2、CentOS 6.8迁移到AWS的挑战
AWS支持通过CLI工具执行vmimport,将自己的私有环境的镜像上传并导入到云上。不过,CentOS 6.8版本在上传后,是缺少AWS这两年广泛使用的5系列实例的ENA功能,即增强网络驱动的支持。由CentOS 6.8原始镜像创建的EC2只能选择T2、C4、M4、R4等规格,各方面性能都受到很大影响。因此,为CentOS 6.8安装ENA增强网络驱动,成为了迁移到AWS的一个重要步骤。
3、跳过手工安装ENA支持的办法
第一种办法:采用Amazon Linux 去替代CentOS 6.8系统。我们知道Amazon Linux 2是与CentOS 7保持较好兼容的,而Amazon Linux是上一代系统,是与CentOS6保持较好兼容的。Amazon Linux 虽然是基于2.6内核的发行版,但提供了一般CentOS没有的NVMe、ENA等支持,是非常好的云上优化方案。需要注意的是,2020年12月31日Amazon Linux将结束标准支持(Standard Support),转入维护支持(Maintain Support),这意味着,未来一年或者两年使用Amazon Linux依然可以继续获取升级包的,对于生产环境的安全是非常重要重要的。因此第一种办法是尝试换用Amazon Linux。
第二种办法:在尝试解决问题的过程中,我们发现从AMI社区镜像和Marketplace中,有很多基于CentOS6基础的镜像。但是,他们的版本大多已经是通过yum update提升到了6.9或者6.10版本,才打开了ENA支持。在社区和市场中,并未找到不含第三方应用的空白的6.8版本。因此,本文这里还是需要探讨如何自行安装CentOS6.8的ENA支持。
4、思路
我们安装过程中,必须保证CentOS 6.8版本,不能执行yum update。同时,不可避免需要内核开发模块、GCC等编译。在这个思路下,我们有多种解决办法:
- 1)在本地用Virtualbox等虚拟化软件,搭建一个全白开发环境,编译模块,调试完成后,卸载gcc等生产不需要的开发环境,然后上传到AWS形成AMI镜像文件;
- 2)在上一步的方式上做一些优化,在编译完成后,将编译出来的ENA内核模块copy到另一个不带开发环境的准生产环境上,直接挂载到内核,然后测试,并打包新的AMI镜像。如此不需要后期再去卸载生产环境不需要的各种工具;
- 3)另一种完全不一样的方法是,从本地上传一个不支持ENA驱动的CentOS 6.8到AWS上做成AMI镜像,然后用EC2的上一代规格例如 c4.large 启动,然后在这个C4实例上,完成ENA驱动安装。安装完毕后,通过CLI为这个实例启动ENA Support,执行将C4升级到C5的过程。升级完毕后,获得5系列实例一个。最后将这个5系列实例转换为一个AMI镜像,今后直接使用。
以上方法中,可以看到方法三是最复杂的,需要做实例升级方法1相对最简单。本文按照方法2编写。
二、在本地开发环境编译内核模块
从CentOS官网或者Kernel.org下载centos 6.8版本的ISO,很多国内源都再不提供镜像。本文最后参考连接位置附上了官网下载网址。下载版本请选择CentOS-6.8-x86_64-bin-DVD1.iso,即第一张DVD即可,注意选择Live版本是不包含gcc的,无法安装编译。
在本地用Virtualbox创建虚拟机时候,选择磁盘格式VHD,动态扩展即可,这样下边的步骤可以直接upload到AWS,无需转化磁盘格式。安装时候,软件包选择basic server。安装过程记得不要联网。不要yum update。
安装完毕后,把iso挂载上,执行如下命令:
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
cd /etc/yum.repos.d/
mv *.repo ~/
vi cdrom.repo
在cdrom.repo内输入以下内容:
[local]
name=iso
baseurl=file:///mnt/cdrom
gpgcheck=1
执行如下命令清空缓存:
yum clean all
这样就建立了一个local的yum repo,完全不联网。接下来继续安装开发工具,执行如下命令:
yum install gcc git openssh-server kernel-devel -y
chkconfig --add sshd
chkconfig sshd on
chkconfig iptables off
这样就获得了一个好的开发环境。
现在重启虚拟机,把虚拟机网卡连回去,注意不要update打补丁。最好在本地局域网,确保安全,不会被别的病毒木马扫描或攻入进来。从本地登录到登录这个虚拟机上,开始联网操作,去checkout git上的代码库。执行如下命令:
git clone https://github.com/amzn/amzn-drivers
cd amzn-drivers/kernel/linux/ena
make
编译完成。可在当前目录下获得ena.ko文件。
三、将ENA内核模块复制到准生产环境加载
按照本文介绍的几种实现方式,我们选择第二种,将编译好的ko文件复制到一个全新的准生产环境上,继续完成模块挂载。
生产环境的CentOS 6.8推荐使用标准安装,例如在软件包界面,选择 Basic Server,然后不需要选择定制,保持默认安装完。如此获得的安装环境是不带gcc和git等工具的,但又包含了ssh server。
执行如下命令。
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/2.6.32-642.el6.x86_64
depmod
dracut -f -v
在本文末尾提到的AWS官方参考文档上,还提到 Predictable Network Interface Names 需要被关闭。经过调查,版本是V197的或者更高的systemd需要这个操作,在centos 6.8上低于197,因此可略过本步骤,继续后续操作。
前一个步骤加载完成。重启虚拟机看是否正常启动。启动过程在虚拟机的console上可能有如下信息:
ena: loading out-of-tree module taints kernel.
ena: module verification failed: signature and/or required key missing - tainting kernel
这个信息在AWS官方的github说明里边,表述了是正常的,请略过。重启完成后,连接到本机,验证ena模块加载正常。执行 modinfo ena,输出如下信息则表示正常。
执行如下命令,删除现有网卡信息。
rm /etc/udev/rules.d/70-persistent-net.rules
好了,关机,准备upload到AWS。
四、上传VHD文件到AWS
上传虚拟机到AWS并导入为镜像,需要配置几个IAM角色和身份,还需要CLI发起操作,导入过程与其他Linux、Windows镜像的导入过程完全一致。本文略过权限设置部分,请参考相关资料。
接下来执行导入。注意执行cli默认区域、vmimport、S3 Bucket区域必须相同。如下截图。
监控上传是否完成。可以看到已经完成。
五、找到镜像并用5系列EC2开机
进入EC2界面,在AMI下找到新导入的镜像。
查看镜像,可以看到ENA=yes是可用的。如果配置不正确,这里会显示ENA=no。
然后选择主机规格,例如c5.xlarge。如果ENA配置不正确,所有5系列实例都是灰色,不可选择。可以选择的话就证明ENA驱动安装成功。
另外,不支持结尾是字母d的实例,字母d表示实例包括本地存储,通道是NVMe,但因为CentOS 6.8的内核2.6系列无法安装AWS的NVMe驱动,因此不能支持。如下截图。
创建EC2的过程不再详细描述。
创建好之后登录到EC2,登录过程需要用密码登录。因为是自行创建的镜像,因此创建中选择登录Key步骤可以选择不需要设置Key。登录后执行如下命令,检查确认ENA模式是否正常。
ethtool -i eth0
如果显示如下信息,在driver部分显示vif,则表示ENA没有正确加载。可能的原因是:1)ENA驱动没安装正确,2)本镜像AMI是支持ENA的,但是当前启动的是T2系列实例、4系列实例等不支持ENA增强网络驱动的EC2,由于EC2本身不支持,这里就也会显示如下信息。
driver: vif
version:
firmware-version:
bus-info: vif-0
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
如果显示如下信息,在driver的部分显示ena,则表示ENA驱动加载成功。
driver: ena
version: 2.2.3g
firmware-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
至此配置完成。
六、注意事项
本文操作的整个过程,关键环节是build前准备环境断开联网,不执行yum update,否则会导致很多库被动的升级为CentOS 6.10的库版本。编译环境需要通过本地的DVD ISO上的各种rpm包来装,可完全匹配CentOS 6.8原生版本。
另外的小tips,上传到AWS之前需要把ssh server设置开机自动启动,并关闭iptables。上云后的最佳实践是使用EC2的Security Group来管控端口开放,因此可完全关闭iptables。
七、参考文档
1、CentOS 6.8官方下载网址:
http://archive.kernel.org/centos-vault/6.8/isos/x86_64/
2、将私有镜像导入到AWS之前的IAM权限准备操作说明:
https://docs.aws.amazon.com/zh_cn/vm-import/latest/userguide/vmie_prereqs.html
3、Linux系统启用ENA支持:
4、ENA内核模块源代码和编译说明:
https://github.com/amzn/amzn-drivers/tree/master/kernel/linux/ena
全文完。