🚨 事发:凌晨8点的告警
早上刚到公司,手机就开始疯狂震动。登录服务器一看, top 命令的输出让人血压飙升:
top - 08:09:32 up 1355 days, 19:35, 0 users, load average: 9.54, 6.21, 4.31
1355天(3年8个月)未重启的 CentOS 7 服务器,负载飙到 9.54,内存使用率 83%,而罪魁祸首是一个看似人畜无害的系统进程——polkitd。
更离谱的是内存占用排名:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 16061 polkitd 20 0 16.5g 15.5g 2184 S 2.3 25.0 12906:21 /usr/lib/polkit-1/polkitd --no-debug
一个系统守护进程,竟然吞掉了 15.5GB 物理内存(占总内存 25%)!这已经不是简单的"占内存"了,这是典型的内存泄漏(Memory Leak)。
🔍 诊断:三重致命打击
通过 rpm -qa 检查,确认了更可怕的事实:
polkit-0.112-26.el7_9.1.x86_64
polkit 0.112,CentOS 7 默认版本,存在已知且无法通过配置修复的内存泄漏漏洞。
当前系统面临的三重危机:
更糟的是,这台服务器还跑着 AnyBackup 备份服务(esfdaemon),本身就需要 14GB 内存。两个"内存大户"叠加,系统已处于崩溃边缘。
⚡ 急救:不重启系统的"微创手术"
好消息:polkitd 可以在线重启,无需重启服务器,不影响现有 SSH 连接和业务进程。
坏消息:如果操作不当,可能导致短暂的认证中断。
立即止损(3步走)
Step 1: 确认安全窗口
# 检查是否有特权操作在进行whow# 查看 polkit 版本确认漏洞存在rpm -qa | grep polkit # 输出 0.112 即为漏洞版本
Step 2: 优雅重启
# 记录重启前状态systemctl status polkit > /tmp/polkit_status_before.log# 执行重启(会立即释放15GB内存)systemctl restart polkit# 验证新进程状态ps aux | grep polkitd
Step 3: 效果确认
# 内存应降至 30MB 以下(正常范围)systemctl status polkit# 重点关注:Memory 字段
重启后,polkitd 内存从 15.5GB 降至约 20-40MB,系统可用内存瞬间从 1.3GB 回升至 16GB+,负载开始下降。
🛠️ 根治:防止悲剧重演
单次重启治标不治本,0.112 版本会继续泄漏。两个长期方案:
方案 A:升级到 0.113+(完美解决)
# 检查官方源是否有更新yum update polkit --changelog# 如有更新直接升级yum update polkit -y
方案 B:定期重启(稳妥兜底)
创建监控脚本,防止泄漏累积:
cat > /opt/scripts/polkit_guard.sh << 'EOF'#!/bin/bash# Polkit 内存守护脚本# 当内存超过 200MB 时自动重启MEMORY=$(systemctl show polkit --property=MemoryCurrent | cut -d= -f2)if [ "$MEMORY" -gt 209715200 ]; then logger "ALERT: Polkit memory ${MEMORY} bytes, restarting..." systemctl restart polkitecho"$(date): Polkit restarted due to high memory" >> /var/log/polkit_monitor.logfiEOFchmod +x /opt/scripts/polkit_guard.sh# 加入定时任务(每天凌晨3点检查)echo"0 3 * * * /opt/scripts/polkit_guard.sh" | crontab -
📋 复盘:运维人的 checklist
这次故障暴露了几个经典运维陷阱:
- 忽视系统进程:总以为只有业务应用才会内存泄漏,忽略了基础组件漏洞
- 追求"永不重启":1355天的 uptime 不值得炫耀,可能是颗定时炸弹
- 监控盲区:只监控了业务进程,没监控
polkitd、systemd-journald 等系统进程内存
建议加入监控体系的关键指标:
# 系统进程内存监控脚本片段checks="polkitd systemd-journald rsyslogd"for proc in$checks; do pid=$(pgrep -x $proc)if [ -n "$pid" ]; then mem=$(ps -o rss= -p $pid | awk '{print $1/1024}')if (( $(echo"$mem > 100" | bc -l) )); thenecho"WARNING: $proc using ${mem}MB memory"fifidone
💡 结语
在 Linux 运维中,"稳定运行"不等于"健康运行"。那个 quietly 吃掉你 15GB 内存的 polkitd,可能就是下次凌晨告警的元凶。
记住:及时的维护重启,比追求虚无的 uptime 记录更重要。
如果你也在用 CentOS 7/RHEL 7,赶紧检查一下你的 polkit 版本:
systemctl status polkit --no-pager | grep Memory
别让 15GB 内存泄漏,在你的服务器里默默生长。
延伸阅读:
- Red Hat Bugzilla: polkit memory leak in version 0.112
本文基于真实生产环境故障整理,代码经过实测,请放心食用。
作者:运维老司机公众号:敢拼才有可能赢原创文章,转载请联系作者