
做运维这些年系统升级做过不少但内核升级始终是那个“不做不行、做了心惊”的活儿。Anolis OS龙蜥操作系统这几年在服务器端的出镜率越来越高一方面是因为它跟CentOS生态兼容性好另一方面是社区的更新节奏确实跟得上。不过内核升级这件事很多朋友要么不敢动要么上来就一把梭结果启动直接进不了系统。这篇文章我就把Anolis OS内核升级从查询到配置的完整流程拆开揉碎讲一遍包括各种查询命令、升级方式、引导配置、回滚机制以及我踩过的坑希望你看完能少走弯路。文章适合谁看主要是正在使用或准备迁移到Anolis OS的运维工程师、开发环境管理员以及那些被CentOS停服搞得不得不换系统的朋友们。读懂这篇文章你能搞清楚一件事内核升级不是玄学是一套有迹可循的标准化操作关键是把每一步的“为什么”弄明白。1. 升级前先摸清家底内核版本查询与现状评估1.1 当前内核版本查询的几种姿势先说最基础的怎么知道当前系统跑的是哪个内核版本。这个命令大家应该都熟就是uname -r但实际工作中光靠它还不够。# 查看当前运行的内核版本 uname -r # 查看内核完整信息包括编译时间、编译器版本等 uname -a # 查看系统发行版信息确认是Anolis OS哪个大版本 cat /etc/os-release # 查看已安装的内核相关包 rpm -qa | grep ^kernel输出大概是这样的[rootanolis ~]# uname -r 4.18.0-372.32.1.an8_6.x86_64 [rootanolis ~]# cat /etc/os-release NAMEAnolis OS VERSION8.6 IDanolis ID_LIKErhel fedora centos VERSION_ID8.6 PLATFORM_IDplatform:an8 PRETTY_NAMEAnolis OS 8.6 ANSI_COLOR0;31 HOME_URLhttps://openanolis.cn/这里有两个信息特别关键内核版本号和系统大版本号。Anolis OS 8系列默认的内核是4.18这是从RHEL/CentOS 8沿袭下来的内核主线Anolis在此基础上做了大量的补丁和优化。如果你看到内核版本里带an8字样说明这是龙蜥官方适配过的内核。1.2 硬件与内核兼容性摸底升级内核之前我强烈建议先做一轮硬件兼容性检查。内核升级后遇到的绝大多数问题其实不是内核本身的问题而是新内核和旧硬件驱动之间的适配问题。需要重点检查的硬件包括网卡芯片型号尤其是板载网卡和万兆网卡RAID卡和HBA卡直通卡型号GPU型号如果有NVMe SSD的固件和驱动情况主板上的BMC/iDRAC管理口芯片查询方式可以用# 查看PCI设备列表 lspci | grep -i ethernet lspci | grep -i raid lspci | grep -i vga # 查看已加载的内核模块 lsmod # 查看当前内核支持的模块路径 ls /lib/modules/$(uname -r)/我见过最典型的一个案例一台机器上用着老款的Broadcom网卡CentOS 7自带的3.10内核一直跑得好好的用户升级到4.18内核后网卡驱动模块加载失败服务器直接失联。最后排查下来是旧网卡不在新内核的驱动支持列表里需要额外编译驱动模块。所以在升级前把硬件清单拉出来去内核的drivers/net目录或者其他驱动源里确认一下支持情况这个动作能帮你省掉不少麻烦。1.3 判断是否需要升级的四个信号不是所有机器都需要没事就升内核内核升级是有明确诉求才做的操作。我总结下来出现以下四个信号之一你就该认真考虑升级了第一安全漏洞修复。系统发布安全公告后如果涉及内核漏洞比如脏管道、Dirty COW这类且你的业务环境对安全等级有要求那就得尽快跟进。第二硬件驱动支持不足。新采购的服务器比如最新的NVMe盘、新的网卡旧内核识别不了或者性能发挥不出来这时候不升级不行。第三性能瓶颈。某些业务场景下旧内核的调度器、网络栈表现不佳。比如高并发网络转发场景新内核在TCP性能上往往有明显改善。第四容器和虚拟化需求。Docker、Kubernetes 对内核特性有要求像 overlayfs、cgroup v2、iptables 的某些模块新内核支持更完整运行更稳定。但反过来也要提醒一句如果你的业务系统跑得好好的没有安全诉求也没有新硬件要支持那就别折腾。内核升级是有风险的操作稳定压倒一切这是运维工作的铁律。2. 升级前的准备工作备份与依赖检查2.1 系统快照与关键配置备份说句实在话内核升级前最重要的事不是执行升级命令而是做好回滚预案。我见过太多人忽略了备份结果新内核起不来旧内核又被清理了最后只能拿光盘进救援模式。那种酸爽谁经历谁知道。这里说的备份包括几层如果是虚拟机优先做整机快照。操作前在虚拟化平台点一下快照出问题一键还原这是成本最低的保险方案。如果是物理机建议备份/boot分区和整个/etc目录。内核升级会改动/boot下的vmlinuz、initramfs同时可能改写/etc/default/grub和grub配置。如果条件允许把重要的业务数据进行异地备份以防极端情况。# 备份 /etc 目录 tar -czf /data/backup/etc_$(date %Y%m%d%H%M%S).tar.gz /etc # 备份 /boot 目录 tar -czf /data/backup/boot_$(date %Y%m%d%H%M%S).tar.gz /boot2.2 软件源配置检查Anolis OS的内核升级依赖软件源所以升级前必须先确认yum源配置正确。Anolis默认的源是repo.openanolis.cn你可以在/etc/yum.repos.d/下看到相关的repo文件。# 查看已配置的源 yum repolist # 查看内核相关的可用包 yum list available kernel*检查的时候注意几个点第一确认源文件没有损坏baseurl或mirrorlist地址能正常访问。有时候内网环境需要走代理那就要在/etc/yum.conf里配置好代理。第二确认源的gpgcheck设置。官方源的gpgcheck一般是1这是为了校验软件包签名防止被篡改不建议关闭。第三如果公司内部有镜像源可以用内网源替换默认源速度会快很多。我之前在内网部署了一个龙蜥源的镜像升级内核时下载速度能从几MB/s提升到上百MB/s。2.3 磁盘空间与引导分区检查内核升级会占用不少磁盘空间特别是/boot分区因为每个内核版本都会在/boot下生成 vmlinuz 和 initramfs 两个文件加起来大概几十MB到上百MB。如果/boot分区当初分配得太小升级完新内核后旧的还来不及清理很容易把分区撑爆。检查命令# 查看各分区使用情况 df -h # 重点看 /boot 分区的剩余空间 df -h /boot # 查看 /boot 下已有的内核文件 ls -lh /boot/我的建议是升级前保证/boot至少有200MB以上的空闲空间/分区或者说/usr分区至少有2GB以上空闲。Anolis OS 8.6默认的/boot分区大小一般是1GB如果你用的是默认分区方案正常来说够用但运行了一段时间后里面可能积累了不少旧内核文件那就得先手动清理一下。注意清理旧内核的时候不要用rpm -e一个个删可能会出现依赖问题。建议用dnf remove --oldinstallonly或者手动保留最近两个版本其余的统一移除。具体方法后面会展开讲。3. 内核升级实操在线与离线两种路径3.1 在线升级一条命令到最新稳定版Anolis OS是基于RHEL 8体系构建的软件管理走的是dnfyum。所以最直接的在线升级方法就是# 刷新软件源缓存 dnf makecache # 查看可用的内核包 dnf list available kernel # 安装最新内核 dnf install kernel -y执行完成后系统会安装一个新的内核包并自动为你生成对应的initramfs文件。需要注意这时候新内核并不会立即生效重启机器后默认进入的也不一定是新内核需要手动指定引导项或设置默认内核。另外Anolis OS 8.6的官方源里内核包是分拆的除了kernel主包还有kernel-core、kernel-modules、kernel-modules-extra等子包。安装kernel的时候会通过依赖关系自动把需要的子包装上一般不需要手动干预。但如果你的业务需要某些特殊模块比如文件系统驱动、网络过滤模块升级后要检查一下kernel-modules-extra是否也更新到了同版本。# 检查内核相关包的版本一致性 rpm -qa kernel\* | sort升级完成后建议同步更新一下系统工具避免新内核和旧用户态工具之间出现兼容性问题# 同步更新系统不推荐在生产环境直接全量更新但内核升级后建议更新相关工具 dnf update -y实际操作中我不建议一上来就dnf update全量更新那样变化范围太大出了问题不好排查。更稳妥的做法是只升级内核和与之直接相关的包观察一段时间没问题后再做其他更新。3.2 指定版本内核安装与离线安装路径有些时候你不能装最新版内核比如业务方有特殊要求或者内网环境与外网隔离无法访问在线源。这时候就需要走指定版本安装或离线安装的路径。先看看怎么装指定版本。假设你的软件源里有多个内核版本可以用下面的命令查询# 查看源里所有可用的内核版本 dnf list kernel --showduplicates # 安装指定版本比如 kernel-4.18.0-372.19.1.an8_5.x86_64 dnf install kernel-4.18.0-372.19.1.an8_5.x86_64 -y离线安装场景就比较麻烦了。常见的做法是在一台能上网的Anolis机器上先下载好内核RPM包再拷贝到内网机器上安装。# 在联网机器上下载内核包不安装只下载 dnf download kernel kernel-core kernel-modules kernel-modules-extra --destdir/tmp/kernel_rpms # 如果有依赖包没下载全可以用下面的命令把依赖也一起下载 dnf download kernel* --resolve --alldeps --destdir/tmp/kernel_rpms然后把/tmp/kernel_rpms下的所有rpm包拷贝到目标机器上用本地安装# 在离线机器上安装本地rpm包 dnf install /tmp/kernel_rpms/*.rpm -y这里有个坑要特别提醒离线安装时如果内核的依赖包和目标机器上已有的包版本不一致dnf可能会报依赖错误。解决办法是把依赖包也一并下载齐全或者用--setoptobsoletes0选项避开某些过时包的冲突这个操作有风险不建议新手使用。3.3 内核模块与第三方驱动的兼容性处理升级内核后原来自行编译安装的内核模块比如网卡驱动、GPU驱动、安全软件的内核模块可能会失效因为模块是针对特定内核版本编译的。这是内核升级里最容易翻车的地方。处理思路是这样的升级前先搞清楚有哪些第三方模块在运行# 查看当前加载的所有模块标记一下哪些不是系统自带的 lsmod # 查看模块文件路径如果是在 /lib/modules/xxx/extra 或 /lib/modules/xxx/updates 下就是第三方编译的 find /lib/modules/$(uname -r)/ -type f -name *.ko* | grep -E extra|updates对于这些第三方模块升级前要向厂商确认兼容性或者把源码准备好升级后重新编译。比较典型的像NVIDIA GPU驱动每次内核升级后基本都要重新编译。Anolis OS的软件源里其实有适配好的NVIDIA驱动包可以直接用dnf install nvidia-driver安装但生产环境用的话我还是建议走厂商官方支持渠道。另外有个小技巧如果某个第三方模块在新内核里编译不过去你可以临时加载旧内核的模块文件夹到新内核下试试。这不是正规做法但在应急场景下偶尔能救急。具体操作是# 找到旧内核模块目录 ls /lib/modules/ # 把旧内核模块软链接到新内核目录谨慎使用只能作为临时手段 ln -s /lib/modules/$(旧内核版本)/extra /lib/modules/$(新内核版本)/extra这个操作之后需要重新生成initramfs才能生效dracut -f但说真的这个应急方案问题很多特别是内核抽象层KABI不兼容的情况下强行加载旧模块可能导致内核崩溃建议不到万不得已不要用。4. 引导配置让新内核真正生效4.1 grubby管理引导项的神器内核装好了重启之前必须先做一件事确认新内核会被默认加载。如果不做配置重启后系统可能还是进入旧内核甚至直接进入救援模式如果引导配置损坏的话。Anolis OS 8系列使用的是GRUB 2引导器推荐的管理工具是grubby。这个工具比手动改grub.cfg安全得多它会自动处理很多细节。# 查看当前默认的内核引导项 grubby --default-kernel # 查看所有可用的内核引导项 grubby --infoALL # 设置新内核为默认引导项 grubby --set-default$(ls /boot/vmlinuz-* | tail -1) # 或者直接指定内核版本号 grubby --set-default/boot/vmlinuz-4.18.0-372.32.1.an8_6.x86_64grubby --infoALL的输出信息量很大它会列出每个内核引导项的索引、内核路径、initrd路径、启动参数等。执行过之后你能清楚看到新版内核的入口信息。4.2 手动调整GRUB配置文件虽然grubby很方便但有时候你也需要手动修改GRUB配置比如调整内核启动参数、修改默认超时时间等。GRUB 2的主配置文件路径是/etc/default/grub里面的内容大致如下[rootanolis ~]# cat /etc/default/grub GRUB_TIMEOUT5 GRUB_DISTRIBUTOR$(sed s, release .*$,,g /etc/system-release) GRUB_DEFAULTsaved GRUB_DISABLE_SUBMENUtrue GRUB_TERMINAL_OUTPUTconsole GRUB_CMDLINE_LINUXcrashkernelauto spectre_v2retpoline rhgb quiet GRUB_DISABLE_RECOVERYtrue常用的几个配置项含义GRUB_TIMEOUT开机时引导菜单等待时间单位是秒。生产环境建议设置成5秒既不影响开机速度也留了手动选择内核的时间。GRUB_DEFAULT默认启动项可以是saved记住上次选择、数字索引或具体的菜单项名称。GRUB_CMDLINE_LINUX内核启动参数。一般不需要动但如果你的服务器要调整某些内核参数比如关闭透明大页、调整IO调度器就是通过改这里实现的。修改完/etc/default/grub后记得重新生成grub配置grub2-mkconfig -o /boot/grub2/grub.cfg注意UEFI启动的机器输出路径不同grub2-mkconfig -o /boot/efi/EFI/anolis/grub.cfg怎么判断自己是BIOS还是UEFI启动看有没有/sys/firmware/efi目录[ -d /sys/firmware/efi ] echo UEFI || echo BIOS4.3 设置默认启动项与开机超时grubby设置默认内核以后默认启动项就变了。如果想确认是否设置成功可以执行grubby --default-kernel grubby --default-index其中一个细节值得注意如果/etc/default/grub里的GRUB_DEFAULTsaved那么系统每次启动时默认加载的内核是grubby --set-default指定的那个但如果你在GRUB菜单里手动选择了其他内核下次开机默认会记住你上次的选择。这个行为默认是saved模式造成的如果你希望无论上次选了啥每次开机都固定进某个内核可以把GRUB_DEFAULT改成具体的菜单项名称或索引数字。# 查看当前默认启动项对应的菜单名称 grubby --info$(grubby --default-kernel) | grep title # 将GRUB_DEFAULT设置为固定的菜单名称 sed -i s/^GRUB_DEFAULT.*/GRUB_DEFAULTAnolis OS (4.18.0-372.32.1.an8_6.x86_64) 8.6/ /etc/default/grub # 重新生成grub配置 grub2-mkconfig -o /boot/grub2/grub.cfg5. 升级后验证与回滚机制5.1 验证新内核是否正常运行重启之后第一件事就是确认系统是否正常跑起来了别急着高兴。我给自己定了一个检查清单# 1. 确认内核版本 uname -r # 2. 确认系统运行时间如果uptime很短说明重启过正常 uptime # 3. 查看系统日志里有没有内核报错 dmesg | grep -i error journalctl -k -b | grep -i error # 4. 确认关键模块加载正常 lsmod | grep -E ext4|xfs|virtio|e1000|igb|mlx # 5. 确认网络、文件系统、服务状态 systemctl status network mount | grep -E / | /boot有时候uname -r显示的确实是新内核但系统状态并不健康。我遇到过一种情况新内核起来了网络服务也重启了但SELinux上下文错乱导致很多服务无法正常启动。这种情况下通常要检查SELinux的状态甚至可能需要用touch /.autorelabel触发文件系统重新打标签。5.2 应用兼容性验证清单系统层面没问题不代表应用层面没问题。内核升级后影响最大的几个应用层面是第一容器运行时。如果你在跑Docker或Kubernetes要重点关注cgroup版本和iptables规则的兼容性。新内核默认可能启用了cgroup v2取决于内核编译选项而旧版本的Docker不一定支持cgroup v2。验证的方式是docker info | grep -i cgroup cat /sys/fs/cgroup/cgroup.controllers第二数据库和中间件。MySQL、Java应用这些对内核参数比较敏感比如TCP拥塞控制算法、透明大页THP设置。升级后建议观察一段时间业务指标对比升级前后的CPU、内存、IO性能数据。第三安全软件和监控agent。很多安全软件会加载内核模块或者依赖特定的syscall行为内核升级后它们可能无法正常工作。我的建议是升级前就跟安全团队或厂商确认好兼容性。5.3 出问题怎么回滚如果新内核有问题也不能慌。回滚的思路其实很简单重启时在GRUB菜单里选择旧内核或者用grubby重新设置旧的默认内核。重启机器后在GRUB引导菜单界面快速按下方向键或Esc键不同版本按键不同进入菜单选择界面用上下键选中旧内核那一项回车启动。如果你人能进系统但想永久切回旧内核# 查看当前已有内核版本 grubby --infoALL | grep -E ^kernel|^title # 设置旧内核为默认引导项 grubby --set-default/boot/vmlinuz-4.18.0-372.19.1.an8_5.x86_64 # 确认已切换 grubby --default-kernel如果新内核启动后系统都不稳定没法正常进系统那你只能在GRUB菜单里选择旧内核启动然后重新执行grubby --set-default切回去。回滚之后建议先不要把新内核的rpm包删掉留着观察一段时间。确认没问题后再清理旧内核包或者决定是否重新升级。6. 常见问题与排查技巧实录6.1 重启后网络不通这个是我遇到频率最高的问题。新内核起来了但网络不通SSH完全连不上只能在控制台上操作。排查思路如下# 查看网卡是否识别 ip link show # 查看网卡驱动是否加载 ethtool -i eth0 # 查看NetworkManager状态 systemctl status NetworkManager # 如果网卡没起来手动拉起试试 ip link set eth0 up dhclient eth0大部分情况下网络不通是因为内核升级后网卡驱动模块没有自动加载。解决方法是找到匹配的驱动模块手动加载modprobe igb # 以Intel I350为例如果驱动的确不存在那就得回到旧内核启动然后安装或编译匹配的驱动模块。6.2 dracut生成的initramfs有问题新内核安装后默认会自动运行dracut生成initramfs文件。但如果dracut配置有问题或者某些驱动模块没打进去启动时就会出现mount: could not find root device之类的报错。遇到这种情况先别慌从GRUB菜单进旧内核然后手动重建initramfs# 重建当前默认内核的initramfs dracut -f # 重建指定内核版本的initramfs dracut -f /boot/initramfs-4.18.0-372.32.1.an8_6.x86_64.img 4.18.0-372.32.1.an8_6.x86_64重建完成后再切回新内核启动一次。如果还是报mount root失败大概率是根文件系统所在磁盘的驱动比如nvme、sata、virtio驱动没进initramfs此时需要检查/etc/dracut.conf配置确保必要的驱动被纳入。6.3 旧内核清理与磁盘空间管理系统里堆积了大量旧内核后/boot分区很容易告警。Anolis OS 8系列默认有installonly_limit限制系统里最多保留3个内核包超过会自动清理。默认值虽然省心但我建议在生产环境改成5留出更多回滚余地。# 查看当前installonly_limit值 grep installonly_limit /etc/dnf/dnf.conf # 修改为5在/etc/dnf/dnf.conf中追加 echo installonly_limit5 /etc/dnf/dnf.conf手动清理旧内核只保留当前用的和最新的一个# 查看已安装的内核包 rpm -qa | grep ^kernel # 删除指定旧版本注意不要删除当前运行的内核版本 dnf remove kernel-4.18.0-372.19.1.an8_5.x86_64这里有个血泪教训手动删除内核包的时候一定要看清楚当前uname -r的版本别把自己正在用的内核给删了。我见过有同事手一抖把正在跑的版本删了结果系统直接没法引导。如果真发生这种情况只能通过光盘救援模式把内核包重装回去。6.4 升级到新内核后性能反而下降这种情况一般出现在有特殊硬件或特殊应用场景的机器上。新内核默认启用的特性可能不适用于你的业务比如新内核默认开启的CPU频率调节策略、内存管理策略、透明大页选项等。这时候排查思路是先用以下命令看看当前内核参数# 查看CPU调频策略 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # 查看透明大页状态 cat /sys/kernel/mm/transparent_hugepage/enabled # 查看TCP拥塞控制算法 sysctl net.ipv4.tcp_congestion_control根据业务场景通过修改启动参数或运行时sysctl调整策略。比如对延迟敏感的数据库应用可以禁用透明大页echo never /sys/kernel/mm/transparent_hugepage/enabled如果要永久生效就加到内核启动参数里grubby --update-kernelALL --argstransparent_hugepagenever6.5 一个额外的建议先在测试环境跑一遍最后真心建议一句内核升级这种事千万别拿生产环境当第一个实验对象。有条件的先在测试环境或者一台业务量小的机器上完整走一遍流程包括升级、重启、验证、回滚测试确认没问题了再逐步扩大范围。我自己维护的服务器有上百台每次内核升级的节奏都是先在测试机跑一遍观察48小时然后在非核心业务机器上跑再观察48小时最后才轮到核心业务机器。这套节奏看起来慢但其实是最省时间的方式——因为出一次生产事故的时间够你按这个节奏跑好几轮了。个人经验是Anolis OS的内核升级在整个Linux发行版里算是比较平滑的毕竟它跟RHEL 8的体系一脉相承rpm包管理和grub配置的逻辑都是标准的只要你按照“查询现状-准备备份-安装内核-设置引导-重启验证-准备回滚”这条主线走下来基本上不会出大问题。最后再分享一个小技巧升级完内核后别急着删旧内核至少保留两个可用版本这是你系统稳定运行的最后一道安全网。