第 28/30 天
引言
服务器宕机了怎么办?系统无法启动了?某个服务莫名其妙挂了?——作为 Ubuntu 管理员,故障排查是必备的核心技能。即使配置再完善,系统也难免会遇到意外情况:内核崩溃、磁盘故障、配置错误导致服务无法启动、启动引导损坏等。
本周(第 4 周)我们从前 22 天的安全加固开始,经历了性能调优、虚拟化、容器编排、高可用集群和自动部署。今天,我们来学习故障发生时如何冷静、系统化地定位问题并恢复系统。掌握这些技能,你就能在关键时刻成为团队最信赖的人。
本文将覆盖:应急响应流程、系统救援与启动修复、日志分析技巧、崩溃排查方法,以及常见故障的实战案例。
一、故障排查的核心方法论
1.1 故障排查四步法
无论遇到什么问题,遵循以下步骤可以避免慌乱和遗漏:
| 步骤 | 操作 | 目的 |
|---|---|---|
| ① 收集信息 | 查看日志、错误信息、系统状态 | 确定故障范围和影响 |
| ② 分析定位 | 对比正常状态、缩小范围 | 找出根本原因 |
| ③ 制定方案 | 根据 root cause 确定修复步骤 | 确保修复有效 |
| ④ 实施验证 | 执行修复、验证恢复、监控稳定 | 确认问题解决 |
1.2 诊断工具箱
在排查问题前,先确认手头有哪些工具可用:
# 系统信息收集(无需安装)
uname -a # 内核版本
lsb_release -a # Ubuntu 版本
cat /etc/os-release # 发行版信息
dmesg | tail -50 # 内核环形缓冲区信息
uptime # 运行时间 + 负载
free -h # 内存使用
df -h # 磁盘使用
mount | grep " / " # 根分区挂载情况
# 进程信息
ps auxf # 进程树
top -bn1 # 一次性 top 输出
systemctl list-units --failed # 列出失败的服务
二、系统救援与启动修复
2.1 GRUB 引导修复
场景: 系统启动到 GRUB 提示符或黑屏。这是最常见也最令人恐慌的故障之一。
现象: 开机后显示 grub rescue> 或 error: no such partition。
修复方法:
# 第一步:查找 GRUB 所在的正确分区
grub rescue> ls
(hd0) (hd0,msdos1) (hd0,msdos2)
# 第二步:尝试找到 /boot/grub 目录
grub rescue> ls (hd0,msdos1)/boot/grub
# 如果找不到,试其他分区
# 第三步:手动加载 GRUB 模块
grub rescue> set prefix=(hd0,msdos1)/boot/grub
grub rescue> insmod normal
grub rescue> normal
# 进入 GRUB 菜单后,先启动系统
# 然后在系统内修复
sudo update-grub
sudo grub-install /dev/sda
预防措施: 安装 GRUB 到备用分区,保存 GRUB 配置文件备份:
# 备份 GRUB 配置
sudo cp /boot/grub/grub.cfg /boot/grub/grub.cfg.bak
# 检查 GRUB 安装状态
sudo grub-install --recheck /dev/sda
2.2 使用 Live USB 进行系统救援
当系统完全无法启动时,Live USB 是最强大的救援工具。以下是典型救援流程:
# 1. 用 Ubuntu Live USB 启动,选择 "Try Ubuntu"
# 2. 挂载受损系统的根分区
sudo mkdir -p /mnt/rescue
sudo mount /dev/sda2 /mnt/rescue # 假设根分区是 sda2
sudo mount /dev/sda1 /mnt/rescue/boot # 如果有独立 boot 分区
# 3. 挂载必要的虚拟文件系统
sudo mount --bind /dev /mnt/rescue/dev
sudo mount --bind /proc /mnt/rescue/proc
sudo mount --bind /sys /mnt/rescue/sys
# 4. chroot 进入受损系统
sudo chroot /mnt/rescue
# 5. 在 chroot 环境中修复
# 例如:修复 GRUB
grub-install /dev/sda
update-grub
# 修复包管理器
dpkg --configure -a
apt-get install -f
# 修复文件系统
fsck /dev/sda2
# 6. 退出 chroot 并重启
exit
sudo umount -R /mnt/rescue
sudo reboot
2.3 恢复模式(Recovery Mode)
Ubuntu 内置了恢复模式,无需 Live USB 即可修复部分问题:
# 启动时按住 Shift(BIOS)或 Esc(UEFI)
# 选择 "Advanced options for Ubuntu" → "recovery mode"
# 恢复菜单提供以下选项:
# - clean: 清理磁盘空间
# - dpkg: 修复损坏的软件包
# - fsck: 检查文件系统
# - grub: 更新 GRUB 引导
# - network: 启用网络连接
# - root: 进入 root shell
实战案例:修复因错误配置导致的启动失败:
# 在 recovery mode 的 root shell 中:
# 假设是 /etc/fstab 配置错误导致无法挂载分区
mount -o remount,rw /
nano /etc/fstab
# 注释掉或修正错误的分区条目
# 如果是因为显卡驱动问题,卸载驱动
apt-get purge nvidia-*
# 重新生成 initramfs
update-initramfs -u
三、日志分析:定位问题的第一把钥匙
3.1 journalctl — systemd 日志系统
现代 Ubuntu 使用 systemd-journald 管理日志,journalctl 是你的首要分析工具:
# 查看所有日志(分页,可搜索)
journalctl
# 查看本次启动的日志
journalctl -b
# 查看上一次启动的日志(内核崩溃后特别有用)
journalctl -b -1
# 实时跟踪日志(类似 tail -f)
journalctl -f
# 按时间范围过滤
journalctl --since "2026-08-06 10:00:00" --until "2026-08-06 11:00:00"
# 按服务过滤
journalctl -u nginx.service
journalctl -u ssh.service
# 按优先级过滤(0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug)
journalctl -p err -b # 本次启动的错误日志
journalctl -p 3 -b # 同上(数字形式)
# 输出 JSON 格式便于分析
journalctl -b -o json-pretty
3.2 传统日志文件
| 日志文件 | 用途 | 查看命令 |
|---|---|---|
/var/log/syslog |
系统全局日志 | less /var/log/syslog |
/var/log/auth.log |
认证日志(SSH、sudo) | sudo less /var/log/auth.log |
/var/log/kern.log |
内核日志 | sudo less /var/log/kern.log |
/var/log/dmesg |
内核环形缓冲 | dmesg -T |
/var/log/apt/history.log |
包管理历史 | less /var/log/apt/history.log |
/var/log/nginx/error.log |
Nginx 错误日志 | less /var/log/nginx/error.log |
/var/log/mysql/error.log |
MySQL 错误日志 | sudo less /var/log/mysql/error.log |
3.3 日志分析实战技巧
技巧一:快速定位异常:
# 查看系统最近的错误(排除重复行,按频率排序)
journalctl -p err -b --no-pager |
sed 's/^.*[A-Za-z0-9_.-]*[[0-9]*]: //' |
sort | uniq -c | sort -rn | head -20
技巧二:分析 SSH 暴力破解尝试:
# 统计失败的 SSH 登录尝试
sudo grep "Failed password" /var/log/auth.log |
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# 统计成功的 SSH 登录
sudo grep "Accepted password" /var/log/auth.log |
awk '{print $9, $11}' | sort | uniq -c | sort -rn
技巧三:磁盘空间突然用满的排查:
# 查找大文件
du -sh /* 2>/dev/null | sort -rh | head -10
# 查找被删除但仍在被占用的文件(释放空间需重启进程)
lsof | grep '(deleted)'
# 检查日志文件大小
ls -lhS /var/log/*.log | head -10
# 用 ncdu 交互式分析(需要安装)
sudo apt install ncdu -y && sudo ncdu /
四、崩溃排查:从内核 Panic 到应用崩溃
4.1 内核恐慌(Kernel Panic)
症状: 屏幕显示 Kernel panic - not syncing 并冻结。
排查步骤:
# 1. 查看崩溃时的内核消息
journalctl -b -1 -k --no-pager | grep -i "panic|oops|error|fault"
# 2. 检查 kdump/crashdump(如果配置了)
ls -la /var/crash/
# 使用 crash 工具分析 vmcore
sudo apt install linux-crashdump -y
# 配置后在 /etc/default/kdump-tools 中启用
# 3. 查看硬件错误
dmesg | grep -i "hardware error|mce|memory|ECC"
# 检查内存错误
sudo apt install mcelog -y
sudo mcelog --client
常见原因及解决方案:
| 原因 | 特征 | 解决 |
|---|---|---|
| 内存故障 | 随机崩溃,MCE 日志 | 运行 memtest86+ 测试 |
| 磁盘故障 | I/O 错误,SCSI 错误 | 检查 smartctl -a /dev/sda |
| 驱动冲突 | 安装新驱动后崩溃 | 进入 recovery mode 卸载驱动 |
| 内核 bug | 特定内核版本稳定触发 | 降级/升级内核版本 |
4.2 OOM Killer(内存不足)
症状: 进程被突然杀死,日志中出现 Out of memory: Kill process。
# 查看 OOM 记录
journalctl -b | grep -i "oom|out of memory"
# 查看当前内存压力
cat /proc/pressure/memory
# 输出示例:
# some avg10=2.35 avg60=1.20 avg300=0.50 total=1234567
# full avg10=0.89 avg60=0.45 avg300=0.20 total=567890
# 查看进程内存排行
ps aux --sort=-%mem | head -10
# 调整 OOM 评分(让关键进程不被优先杀死)
# 值范围 -1000(禁止杀死)到 1000(优先杀死)
sudo echo -500 > /proc/$(pgrep -f mysqld)/oom_score_adj
永久解决方案: 配置 swap 或调整系统内存策略:
# 创建 swap 文件(如果还没有)
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 在 /etc/fstab 中添加:
# /swapfile none swap sw 0 0
# 调整 vm.swappiness(默认 60,越低越不倾向用 swap)
sudo sysctl -w vm.swappiness=10
# 永久生效
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
4.3 服务崩溃与自动恢复
# 查看服务崩溃历史
journalctl -u nginx.service -p err --since "1 week ago"
# 配置 systemd 自动重启(编辑 service 单元文件)
sudo systemctl edit nginx.service
添加以下内容:
[Service]
Restart=on-failure
RestartSec=5s
StartLimitIntervalSec=0
StartLimitBurst=10
应用更改:
sudo systemctl daemon-reload
sudo systemctl restart nginx.service
4.4 系统挂起时的手动排查
当系统响应缓慢但不完全崩溃时:
# 1. 检查负载和 CPU 状态
uptime
mpstat -P ALL 1 5 # 需要安装 sysstat
# 2. 查看 I/O 瓶颈
iostat -x 1 5 # 需要安装 sysstat
iotop -o # 需要安装 iotop(需 root)
# 3. 查看 D 状态进程(不可中断睡眠,通常代表 I/O 问题)
ps aux | grep " D"
# 4. 查看网络连接状态
ss -tupn
netstat -i
# 5. 使用 strace 跟踪进程系统调用
sudo strace -p <PID> -e trace=network,file -c -S time
五、实战案例:完整故障排查演示
案例:Nginx 服务突然停止,网站无法访问
阶段 1 — 收集信息:
# 检查服务状态
systemctl status nginx.service
# 输出:Active: failed (Result: exit-code)
# 查看错误日志
journalctl -u nginx.service -n 50 --no-pager
# 发现:bind() to 0.0.0.0:80 failed (98: Address already in use)
# 确认端口占用
ss -tlnp | grep :80
# 发现另一个进程已经占用了 80 端口
阶段 2 — 分析定位:
# 查看哪个进程占用了端口
ss -tlnp | grep :80
# 输出:LISTEN 0 100 0.0.0.0:80 *:* users:(("apache2",pid=1234,fd=4))
# 确认 Apache 未正确关闭,导致端口冲突
# 根本原因:之前安装过 Apache,未彻底卸载
阶段 3 — 制定方案:
# 方案 A:停止 Apache 并重启 Nginx
sudo systemctl stop apache2
sudo systemctl disable apache2
# 方案 B:或修改 Nginx 监听端口(临时方案)
# 编辑 /etc/nginx/sites-enabled/default,将 listen 80 改为 listen 8080
阶段 4 — 实施验证:
# 执行方案 A
sudo systemctl stop apache2
sudo systemctl restart nginx
systemctl status nginx.service
# 确认 active (running)
# 验证网站访问
curl -s -o /dev/null -w "HTTP %{http_code}" http://localhost/
# 输出:HTTP 200
# 设置 Nginx 在 Apache 后启动(如果 Apache 必须保留)
sudo systemctl edit nginx.service
# 添加:
# [Unit]
# After=network.target apache2.service
六、故障排查预防措施
6.1 建立系统基线
在系统正常运行时记录关键指标,故障时对比:
# 创建系统基线脚本
cat > /usr/local/bin/system-baseline.sh << 'EOF'
#!/bin/bash
DATE=$(date +%Y%m%d)
BASEDIR="/var/log/baseline"
mkdir -p $BASEDIR
# 记录关键指标
dmesg -T > $BASEDIR/dmesg_$DATE.txt
ss -tlnp > $BASEDIR/ports_$DATE.txt
ps auxf > $BASEDIR/processes_$DATE.txt
df -h > $BASEDIR/disk_$DATE.txt
free -h > $BASEDIR/memory_$DATE.txt
cat /proc/cpuinfo | grep "model name" | head -1 > $BASEDIR/cpu_$DATE.txt
uptime > $BASEDIR/uptime_$DATE.txt
journalctl --list-boots > $BASEDIR/boots_$DATE.txt
# 保留最近 30 天
find $BASEDIR -name "*.txt" -mtime +30 -delete
EOF
chmod +x /usr/local/bin/system-baseline.sh
# 添加到每日 cron
(crontab -l 2>/dev/null; echo "0 6 * * * /usr/local/bin/system-baseline.sh") | crontab -
6.2 配置持久化日志
默认情况下 journald 日志存在内存中,重启后丢失:
# 启用持久化日志
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
# 查看当前日志使用量
journalctl --disk-usage
# 限制日志大小(编辑 /etc/systemd/journald.conf)
sudo sed -i 's/#SystemMaxUse=/SystemMaxUse=500M/' /etc/systemd/journald.conf
sudo sed -i 's/#MaxRetentionSec=/MaxRetentionSec=2weeks/' /etc/systemd/journald.conf
sudo systemctl restart systemd-journald
6.3 关键配置备份
# 备份最重要的系统配置
sudo tar czf /root/system-config-backup-$(date +%Y%m%d).tar.gz
/etc/fstab
/etc/default/grub
/etc/netplan/
/etc/ssh/sshd_config
/etc/sysctl.conf
/etc/nginx/
/etc/systemd/
七、故障排查速查表
| 问题类型 | 症状 | 快速诊断命令 | 典型修复 |
|---|---|---|---|
| 无法启动 | GRUB rescue> | ls (hd0,msdos1) |
grub-install + update-grub |
| 内核 Panic | 屏幕冻结 | journalctl -b -1 -k |
检查硬件/驱动 |
| 磁盘满 | 写入失败 | df -h + du -sh /* |
清理日志/扩容 |
| OOM | 进程被杀 | dmesg | grep oom |
加 swap/调优内存 |
| 端口冲突 | 服务启动失败 | ss -tlnp |
停冲突进程/改端口 |
| DNS 问题 | 域名解析慢/失败 | dig @8.8.8.8 example.com |
检查 /etc/resolv.conf |
| 文件系统损坏 | I/O 错误 | dmesg | grep -i error |
fsck -y /dev/sdaX |
| 网络不通 | ping 失败 | ip route + traceroute |
检查路由/防火墙 |
| SSH 拒绝 | Connection refused | ss -tlnp | grep :22 |
检查 SSH 配置/防火墙 |
| 服务死循环 | CPU 100% | top -c |
strace -p <PID> 定位 |
总结
今天你学习了 Ubuntu 故障排查的完整方法论:
- 系统救援:GRUB 修复、Live USB 救援、恢复模式三大启动修复手段
- 日志分析:journalctl 的 20+ 种用法,传统日志文件定位技巧
- 崩溃排查:内核 Panic、OOM Killer、服务崩溃、系统挂起四大场景
- 实战案例:Nginx 端口冲突的完整排查四步法
- 预防措施:系统基线、持久化日志、配置备份
核心原则: 故障排查不是碰运气,而是系统化的信息收集 → 分析定位 → 制定方案 → 实施验证的过程。记录基线和保存日志是故障排查的”安全网”——没有它们,你就在黑暗中摸索。
下期预告
明天(第 29 天)我们将聊一个轻松但重要的话题:Ubuntu 社区与文档——如何获取帮助、Bug 报告流程、贡献指南。无论你是初学者还是老手,知道在哪里找到答案和如何回馈社区,都是成为 Ubuntu 精通者的重要一步。
系列目录
| 天数 | 主题 | 状态 |
|---|---|---|
| 第 1 天 | Ubuntu 简介与版本选择 | ✅ |
| 第 2 天 | 手把手安装 Ubuntu | ✅ |
| 第 3 天 | GNOME 桌面与软件中心 | ✅ |
| 第 4 天 | 终端基础与文件系统 | ✅ |
| 第 5 天 | 用户与权限管理 | ✅ |
| 第 6 天 | 软件包管理全面对比 | ✅ |
| 第 7 天 | 文件与文本操作实战 | ✅ |
| 第 8 天 | systemd 与 systemctl 完全指南 | ✅ |
| 第 9 天 | 磁盘与文件系统管理 | ✅ |
| 第 10 天 | 网络配置与防火墙 | ✅ |
| 第 11 天 | 进程管理与监控 | ✅ |
| 第 12 天 | 计划任务与自动化 | ✅ |
| 第 13 天 | 备份与恢复策略 | ✅ |
| 第 14 天 | 系统更新与升级管理 | ✅ |
| 第 15 天 | SSH 远程管理与安全加固 | ✅ |
| 第 16 天 | Web 服务器搭建 | ✅ |
| 第 17 天 | 数据库服务器部署 | ✅ |
| 第 18 天 | Docker 容器化管理 | ✅ |
| 第 19 天 | 文件共享服务 | ✅ |
| 第 20 天 | 监控与告警系统 | ✅ |
| 第 21 天 | 邮件服务器基础 | ✅ |
| 第 22 天 | 系统安全加固 | ✅ |
| 第 23 天 | 性能调优与内核参数 | ✅ |
| 第 24 天 | 虚拟化技术 | ✅ |
| 第 25 天 | 容器编排入门 | ✅ |
| 第 26 天 | 高可用与负载均衡 | ✅ |
| 第 27 天 | Ubuntu 自动部署 | ✅ |
| 第 28 天 | 故障排查实战 | 🟢 今日 |
| 第 29 天 | Ubuntu 社区与文档 | ⏳ |
| 第 30 天 | 30 天回顾总结 | ⏳ |















暂无评论内容