1 背景
CentOS(Community Enterprise Operating System)是Linux发行版之一,它由来自于Red Hat Enterprise Linux(RHEL)依照开放源代码规定发布的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定性的服务器以CentOS替代商业版的Red Hat Enterprise Linux使用[1]。自从红帽公司单方面宣布终止CentOS的开发后,我们腾讯云的用户也逐步开始将应用迁移到其它操作系统上。由于CentOS 7的维护终止日期在2024年6月30日,距离当前还有一段时间,所以还有少量客户在继续使用着该版本。
在为客户解决现网问题的过程中,我们发现因为内核缺陷导致操作系统崩溃的情况时有发生。其中一个影响比较普遍的缺陷与日志服务在ext4文件系统上写文件时有关。关于该bug的详细说明,可以见参考文档[2] [3]。显然要彻底解决这些已知缺陷以及修复潜在的安全隐患,最好的方法是升级内核。关于升级Linux内核,可以找到不少参考资料。但是很少有人对于内核升级过程中的风险做过全面的评估。本文将尝试通过实践操作对该问题进行验证,从而为客户升级Linux内核提供参考。
2 测试步骤
我们期望在内核升级过程中,服务不可用的时间最短;内核升级后,原各项服务以及应用程序都能正常运行,数据不丢失;此外在最坏的情况下,若结果不符合预期,可以安全地回退到原系统状态。为此,我们总结了基本的操作步骤如下图所示:
经过本次测试,当前结论是风险可控:内核升级后,已有的服务(例如常见的web服务,数据库服务等)依旧可以使用;已经安装过的驱动(例如GPU驱动),应用程序等,在升级后均可以正常使用,客户数据无影响。唯一例外的是自己定制的驱动程序:由于依赖库的原因,需要同步升级新内核的头文件,新的编译器等,重启编译后可以继续使用。下面将详细说明本次测试过程。
3 测试环境
生产环境中比较典型的服务有:Web服务,数据库服务,容器服务等。时间关系,这里选择了前2项服务进行验证。对于某些特殊的机型,例如GPU机型或者裸金属机型,还会涉及到驱动程序。这里采用了GPU机型验证NVIDAI显卡驱动程序。此外,我们也考虑到客户会有自己的一些应用程序和驱动程序,这里也一并做了测试。测试环境总结如下:
硬件环境:机型为GN7.2XLARGE32,含一张共享的NVIDIA T4 GPU卡
操作系统:centos7.6.0 x64,内核版本3.10.0-1160.71.1.el7.x86_64
服务程序: Web服务采用Nginx, 数据库服务采用MySQL
GPU程序: 采用NVIDIA官方的cuda-samples[4]程序验证显卡驱动
应用程序: 客户应用程序采用ProcDump[5]模拟,客户驱动程序采用TOA[6]模拟
4 操作说明
4.1 准备工作
系统初始化时选择CentOS7.6版本,自带GPU驱动程序,安装界面如下图所示:
为了运行cuda-samples测试程序验证显卡功能,需要将CUDA版本升级到12。我们按照提示进行了升级[7],升级后相应的GPU驱动程序也升级到了525,如下图所示:
通过Git下载CUDA测试程序,进入目录后运行make即可编译程序。这里使用了“2_Concepts_and_Techniques”目录下的histogram程序。因为这里只有1块GPU显卡,通过运行如下命令即可测试:
CUDA_VISIBLE_DEVICES=0 ./histogram
安装Nginx服务[8],安装完成后通过http访问公网IP地址可以看到缺省页面; 安装MySQL服务[9],安装后可以输入mysql进入命令行的方式与数据库进行交互; 下载并编译ProcDump程序,编译过程中需要下载clang 工具包[10]; 下载并编译TOA驱动程序,编译完成后,通过如下命令加载驱动程序验证: insmod ./toa.ko
4.2 创建快照备份
内核升级操作有一定的风险。为了控制风险的影响程度,建议在正式操作前对当前系统盘做一个快照备份。这样若出现不符合预期的情况,可以安全回退到之前的状态。
在腾讯云控制页面中创建快照,可以先进入CVM服务器的控制界面,再从“更多操作”菜单项下选择“创建快照组”。在出现的云硬盘列表中点击操作系统所在磁盘,并移到“本地硬盘快照”项,可以看到旁边有一个“创建快照”功能。点击进入功能页面后创建一个快照。该快照可以用于将来恢复操作系统。
4.3 升级Linux内核
做好上述准备工作后,下面就开始来升级Linux内核。主要包括如下几步:
1)升级相关软件包
首先将服务器上软件包进行升级,分别运行如下命令: yum -y update yum -y install yum-plugin-fastestmirror (更详细的说明见参考文档[11]。)
2)添加软件源
执行如下命令添加软件源 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
3)升级Linux内核
输入如下命令开始升级Linux内核 yum --enablerepo=elrepo-kernel install kernel-ml
4)选择新内核
输入如下命令查看当前系统所安装的内核列表: sudo awk -F' '$1=="menuentry " {print i " : " $2}' /etc/grub2.cfg 运行后会看到如下所示列表:
我们看到索引位置为0的那一项就是我们新安装的内核。为此我们运行如下命令选择该内核:
sudo grub2-set-default 0
随后运行如下命令更新配置文件:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
5)重启系统
做完上述配置后,我们运行reboot重启系统。重启后我们再查询内核版本,可以看到已经升级到最新的6.1.2版本了。
4.4 验证各项服务
重启后经过验证,各项服务均可以正常运行,Web服务和数据库服务均正常; ProcDump测试程序可以正常运行; CUDA相关的测试程序可以正常运行; 但是加载TOA驱动程序报错:
这种情况下需要更新与内核相匹配的开发环境,头文件等[12] [13]。更新后重新编译该驱动程序即可。
需要特别注意的是:根据参考文档[12]操作的过程中,会先删除旧的头文件,编译工具等,这个过程中会将GPU驱动误删除。可以通过重新安装驱动程序恢复。
4.5 失败情况处理
由于前面我们已经创建的了快照备份,所以如果发现内核升级后不符合预期,都可以通过回滚的方式恢复到原始状态。或者通过采用4.3节的“选择新内核”这一步,重新选择旧的内核,重启系统后生效。
若确认升级成功,可以根据参考文档[11]将旧内核删除。
5 问题讨论
1)可否采用热升级的方式,不重启服务器,从而不影响现有的服务?
通过学习相关资料,了解到Redhat以及CentOS可以采用热升级的方式升级内核补丁[14],热升级使用Kpatch工具。但是在实际使用过程中,发现需要有适合Kpatch使用的升级包。在升级内核的过程中,并没有找到现成的升级包。所以本测试所使用的升级方式需要重启系统。对现有服务会有影响。
2)如何检测GPU驱动程序是否正常?
NVIDIA官方提供了一个测试程序包[4],可以对显卡进行测试。其程序运行格式如下所示: CUDA_VISIBLE_DEVICES=x ./y 其中:x表示所使用的显卡序号,数值从0开始;y表示所使用的测试程序。
3)TOA是什么程序?
TOA是TCP Option Address的缩写。它可以被编译成一个内核模块,用于从TCP头信息中获取客户端IP地址。在混合云部署场景下,可以通过 TOA 获取客户端真实 IP,具体可以参考如下文档: https://cloud.tencent.com/document/product/214/68105
4)CVM服务器没有公网地址如何升级内核?
Linux kernel升级的过程中,需要从外网下载安装包。但是有些CVM没有公网IP地址,无法与外网通信。此时可以通过绑定公网IP地址的方式实现与外网的通信。
6 参考资料
[1] CentOS wiki
https://zh.wikipedia.org/zh-cn/CentOS
[2] kernel BUG at jbd2_journal_put_journal_head 0x44
https://access.redhat.com/solutions/5229821
[3] RHEL7: jbd2 deadlock occurs while checkpoint thread waits commit thread to finish.
https://access.redhat.com/solutions/4054181
[4] NVIDIA 官方的cuda-samples
https://github.com/NVIDIA/cuda-samples
[5] ProcDump
https://github.com/Sysinternals/ProcDump-for-Linux
[6] TOA
https://github.com/ucloud/ucloud-toa
[7] 将CUDA版本升级到12
https://developer.nvidia.com/cuda-downloads
[8] CentOS 7 yum 安装 Nginx
https://cloud.tencent.com/developer/article/2070787
[9] centos7 安装MySQL
https://developer.aliyun.com/article/512555
[10] Update GCC
https://blog.csdn.net/qq_32271493/article/details/114652272
[11] How to Upgrade the Linux Kernel on CentOS 7
https://www.howtoforge.com/tutorial/how-to-upgrade-kernel-in-centos-7-server/
[12] How to install kernel-devel and kernel-headers mathching 5.x kernel?
https://stackoverflow.com/questions/69431107/how-to-install-kernel-devel-and-kernel-headers-mathching-5-x-kernel
[13]Use updated kernel in CentOS 7
https://www.virtualtothecore.com/use-updated-kernel-centos-7/
[14] How to Apply Linux Kernel Security Patches: 3 Different Ways
https://tuxcare.com/how-to-apply-linux-kernel-security-patches-3-different-ways/