在CentOS 7或CentOS 8的生产环境中,配置yum-cron实现无人值守的安全更新,是运维工作的基本要求。但这里有一个很棘手的痛点:如果你直接开启全量自动更新,一旦Linux内核被自动升级,系统可能会在某个深夜重启后,因新内核与现有驱动或应用不兼容而直接挂掉,连带着业务中断。所以,我们需要让系统自动打补丁,但必须精准地排除内核包以及相关的开发包。这件事的核心,就在于如何正确配置yum-cron的排除规则,而不是简单地在命令行里加个参数。
理解yum-cron与常规yum命令的区别很多运维人员会下意识地认为,在/etc/yum.conf里配置了exclude,yum-cron就会自动生效。这个认知只对了一半。yum-cron在运行时确实会读取yum主配置文件,但它有自己独立的配置体系,位于/etc/yum/yum-cron.conf。如果你只改了/etc/yum.conf,而yum-cron.conf里没有同步修改,或者两者冲突,自动更新任务依然会把内核全家桶给你装上去。更关键的是,yum-cron的排除机制支持更细粒度的控制,可以针对不同的更新类型(安全更新、全部更新)设置不同的排除策略。
第一步:定位并编辑yum-cron的核心配置文件我们先要找到正确的配置文件。在CentOS 7上,默认安装yum-cron后,主配置文件就是/etc/yum/yum-cron.conf。在CentOS 8上,由于底层包管理器变成了dnf,对应的服务通常是dnf-automatic,配置文件位于/etc/dnf/automatic.conf,但很多习惯用法上仍沿用yum-cron这个包名。本文以CentOS 7环境为例,因为目前仍有大量存量服务器运行着CentOS 7,这个问题出现的频率最高。用你熟悉的编辑器打开它:
vi /etc/yum/yum-cron.conf
打开后,你会看到几个配置段,分别是[commands]、[emitters]、[email]、[groups]和[base]。我们重点关注[base]这一段,因为排除包的规则就在这里设置。
第二步:使用exclude参数精准排除内核包在[base]段中,你会看到一行被注释掉的exclude参数。默认情况下它可能是这样的:
# exclude=
你需要去掉注释,并填入需要排除的包名通配符。针对内核包,最稳妥的写法是同时排除kernel、kernel-core、kernel-devel、kernel-headers、kernel-tools以及它们的所有变体。注意,CentOS 7和CentOS 8的包命名略有不同,但用通配符可以一次性覆盖。建议的配置如下:
exclude=kernel* kernel-core* kernel-devel* kernel-headers* kernel-tools* kernel-modules* linux-firmware*
这里解释一下为什么要把linux-firmware也加进去。某些内核更新会依赖新版本的固件包,如果你只排除了内核本身,固件包仍然可能被更新,虽然不会导致内核版本变化,但某些硬件在固件更新后可能出现异常,为了最大程度保持系统稳定,一并排除是更安全的做法。另外,kernel-modules这个包在CentOS 8中比较常见,也建议加上。
第三步:确保update_cmd参数与你预期一致在同一个[base]段里,还有一个参数叫update_cmd,它决定了yum-cron执行哪种类型的更新。可选值有default、security、security-severity:Critical和minimal。很多人以为设置成security就只会更新安全补丁,内核安全补丁就不会被装上了。实际上,内核安全更新同样属于安全更新范畴,如果你只设置update_cmd=security而不配置exclude,内核安全补丁照样会被打上。所以,update_cmd和exclude必须配合使用。对于追求极致稳定的生产环境,建议设置为:
update_cmd = security
这样配合上面的exclude规则,系统就只会安装非内核相关的安全补丁,既保证了安全性,又避免了内核变动带来的重启风险。
第四步:处理yum.conf与yum-cron.conf的冲突还有一个容易被忽略的细节:/etc/yum.conf里也可能配置了exclude。yum-cron在运行时,会合并这两个配置文件中的exclude值,但合并逻辑是取并集。也就是说,如果yum.conf里排除了某个包,yum-cron.conf里没有排除,最终结果仍然是排除。反过来,如果yum.conf里没有排除,yum-cron.conf里排除了,结果也是排除。这个逻辑本身没问题,但问题出在运维人员排查故障时,往往会忘记自己曾经在yum.conf里加过排除规则,导致yum-cron的行为和预期不一致。所以,建议你在配置完yum-cron后,用以下命令验证一下最终的排除列表:
yum repolist yum list updates --exclude=kernel*
更直接的方法是模拟一次yum-cron的运行,查看日志输出。你可以手动执行yum-cron的脚本:
/usr/sbin/yum-cron
然后检查/var/log/yum.log,看看是否有内核包被标记为更新。如果日志里没有出现kernel相关的包名,说明排除规则已经生效。
第五步:配置自动重启策略,避免内核残留虽然我们排除了内核包,但yum-cron还有一个参数与系统重启相关,那就是random_sleep和apply_updates。如果你之前没有正确配置exclude,系统可能已经下载了新内核,只是还没有重启生效。此时,你需要手动清理旧内核,并确保grub引导项指向正确的内核版本。建议在配置完排除规则后,顺手执行一次旧内核清理:
package-cleanup --oldkernels --count=1
这条命令会保留当前正在运行的内核以及最新的一个内核,删除其余旧版本。同时,检查/etc/yum/yum-cron.conf中的apply_updates参数,确保它设置为yes:
apply_updates = yes
这样,非内核的安全补丁会在下载后自动安装,而内核包因为被排除在外,不会被下载和安装。另外,random_sleep参数可以设置一个随机延迟,避免所有服务器在同一时刻连接更新源造成拥堵,建议设置成360分钟或更长,让更新分散在一天内的不同时段。
第六步:针对CentOS 8及dnf-automatic的特殊说明如果你使用的是CentOS 8或后续的Rocky Linux、AlmaLinux,包管理器变成了dnf,自动更新服务也相应变成了dnf-automatic。它的配置文件在/etc/dnf/automatic.conf,配置逻辑几乎一样,只是段名变成了[commands]、[emitters]和[base]。排除包的写法完全相同:
exclude=kernel* kernel-core* kernel-devel* kernel-headers* kernel-tools* kernel-modules*
注意,dnf-automatic的定时任务是通过systemd timer触发的,你可以用systemctl status dnf-automatic.timer查看定时器状态。如果发现自动更新没有按预期运行,除了检查配置文件,还要确认timer是否被正确启用:
systemctl enable dnf-automatic.timer --now
另外,dnf的缓存机制和yum略有不同,修改配置后建议执行dnf clean all清理缓存,确保新的排除规则立即生效。
第七步:建立监控与告警机制即使配置了排除规则,也不代表可以高枕无忧。内核包被排除后,系统会一直停留在当前内核版本,如果这个内核本身存在严重安全漏洞,你就需要人工介入,在测试环境验证新内核兼容性后,手动升级。因此,建议在监控系统中添加对内核版本和可用更新的监控项。你可以通过一条简单的命令获取当前可用的内核更新数量:
yum list updates kernel* 2>/dev/null | grep -c kernel
如果返回值大于0,说明有内核更新可用但被排除了,此时监控系统应该发出告警,提醒运维人员关注。这种告警不要设置成紧急级别,而是作为信息提醒,因为内核更新需要人工决策,不能自动执行。
常见误区与排错思路很多人在配置完yum-cron后,发现内核还是被更新了,排查下来通常有以下几个原因:一是yum-cron.conf里的exclude写错了包名,比如写成了kernel而不带通配符,这样只能排除名为kernel的主包,无法排除kernel-devel等子包;二是yum-cron服务没有重启,配置文件修改后必须重启服务或等待下一次定时任务触发;三是系统中同时存在yum-cron和cronie定时任务,某个自定义脚本直接调用了yum update -y,绕过了yum-cron的配置;四是/etc/yum.repos.d/下面有第三方源,第三方源里的内核包命名规则不同,通配符没有覆盖到。针对最后一种情况,你可以先用yum list available | grep kernel命令查看所有可用的内核相关包,确认它们的完整包名,再回头调整exclude规则。
总结与最佳实践在CentOS系统中使用yum-cron实现自动更新的同时排除内核包,核心操作就是在/etc/yum/yum-cron.conf的[base]段中设置exclude参数,并使用kernel*等通配符覆盖所有内核相关包。同时,将update_cmd设置为security,只自动安装安全补丁。配置完成后,通过查看日志和模拟运行来验证排除规则是否生效。对于CentOS 8及以上系统,配置思路完全一致,只是配置文件和命令略有不同。最后,建立监控告警,确保被排除的内核更新能够被及时感知,由人工在测试验证后手动升级。这样一套组合拳下来,你的服务器既能在无人值守的情况下保持安全补丁的及时更新,又不会因为内核自动升级而面临意外重启和兼容性风险。
