说实话,第一次遇到 AlmaLinux 黑屏进不去系统的我,心态也崩过。毕竟从 CentOS 转过来没多久,以为换汤不换药,结果服务器突然“罢工”,SSH 连不上,控制台一片黑或者卡在启动界面,真的让人头皮发麻。但别慌,咱们一步步来,就像修车一样,先听声音、看仪表盘,再拆引擎盖。今天这篇,我就把自己踩过的坑、查过的文档、试过的命令,全部掏出来,帮你把 AlmaLinux 磁盘满、服务起不来、黑屏蓝屏这些问题讲得明明白白。
先说个真实场景:上周二凌晨三点,我收到监控告警,一台生产环境的 AlmaLinux 9 服务器 CPU 飙升到 100%,然后 SSH 直接超时。第二天早上上班,运维同事打电话说,开机后界面卡在“Welcome to Dracut emergency shell”这个黑屏状态,输入 root 密码进去,发现磁盘空间满了,关键服务 systemd-journald 起不来,整个系统处于半死不活的状态。那一刻,我真想砸键盘。但后来冷静下来,梳理清楚,发现其实核心问题就一个——磁盘满了。其他都是连锁反应。所以,今天咱们先从最根源的地方讲起。
一、先理解 AlmaLinux 的启动流程,才能知道黑屏卡在哪
很多人看到黑屏就慌,但不知道系统在哪个阶段“死了”。AlmaLinux 基于 RHEL,启动流程其实挺规范的。咱们先快速过一遍,这样后面排查才有方向。
系统通电后,BIOS/UEFI 自检,然后加载 GRUB 引导器。GRUB 会显示一个菜单,如果你没改动过,通常 5 秒后自动进入默认内核。内核加载后,会挂载根文件系统,然后启动 systemd。systemd 是 init 系统的替代,它负责启动各种服务、挂载点、目标(target)。正常情况,systemd 跑完后,就会进入登录界面或者命令行。
那黑屏/蓝屏一般卡在哪几个点呢?
- 内核加载阶段:如果内核参数错了,或者硬盘驱动有问题,可能连 GRUB 都进不去,直接黑屏。
- 文件系统挂载阶段:这是最常见的!如果
/etc/fstab里有个分区挂载错误,或者磁盘坏了,systemd 会进 dracut emergency shell,也就是你看到的那个黑屏界面,让你手动修复。 - 服务启动阶段:文件系统挂上了,但某个关键服务(比如 network、sshd、或某个应用)启动失败,可能会卡住或者自动回退到 emergency shell。
- 登录阶段:服务都起来了,但图形界面(如果装了 GNOME)起不来,或者 SSH 服务没启动,你远程连不上,本地看也是黑屏。
所以,遇到黑屏,别急着敲命令,先观察。看屏幕提示,看键盘大小灯(NumLock、CapsLock)有没有反应,判断是不是系统还活着。如果完全死锁,那可能是硬件问题,但咱们今天主要讲软件和磁盘问题。
二、磁盘满:最常见的“隐形杀手”
回到刚才的场景。那位同事进去后,用 df -h 一看,/ 根分区用了 100%。瞬间就明白了。但问题来了:为什么会满?满了之后系统怎么就崩了?咱们细说。
1. 为什么磁盘满了系统会黑屏?
很多人以为磁盘满了,顶多是存不下文件。其实不然。Linux 系统运行时,大量依赖磁盘空间。比如:
- 系统日志:
systemd-journald把日志存到/var/log/journal,如果日志文件爆炸,磁盘就满了。 - 临时文件:
/tmp和/var/tmp里堆积的临时文件。 - 包管理器缓存:
dnf或yum下载的 rpm 包缓存,在/var/cache/dnf。 - 核心转储:程序崩溃时产生的 core dump,默认可能存到根分区。
- 用户数据:有时候开发团队忘了清理旧的备份、虚拟机镜像、日志文件,不知不觉就把磁盘塞满了。
当磁盘使用率到 100% 时,系统会出现一系列诡异问题:
- systemd 无法启动服务:因为 systemctl 启动服务时,需要写一些状态文件,磁盘满了,写不进去,服务就起不来。
- SSH 无法登录:sshd 需要写日志、锁文件,磁盘满就失败了。
- 内核模块加载失败:一些动态加载的模块,需要临时空间。
- 文件系统只读:ext4 或 xfs 在检测到严重问题时,可能自动挂载为只读,防止数据损坏。这时候你连
df都执行不了,黑屏就更严重了。
所以,磁盘满不是小事,它是系统崩溃的常见诱因。
2. 进入紧急模式后,怎么确认是磁盘满?
回到那个黑屏界面,你会看到类似这样的提示:
dracut-058:~#
这是 dracut emergency shell。输入 root 密码(如果设了的话)进入。然后执行:
mount
看看根文件系统是不是挂载上了。如果显示是只读的(ro),那可能已经出问题了。然后执行:
df -h
如果看到 / 或 /var、/home 使用率 100%,那就确诊了。
但有时候,df -h 也可能报错,因为根本文件系统只读。这时候你可以尝试:
mount -o remount,rw /
把根文件系统重新挂载为读写模式,然后再执行 df -h。如果还是不行,可能需要用 lsblk 看看磁盘分区情况,确认是不是磁盘本身坏了。
3. 清理磁盘空间:核心技巧
确认磁盘满后,第一步是清理。但别瞎删,得找到大文件在哪里。以下命令帮你快速定位:
查看各分区使用情况:
df -h
找到根目录下哪个文件夹占用最多:
sudo du -sh /* 2>/dev/null | sort -hr
这个命令会列出根目录下所有一级文件夹的大小,并按大小降序排列。注意,2>/dev/null 是屏蔽权限错误,让你看得更清爽。
深入排查某个大文件夹:
比如,发现 /var 很大,那就:
sudo du -sh /var/* 2>/dev/null | sort -hr
查找大于 100MB 的文件:
sudo find / -type f -size +100M 2>/dev/null
这个命令会遍历整个文件系统,找出所有大于 100MB 的文件。你可能会发现一些可疑的大文件,比如 /var/log/messages-20230101 这种旧的日志压缩文件,或者 /home/user/backup.tar.gz 这种没人要的大包。
清理常见的“垃圾”:
- 清理 systemd 日志:
sudo journalctl --vacuum-size=100M
这条命令会把 systemd 日志限制在 100MB 以内。你也可以用 --vacuum-time=7d 只保留最近 7 天的日志。
- 清理 dnf 缓存:
sudo dnf clean all
- 清理临时文件:
sudo rm -rf /tmp/* /var/tmp/*
注意,删 /tmp 时要小心,有些服务可能正在使用临时文件。最好先 ls 看一下。
- 查找并删除大文件:
比如,发现 /var/log 下有巨大的日志文件:
sudo ls -lhS /var/log
按大小排序,然后删除旧的:
sudo rm /var/log/old.log.gz
或者,如果某个应用日志太大,可以截断它,而不是直接删:
sudo truncate -s 0 /var/log/app.log
这样应用还能继续写日志,但空间释放了。
4. 如果磁盘满是因为 inode 满了呢?
有时候 df -h 显示空间还有,但 df -i 显示 inode 使用率 100%。inode 是文件系统的小元数据,每个文件占一个 inode。如果目录下有几百万个小文件(比如邮件队列、临时会话),可能会把 inode 用光。
检查 inode 使用率:
df -i
如果 inode 满了,你需要找到哪个目录 inode 最多:
sudo find / -xdev -type f -printf '%h\n' | sort | uniq -c | sort -n | tail -20
这个命令会列出 inode 使用最多的前 20 个目录。然后,你可以进入那个目录,删除多余的小文件,或者把文件合并成大文件。
三、服务起不来:连锁反应的处理
磁盘清理后,系统应该能正常启动了。但有时候,即使磁盘有空闲了,某些服务还是起不来。这可能是因为磁盘满期间,服务状态文件损坏,或者依赖关系乱了。
1. 检查关键服务状态
进入系统后,先检查几个核心服务:
systemctl status systemd-journald
systemctl status sshd
systemctl status network
如果某个服务失败,查看详细日志:
journalctl -u sshd -n 50 --no-pager
-n 50 显示最近 50 条日志,--no-pager 避免分页,方便阅读。
2. 常见服务起不来的原因
- sshd 起不来:可能是配置错误,或者磁盘满导致密钥文件权限问题。尝试:
sudo sshd -t
测试配置文件语法。如果没问题,重启服务:
sudo systemctl restart sshd
- network 起不来:可能是网络配置文件损坏,或者磁盘满导致网卡状态文件丢失。检查:
sudo nmcli device status
sudo nmcli connection show
看看网卡和连接状态。如果异常,可以重启 NetworkManager:
sudo systemctl restart NetworkManager
- systemd-journald 起不来:这可能是日志目录权限问题。检查:
ls -ld /var/log/journal
确保所有者是 systemd-journal 或 root,权限正确。然后:
sudo systemctl restart systemd-journald
3. 如果服务启动循环失败怎么办?
有时候,服务会反复重启失败,log 里一堆报错。这时候,可以用 systemctl list-units --failed 查看所有失败的服务。然后,针对每个服务,查看它的依赖:
systemctl list-dependencies --reverse sshd.service
看看哪些服务依赖于 sshd,也许问题出在依赖上。
四、预防:避免再次踩坑
清理完、修好后,别高兴太早。得想想怎么预防下次再出现类似问题。
1. 监控磁盘使用率
装个监控工具,比如 prometheus + node_exporter,或者简单的 df 脚本告警。我推荐写个 crontab 任务,每天检查一次,超过 85% 发邮件告警:
#!/bin/bash
THRESHOLD=85
USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "Disk usage on $(hostname) is at ${USAGE}%" | mail -s "Disk Alert" your@email.com
fi
保存为 disk_check.sh,然后加到 crontab:
crontab -e
加入:
0 8 * * * /path/to/disk_check.sh
这样每天早上 8 点检查一次。
2. 定期清理
别等磁盘满了再清理。定期执行清理任务:
sudo dnf clean all
sudo journalctl --vacuum-time=7d
sudo find /tmp -type f -mtime +7 -delete
可以做成 weekly cron job。
3. 合理划分分区
如果是新装系统,建议把 /var、/home 单独分区。这样即使 /var 日志爆炸,也不会影响根分区和其他用户数据。AlmaLinux 安装时,可以选择自定义分区方案。
4. 设置磁盘配额
对于多用户环境,可以启用磁盘配额,限制每个用户的磁盘使用量。但这需要文件系统支持(ext4、xfs 都支持),并且在安装或后期启用。
五、进阶:如果磁盘满了,但紧急模式下无法写入
有时候,磁盘满到连 emergency shell 都写不进去。这时候,你可以尝试以下方法:
1. 使用救援模式
重启服务器,在 GRUB 菜单按 e 编辑启动项,找到 linux 那行,在末尾加上 rd.break,然后按 Ctrl+x 启动。这会进入救援模式,你可以挂载根文件系统并清理。
2. 临时挂载一个空目录
如果根分区满了,你可以把 /tmp 或 /var/tmp 临时挂载到一个内存文件系统(tmpfs)上,释放一些空间:
sudo mount -t tmpfs tmpfs /tmp
这样,临时文件会写到内存里,根分区压力减轻。但注意,内存有限,只是临时方案。
3. 使用远程控制台
如果服务器是云上的(比如阿里云、AWS),通常有 VNC 远程控制台。你可以直接通过浏览器访问控制台,操作 emergency shell,而不依赖 SSH。
六、真实案例分享:我那次凌晨三点的救援
回到开头说的案例。当时,我 SSH 连不上,只能靠云控制台的 VNC 进去。进去后,黑屏显示 dracut emergency shell。我输入 root 密码,进入后执行 df -h,发现 / 100% 使用率。然后执行 du -sh /*,发现 /var/log 占了 80GB。进一步查看,发现一个应用日志文件 app.log 每天增长 10GB,而且没有日志轮转配置。我立刻截断这个文件:
sudo truncate -s 0 /var/log/app.log
然后重启 systemd-journald 和 sshd:
sudo systemctl restart systemd-journald
sudo systemctl restart sshd
接着,我检查了应用的日志配置,发现开发者忘了配置 logrotate。我帮他写了一个 logrotate 配置,放在 /etc/logrotate.d/app:
/var/log/app.log {
weekly
rotate 4
compress
missingok
notifempty
copytruncate
}
这样,每周日志会轮转,保留 4 份,压缩旧日志。最后,我清除了其他垃圾文件,释放了 50GB 空间。系统恢复正常,我也能 SSH 进去了。
事后,我给团队写了个文档,强调新应用上线必须配置日志轮转,并且设置磁盘监控告警。不然,下次再黑屏,可能就不是凌晨三点,而是业务高峰期了。
七、总结:遇到问题,冷静排查
AlmaLinux 黑屏、磁盘满、服务起不来,听起来吓人,但核心逻辑很清晰:
- 先观察:黑屏时看提示,判断卡在哪个阶段。
- 再诊断:进入紧急模式,用
df、du、systemctl等工具定位问题。 - 后清理:找到大文件,合理清理,别盲目删除。
- 防未然:监控、定期清理、合理分区,避免再次发生。
记住,Linux 系统虽然稳定,但也不是铁打的。磁盘满这种问题,往往是因为疏忽。作为运维或开发者,养成定期检查、及时清理的习惯,比出事后再救火更重要。
希望这篇详解能帮你解决 AlmaLinux 的黑屏、磁盘满问题。如果还有疑问,欢迎留言讨论。毕竟,咱们都是从踩坑中成长的。
