从开机卡死到服务崩溃 AlmaLinux系统故障排查完全指南
嘿,朋友。如果你正在这里找答案,大概率是遇到了系统启动卡在黑屏或者某个服务莫名其妙地挂了。别慌,这种事情在Linux世界里太常见了,就连我当年折腾第一台服务器的时候,也对着终端屏幕发呆过好几个小时。
今天咱们就聊聊AlmaLinux这系统,把从开机卡死到服务崩溃这一路的排查方法,掰开揉碎讲给你听。
开机卡死的那些事儿
先分清是哪儿卡住了
AlmaLinux开机这个过程,其实是由几个环节串起来的。你卡住了,得先知道卡在哪儿。
第一个卡点,往往在BIOS/UEFI自检那儿。这时候你还没见到任何文字,可能屏幕直接黑了,或者卡在厂商logo那儿不动。这种情况八成是硬件问题——内存条松了、硬盘没接好、或者什么外设捣乱。
我遇到过一次,新加了根内存,结果开机就卡在厂商logo,怎么按键盘都没反应。后来把内存拔了插上,再试就好了。这种问题,排查顺序应该是:先断电,拔掉所有不必要的USB设备,只留键盘显示器,重新插拔内存和硬盘。
卡在GRUB引导界面
如果能到GRUB菜单了,说明硬件基本没问题。这时候卡住,可能是内核加载出问题。
你想想,GRUB是干嘛的?它就是个引导加载器,负责把控制权交给内核。如果这时候卡住,通常是内核镜像有问题,或者initramfs(初始内存文件系统)不完整。
这种情况,最直接的办法就是进单用户模式。GRUB菜单按’e’编辑启动项,找到linux16或者kernel那行,在末尾加上rd.break,然后Ctrl+X启动。这样系统会加载内核,但不会继续后面的启动流程,而是给你一个root提示符。
# 进入rd.break后的操作示例
switch_root:/# mount -o remount,rw /sysroot
switch_root:/# chroot /sysroot
sh-5.1# echo "hello" > /etc/motd
sh-5.1# touch /.autorelabel
sh-5.1# exit
switch_root:/# exit
注意那个touch /.autorelabel,这步很关键。因为你在chroot环境里改了文件系统,SELinux的标签需要重新计算,否则启动可能又出问题。不加这个,系统可能还是起不来。
启动过程中卡住——看日志是最靠谱的
如果GRUB之后还能看到滚动文字,然后突然不动了,那通常是某个服务启动失败,或者某个进程hang住了。
这时候别瞎猜,看日志。但是问题来了——系统都起不来,日志在哪儿?
AlmaLinux用的是journald,日志存在/tmp或者/var/log/journal里。如果系统没完全启动,你可以按Ctrl+Alt+F2到F6切到TTY终端,如果能进的话,直接用journalctl查。
# 查看系统启动以来的所有日志
journalctl -b
# 只看上一次启动的日志(当前启动失败时用这个)
journalctl -b -1
# 只看错误和警告
journalctl -p err -b
# 查看某个服务的启动日志
journalctl -u sshd -b
如果连TTY都进不去,那就得用更原始的方法了。重启系统,在GRUB菜单选高级选项,找一个内核版本,后面加break=premount,这样系统会在挂载根文件系统之前停下来,你可以手动挂载根分区,然后去读日志。
# 手动挂载根分区查看日志
mount /dev/mapper/alma-root /mnt
cat /mnt/var/log/journal/*/system.journal | journalctl -F _PID=1
文件系统检查
有时候卡死是因为文件系统坏了。AlmaLinux默认用ext4或者xfs,启动过程中会fsck检查。如果检查失败或者卡住,可能是磁盘有问题。
这种情况下,你可以通过init=选项来跳过自动检查,然后手动检查。
# GRUB启动项末尾加
init=/bin/bash
# 挂载根分区为只读,避免进一步损坏
mount -o remount,ro /
# 手动检查文件系统(xfs为例)
xfs_repair /dev/mapper/alma-root
# 如果是ext4
e2fsck -f /dev/mapper/alma-root
注意,xfs_repair前一定要确保文件系统没有挂载,或者至少是只读挂载。不然可能造成数据损坏。
服务崩溃的排查逻辑
systemd服务挂了的正常姿势
AlmaLinux用systemd管理服务。服务崩溃了,systemd会记录日志,你也应该习惯用systemctl和journalctl来查。
先说个最常见的场景:你启动一个服务,它挂了。
# 查看服务状态,会告诉你是不是active,还是failed
systemctl status nginx
# 或者更详细一点
systemctl status nginx --no-pager
输出里会有一行说”Started nginx…“然后马上变成”Failed”。这时候你应该看日志:
# 看这个服务的详细日志
journalctl -u nginx -n 100 --no-pager
大多数时候,日志里会有明确错误。比如nginx配置写错了,日志会说”syntax error”;比如端口被占了,会说”bind() failed”。
资源耗尽导致的服务崩溃
有时候服务不是自己坏的,是被系统资源挤兑死的。
比如内存不够用了,OOM killer会挑一个进程杀掉。被杀的那个进程,systemd会标记为failed,但根本原因是内存不足。
# 查看OOM事件
dmesg | grep -i oom
# 或者看内核日志
journalctl -k | grep -i oom
输出长这样:
Out of memory: Killed process 12345 (java) total-vm:8000000kB, anon-rss:4000000kB
这就很明显了,有个Java进程被OOM killer干掉了。这时候你要想的是:为什么Java会吃这么多内存?是配置问题还是真的有那么多数据要处理?
再比如磁盘空间满了。很多服务写日志写到满盘,然后自己卡死或者崩溃。
# 查看磁盘使用情况
df -h
# 查看inode使用(有时候是文件太多把inode用完了)
df -i
我见过一个案例,某台服务器的/var/log下面有几十万个小日志文件,df -h看着才用了30%,但df -i显示inode用了99%。结果新建文件全失败,应用就崩了。
服务依赖关系的问题
systemd服务之间经常有依赖关系。A服务依赖B服务,B服务挂了,A服务启动起来也会失败。
# 查看服务的依赖关系
systemctl list-dependencies nginx
# 查看上游依赖(谁服务依赖它)
systemctl list-dependencies --reverse nginx
有时候你看到nginx failed,其实是因为它依赖的数据库服务没起来。这时候单独看nginx的日志,怎么都看不出问题根源。你得把整个依赖链都排查一遍。
# 查看所有failed的服务
systemctl --failed
# 批量查看这些服务的日志
for svc in $(systemctl --failed --no-legend | awk '{print $1}'); do
echo "=== $svc ==="
journalctl -u $svc -n 50 --no-pager
done
权限和SELinux的问题
AlmaLinux默认开启了SELinux。很多时候服务启动失败,不是服务本身的问题,是SELinux拦住了。
# 查看SELinux状态
sestatus
# 查看SELinux拒绝记录
ausearch -m avc -ts recent
# 或者用这个更直观
sealert -a /var/log/audit/audit.log
我遇到过最头疼的一个问题,是Apache启动后无法访问网页。服务状态显示active,日志也没错误。结果用sealert一查,发现是SELinux阻止了Apache读某个目录的文件。
修复方法一般是修改SELinux上下文:
# 查看当前上下文
ls -Z /var/www/html/
# 修改上下文(让Apache能读)
restorecon -Rv /var/www/html/
# 如果需要更宽泛的设置(谨慎使用)
setsebool -P httpd_read_user_content 1
注意,别一上来就setenforce 0把SELinux关掉,那样虽然能解决问题,但安全风险很大。先试试调整策略和上下文。
网络相关的服务问题
有些服务启动看起来正常,但实际上连不上需要的网络资源。
比如一个应用要连接数据库,但数据库在不同机器上。启动时数据库还没就绪,应用就退出了。这种问题在systemd里可以通过配置依赖来解决。
# 在服务的.service文件中添加
[Unit]
After=network.target mysql.service
Requires=mysql.service
[Service]
ExecStart=/usr/local/bin/myapp
But wait,有时候你加了这些依赖,服务还是起不来。这时候要看网络本身有没有问题。
# 检查网络接口
ip addr
# 检查路由
ip route
# 测试DNS解析
nslookup example.com
# 测试端口连通性
nc -zv db-server 3306
一个实际的例子:某台应用服务器启动时连接数据库失败。查日志发现是DNS解析超时。再查网络,发现/etc/resolv.conf里的nameserver配置错了。改过来就好了。
这种问题,排查顺序应该是:服务日志→网络连通性→DNS解析→配置文件。
深入排查工具的使用
strace追踪系统调用
有时候日志也看不出问题,服务就是起不来或者动不动就崩。这时候可以用strace来跟踪进程的 syscall。
# 启动时追踪(先停掉服务)
systemctl stop myapp
strace -f -o /tmp/myapp.trace /usr/local/bin/myapp
输出会很长,里面全是系统调用。你重点关注exit、errno相关的信息。
# 从trace文件里找错误
grep -i "errno\|error\|failed" /tmp/myapp.trace
ltrace追踪库调用
strace看的是系统调用,ltrace看的是库函数调用。有些应用层面的问题,strace看不出来,ltrace能发现。
# 追踪动态库调用
ltrace /usr/local/bin/myapp
性能分析
服务慢或者崩,有时候是性能问题。CPU跑满了、内存泄漏、I/O瓶颈,都可能导致服务异常。
# 实时查看CPU和内存
top
# 更详细的进程信息
htop
# 查看系统负载
uptime
如果怀疑内存泄漏,可以写个脚本定期记录内存使用:
#!/bin/bash
while true; do
echo "=== $(date) ==="
ps aux | grep myapp | grep -v grep
free -h
sleep 60
done > /tmp/memory_monitor.log
跑一段时间后看趋势,如果内存持续增长不释放,那大概率是泄漏了。
文件系统层面的问题
如果怀疑是磁盘或者文件系统的问题,可以用一些工具来诊断。
# 查看磁盘I/O统计
iostat -x 2 5
# 查看smart信息(需要 smartmontools)
smartctl -a /dev/sda
# 检查RAID状态(如果有软RAID)
cat /proc/mdstat
# 查看dmesg里的磁盘相关错误
dmesg | grep -i error | grep -i disk
我经历过一次,服务器频繁卡死,查了应用日志啥都没有。最后用iostat发现某个磁盘的await值持续很高,然后用smartctl一看,磁盘已经报错了。换掉磁盘就好了。
常见的AlmaLinux特有坑
AppArmor和SELinux并存的问题
AlmaLinux默认用SELinux,但有些软件可能也装了AppArmor。这两个东西会冲突,导致意想不到的权限问题。
# 检查AppArmor状态
aa-status
# 如果不需要可以禁用
systemctl disable --now apparmor
包管理相关的问题
AlmaLinux用的是dnf,有时候包依赖出问题会导致服务起不来。
# 检查包依赖完整性
dnf repoquery --requires package-name
# 检查是否有残留的依赖问题
dnf distro-sync
# 重建rpm数据库(极端情况)
rpm --rebuilddb
内核更新后的兼容性问题
AlmaLinux经常更新内核。有时候新内核加载了某个内核模块,但这个模块跟硬件不兼容,导致系统不稳定。
# 查看当前和内核对列表
uname -r
dnf list installed kernel*
# 在GRUB里选择旧内核启动
# 重启时选Advanced options for AlmaLinux,选旧内核版本
如果确认是新内核的问题,可以暂时禁用自动更新:
# 编辑dnf配置
vi /etc/dnf/dnf.conf
# 在[main]下添加
exclude=kernel*
容器和虚拟机环境中的特殊情况
如果你在KVM或者容器中跑AlmaLinux,有些问题跟物理机不太一样。
# 查看是否在容器中
systemd-detect-virt
# 查看虚拟化类型
cat /proc/sys/vmm/info 2>/dev/null || virsh dominfo $(hostname) 2>/dev/null
容器环境里,有些系统调用可能被限制,导致某些服务行为异常。如果服务在物理机上正常,在容器里异常,就要考虑这个因素。
预防胜于治疗
排查故障当然重要,但更好的方法是让故障少发生。
配置日志轮转
别让日志把磁盘撑爆。检查logrotate配置:
# 查看logrotate配置
cat /etc/logrotate.conf
ls -la /etc/logrotate.d/
# 手动测试配置是否正确
logrotate -d /etc/logrotate.conf
监控系统资源
装个监控工具,及时发现异常。AlmaLinux上可以用一些开源方案。
# 安装和配置node_exporter(Prometheus生态)
dnf install node_exporter
systemctl enable --now node_exporter
# 或者简单的监控脚本
#!/bin/bash
THRESHOLD=90
usage=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$usage" -gt "$THRESHOLD" ]; then
echo "Disk usage critical: ${usage}%" | mail -s "Alert: Disk Full" admin@example.com
fi
定期备份和测试恢复
再好的防护也有失手的时候。定期备份重要数据,并且测试备份能不能恢复。
# 备份/etc目录(系统配置)
tar czf /backup/etc-backup-$(date +%Y%m%d).tar.gz /etc
# 备份数据库
mysqldump -u root -p --all-databases > /backup/mysql-full-$(date +%Y%m%d).sql
# 验证备份文件完整性
tar tzf /backup/etc-backup-20240101.tar.gz | head -20
记录变更历史
每次改配置,都记一笔。这样出问题的时候知道最近动过什么。
# 可以用一个简单的变更记录脚本
log_change() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> /var/log/sysadmin-changes.log
}
# 每次改配置后调用
log_change "Modified nginx config, added new location block"
紧急情况下的快速行动清单
最后,给你一个速查清单。遇到系统故障不知道从哪儿下手的时候,按这个顺序来:
# 1. 看系统是否还活着
ping -c 3 google.com
uptime
# 2. 检查资源使用情况
free -h
df -h
top -bn1
# 3. 查看最近的系统日志
journalctl -p err --since "1 hour ago"
# 4. 检查failed的服务
systemctl --failed
# 5. 查看内核日志(硬件/驱动问题)
dmesg -T | tail -50
# 6. 检查磁盘错误
smartctl -a /dev/sda
# 7. 检查网络连通性
ip addr
ip route
ss -tlnp
# 8. 查看最近的认证失败(安全事件)
lastb | head -20
journalctl -u sshd --since "1 hour ago" | grep -i fail
记住,排查问题最重要的是冷静。别看到服务挂了就直接重启,先搞清楚为什么挂。盲目的重启可能掩盖问题,甚至造成数据丢失。
系统故障这事儿,做得越多经验越足。今天踩的坑,明天就是经验。希望这篇文章能帮你在AlmaLinux的坑里爬得快一点。
