遇到开机卡死服务起不来重启变砖 手把手教你排查 AlmaLinux 系统故障从日志分析到修复完整解决方案
老哥,你是不是刚重启机器,盯着屏幕发呆,发现系统死活进不去?或者进了系统,服务起不来,重启之后直接变砖?别慌,这种事儿我见过太多了,今天咱就坐下来,一步一步把 AlmaLinux 的故障排查给捋清楚。放心,我会用最接地气的方式讲,保证你能看懂,照着做就能解决问题。
先冷静下来,观察现象
咱们先别急着敲命令,先看看系统到底啥状态。
开机卡死一般有几种情况:
- 卡在 GRUB 启动界面不动
- 卡在启动logo或者进度条那儿
- 黑屏,啥都没有
- 能到登录界面,但登录后各种服务起不来
重启变砖更常见的是:
- 无限重启
- 进不了系统,直接 panic
- 文件系统报错
第一种情况:卡在启动界面
我有个客户,服务器重启后一直卡在启动界面,啥也不动。他慌得不行,直接找我。我让他先看屏幕上的报错信息,有时候问题就在那儿。
第一步,按 Esc 键或者方向键,看看能不能看到更多输出。 有时候系统其实在跑,只是日志刷得太快,你看不清楚。
# 如果能看到日志,按方向键可以上下滚动查看
# 如果卡死了,试试按 Ctrl+Alt+F2 切到另一个终端
切到其他终端后,试试能不能登录:
# Ctrl+Alt+F2 到 F6 切换不同的虚拟终端
# 如果能登录,说明内核还活着,只是图形界面或者某个服务卡死了
第二步,试试单用户模式。 这是咱排查问题的神器。
重启机器,在 GRUB 界面按 e 键编辑启动项,找到 linux 开头的那一行,在末尾加上 rd.break 或者 emergency:
# 修改后的行大概长这样:
linux16 /vmlinuz-... root=/dev/mapper/... ro rd.break
然后按 Ctrl+X 启动。这样系统会以救援模式启动,不挂载任何文件系统,你能看到一个 shell 提示符。
日志是咱的宝贝
系统出问题,日志是最好的朋友。AlmaLinux 用 systemd,日志全在 journald 里。
查看启动日志
# 查看系统启动以来的所有日志
journalctl -b
# 查看上一次启动的日志(系统崩了也能看)
journalctl -b -1
# 只看报错信息
journalctl -p err -b
# 查看某个服务的日志
journalctl -u nginx -b
# 实时跟踪日志(类似 tail -f)
journalctl -f
重点看什么?
- 文件系统错误 — 看到
EXT4-fs error、XFS: Internal error之类的 - 服务启动失败 — 看到
Failed to start xxx.service - 磁盘空间满 — 看到
No space left on device - 内存问题 — 看到
Out of memory: Killed process
查看具体错误
我见过最坑的一个情况,日志里啥也没有,但服务就是起不来。后来发现是磁盘满了。
# 检查磁盘空间
df -h
# 检查 inode 使用率(有时候磁盘没满,但 inode 用完了)
df -i
# 找到大文件
du -sh /var/log/* | sort -rh | head -20
有个案例,客户的 /var/log 目录下有个日志文件有 500G,直接把磁盘填满了,导致系统服务全都起不来。清理掉那个文件后,一切恢复正常。
服务起不来的排查
AlmaLinux 的服务管理全靠 systemd,学好用好 systemctl 就成功了一半。
查看服务状态
# 查看服务状态
systemctl status nginx
# 输出示例:
# ● nginx.service - The nginx HTTP and reverse proxy server
# Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
# Active: failed (Result: exit-code) since Mon 2024-01-15 10:30:00 CST; 2min ago
# Process: 1234 ExecStart=/usr/sbin/nginx (code=exited, status=1/FAILURE)
# Main PID: 1234 (code=exited, status=1/FAILURE)
关键字段解读:
Loaded— 服务是否被 systemd 识别Active— 服务当前状态Result— 失败的原因Main PID— 主进程 ID
详细排查步骤
# 1. 查看服务详细状态
systemctl status <服务名> -l
# 2. 查看服务启动日志
journalctl -u <服务名> -n 50 --no-pager
# 3. 手动启动服务看报错
systemctl start <服务名>
# 4. 查看系统日志中的相关错误
journalctl -xe | grep <服务名>
# 5. 检查服务配置文件语法
# 以 nginx 为例
nginx -t
# 以 Apache 为例
httpd -t
# 6. 检查端口占用
ss -tlnp | grep <端口号>
常见服务启动失败的原因
1. 端口被占用
# 检查端口是否被占用
ss -tlnp | grep 80
netstat -tlnp | grep 80
# 找到占用端口的进程
lsof -i :80
有个案例,新装的 nginx 起不来,查了半天发现是旧的 nginx 进程还占着端口,没杀干净。
2. 配置文件语法错误
# nginx 配置检查
nginx -t
# 输出:nginx: configuration file /etc/nginx/nginx.conf test failed
# 修复后再次检查
nginx -t
# 输出:nginx: configuration file /etc/nginx/nginx.conf test is successful
3. 文件权限问题
# 检查关键目录权限
ls -la /var/www/html
ls -la /etc/nginx/
ls -la /var/log/nginx/
# 修正权限
chmod 755 /var/www/html
chown -R nginx:nginx /var/www/html
4. SELinux 拦截
AlmaLinux 默认开启 SELinux,有时候服务起不来是因为 SELinux 在拦截。
# 查看 SELinux 状态
sestatus
# 查看 SELinux 拒绝日志
ausearch -m avc -ts recent
# 临时关闭 SELinux 测试(不推荐长期使用)
setenforce 0
# 查看具体的 SELinux 拒绝记录
grep denied /var/log/audit/audit.log | audit2allow -a
# 修复 SELinux 上下文
restorecon -Rv /var/www/html
文件系统损坏排查
这个是最让人头疼的,但也是最需要认真对待的。
检查磁盘状态
# 查看磁盘 SMART 信息
smartctl -a /dev/sda
# 检查文件系统
fsck -n /dev/sda1
# 查看磁盘错误
dmesg | grep -i error
dmesg | grep -i disk
修复文件系统
重要提示:修复前一定要先备份数据!修复操作有风险!
# 1. 先尝试只读检查
fsck -n /dev/sda1
# 2. 如果是 ext4 文件系统,可以安全修复
# 注意:必须在卸载状态下修复,或者使用只读模式先检查
umount /dev/sda1
fsck -y /dev/sda1
# 3. 如果是 xfs 文件系统
xfs_repair /dev/sda1
# 4. 如果根分区损坏,需要从 Live CD 启动后修复
# 挂载根分区到 /mnt
mount /dev/sda1 /mnt
chroot /mnt
# 然后执行修复
实际案例
有个客户的服务器,突然重启后进不去系统,日志里全是 XFS 错误:
[ 2.345678] XFS (sda1): Internal error xfs_trans_cancel at line 933 of fs/xfs/kr
[ 2.345679] XFS (sda1): Call trace: xfs_do_force_shutdown+0x2c/0x40
[ 2.345680] XFS (sda1): PANIC: Invalid argument
我们用 Live CD 启动后,执行了 xfs_repair /dev/sda1,修复了元数据错误,系统恢复正常。但这个案例提醒我们,XFS 文件系统虽然快,但一旦损坏,恢复起来很麻烦。平时多做备份才是王道。
内存和 Swap 问题
内存问题有时候很隐蔽,特别是当 Swap 分区配置不当时。
检查内存使用情况
# 查看内存使用
free -h
# 查看详细内存信息
cat /proc/meminfo
# 查看哪些进程占用内存最多
ps aux --sort=-%mem | head -20
Swap 配置检查
# 查看 Swap 状态
swapon --show
# 查看 Swap 使用情况
free -h
# 如果 Swap 没启用,可以创建
dd if=/dev/zero of=/swapfile bs=1M count=4096
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# 添加到 fstab 开机挂载
echo '/swapfile none swap sw 0 0' >> /etc/fstab
OOM Killer
当内存不足时,Linux 会触发 OOM Killer,杀掉一些进程来释放内存。
# 查看是否有进程被 OOM Killer 杀掉
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"
journalctl | grep -i "oom"
如果经常看到 OOM 日志,说明内存不够用,需要:
- 增加物理内存
- 优化应用配置
- 调整 OOM Score
# 调整某个进程的 OOM Score
echo -1000 > /proc/<PID>/oom_score_adj
网络问题导致服务起不来
有时候服务起不来,是因为网络配置有问题。
检查网络状态
# 查看网络接口
ip addr show
# 查看路由表
ip route show
# 查看 DNS 解析
cat /etc/resolv.conf
nslookup example.com
# 测试网络连通性
ping -c 4 8.8.8.8
ping -c 4 baidu.com
检查网络服务
# 查看 NetworkManager 状态
systemctl status NetworkManager
# 查看网络配置
nmcli device status
nmcli connection show
# 重启网络服务
systemctl restart NetworkManager
重启变砖的深度排查
重启变砖是最严重的情况,通常有以下几个可能:
1. GRUB 损坏
# 如果 GRUB 损坏,可以用 Live CD 修复
# 挂载根分区
mount /dev/sda1 /mnt
# 挂载其他必要分区
mount /dev/sda2 /mnt/boot # 如果有独立的 boot 分区
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
# chroot 进去
chroot /mnt
# 重新安装 GRUB
grub2-install /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg
# 退出 chroot
exit
# 重启
reboot
2. 内核问题
# 查看已安装的内核
rpm -qa | grep kernel
# 查看当前使用的内核
uname -r
# 如果有多个内核,可以在 GRUB 菜单选择旧内核启动
# 如果新内核有问题,可以临时禁用
# 编辑 /etc/default/grub
GRUB_DISABLE_RECOVERY=true
GRUB_TIMEOUT=10
# 更新 GRUB 配置
grub2-mkconfig -o /boot/grub2/grub.cfg
3. initramfs 损坏
# 重建 initramfs
dracut --force /boot/initramfs-$(uname -r).img $(uname -r)
# 或者指定具体版本
dracut --force /boot/initramfs-5.14.0-xxx.el9.x86_64.img 5.14.0-xxx.el9.x86_64
4. /etc/fstab 配置错误
这个坑我最怕,有一次客户改了 fstab 里的 UUID,重启后直接进 emergency mode。
# 在 emergency mode 下检查 fstab
cat /etc/fstab
# 正确的格式
# <device> <mountpoint> <type> <options> <dump> <fsck>
/dev/sda1 / ext4 defaults 1 1
UUID=xxxx-xxxx /boot ext4 defaults 1 2
# 获取正确的 UUID
blkid
# 修复后重启
reboot
紧急恢复模式的使用
当系统完全起不来时,emergency mode 是最后的救命稻草。
进入紧急模式
# 方法一:在 GRUB 菜单选择高级选项,进入 recovery mode
# 方法二:在 GRUB 启动参数加上 emergency
# 方法三:如果系统能启动但很快崩溃,可能自动进入 emergency mode
emergency mode 下的常用操作
# 挂载根文件系统为可读写
mount -o remount,rw /
# 查看日志
journalctl -xb
# 检查磁盘空间
df -h
# 修复文件系统
fsck -y /dev/sda1
# 重置 root 密码(如果忘记密码)
passwd root
# 禁用有问题的服务
systemctl disable <服务名>
预防胜于治疗
说了这么多故障排查,其实最好的办法是预防。
定期检查
# 创建定期检查脚本
cat > /usr/local/bin/health-check.sh << 'EOF'
#!/bin/bash
# 系统健康检查脚本
echo "=== 系统时间 ==="
date
echo "=== 磁盘使用 ==="
df -h
echo "=== 内存使用 ==="
free -h
echo "=== 系统负载 ==="
uptime
echo "=== 失败的 systemd 服务 ==="
systemctl --failed
echo "=== 最近的系统日志错误 ==="
journalctl -p err -n 20 --no-pager
echo "=== 文件系统检查 ==="
fsck -n /dev/sda1 2>/dev/null || echo "需要卸载后检查"
EOF
chmod +x /usr/local/bin/health-check.sh
# 添加到 crontab 每天运行
crontab -e
# 添加:0 6 * * * /usr/local/bin/health-check.sh >> /var/log/health-check.log 2>&1
备份策略
# 使用 rsync 备份重要数据
rsync -avz --progress /etc/ backup:/backups/etc/$(date +%Y%m%d)
# 使用 tar 备份整个系统
tar czvf /backup/system-$(date +%Y%m%d).tar.gz \
--exclude=/proc \
--exclude=/sys \
--exclude=/dev \
--exclude=/run \
--exclude=/backup \
/
# 定期测试恢复
# 备份不做恢复测试,等于没有备份
监控系统
# 安装监控工具
dnf install -y netdata prometheus-node-exporter
# 或者使用简单的监控脚本
cat > /usr/local/bin/alert.sh << 'EOF'
#!/bin/bash
# 磁盘空间告警
THRESHOLD=90
usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$usage" -gt "$THRESHOLD" ]; then
echo "磁盘空间不足: ${usage}%" | mail -s "AlmaLinux 告警" admin@example.com
fi
EOF
总结
排查 AlmaLinux 故障,核心就几个字:看日志、查状态、逐步缩小范围。
- 先观察现象 — 卡在哪儿?有报错吗?能进终端吗?
- 看日志 — journalctl 是你的好朋友
- 检查资源 — 磁盘、内存、inode
- 查看服务状态 — systemctl status
- 排查文件系统 — fsck
- 必要时进紧急模式 — emergency
- 修复后验证 — 重启看是否正常
记住,别慌。系统出问题不可怕,可怕的是乱操作。每一步都要想清楚再动手,特别是涉及文件系统修复的时候,先备份,先检查。
最后送你一句话:好的运维习惯,胜过无数故障排查技巧。定期备份、定期检查、定期更新,你的 AlmaLinux 会稳如老狗。
好了,今天就讲到这儿。有啥问题随时问,咱一起解决。
