Ubuntu 运维系列 | 第 28 天:故障排查实战——启动失败、高负载、网络异常的定位与处理

引言

线上故障发生时,时间就是金钱,心态就是产能。运维工程师最常遇到的三类故障并非软件 Bug,而是”系统起不来””机器跑不动””网络连不上”——这三类故障占生产事故的比例通常超过 70%。它们往往没有显式的错误日志,没有明确的告警阈值,靠的是一套可复用的 排查方法论诊断命令组合拳,而不是临时抱佛脚。

本文将以 Ubuntu 22.04 / 24.04 LTS 为底座,系统讲解这三类高频故障的定位流程:从启动链路的 initrd 到 GRUB、从 CPU/内存/IO 三维负载模型到进程归因、从 Netplan 到路由表、从 ARP 到 DNS 的逐层下钻,并给出可直接套用的命令清单与应急脚本。读完本篇,你将拥有面对大多数 P1 故障时的”先做什么、再看什么、最后处理什么”的肌肉记忆。

Ubuntu 运维 第28天

一、故障排查的通用方法论:分治与分层

1.1 五步定位法

无论故障表象如何,都建议遵循一条固定路径:

  1. 复现与止损:先止血(重启、摘流量、降级),保留现场(截图、日志、core dump)。
  2. 缩小范围:分层确认——硬件层 / 内核层 / 系统层 / 应用层。
  3. 采集证据:使用系统内置工具采集指标,避免”凭感觉”。
  4. 定位根因:把异常指标对应到具体进程、服务、配置或硬件。
  5. 修复与回归:修复 → 灰度 → 全量,补充监控与告警,更新 Runbook。

1.2 三类故障的边界

类型 典型表象 优先级工具
启动失败 蓝屏、GRUB 报错、卡在 initramfs dmesg, journalctl -b -1, grub-mkconfig
高负载 CPU 打满、load average 飙升、磁盘 iowait top, vmstat, iostat, pidstat
网络异常 丢包、延迟高、Connection refused ss, tcpdump, mtr, iptables -L

二、启动失败排查实战

2.1 启动链路回顾

Ubuntu 的启动链路为:固件(UEFI/BIOS) -> GRUB -> Linux Kernel -> initramfs -> systemd(PID 1) -> 服务单元。任一环节异常都可能表现为”系统起不来”。

# 通过 GRUB 菜单进入 Advanced options,选择带 (recovery mode) 的内核
# 启动后按 Esc 中断,进入 GRUB 编辑界面,修改 root= 或 initrd= 参数

2.2 场景 A:卡在 “Loading initial ramdisk” 或 initramfs 提示符

这通常意味着 initrd.img 损坏或 root 分区找不到。处理步骤:

# 从 Live USB 启动,挂载根分区
sudo fdisk -l
sudo mount /dev/sda2 /mnt
sudo mount /dev/sda1 /mnt/boot  # 若 /boot 独立分区
sudo chroot /mnt

# 重新生成 initramfs
update-initramfs -u -k all
grub-mkconfig -o /boot/grub/grub.cfg
exit
sudo reboot

2.3 场景 B:进入 GRUB 后无法启动(Kernel panic)

最常见的根因是内核参数错误或磁盘设备名变更(如 /dev/sda -> /dev/nvme0n1)。

# 使用 systemd-analyze 检查上次启动的失败原因
journalctl -b -1 -p err --no-pager | tail -50
systemd-analyze blame | head -20

# 若 boot 分区是 ext4,先检查文件系统一致性
sudo fsck -y /dev/sda1

2.4 场景 C:systemd 起不来(一直停在 “Starting…”)

systemctl list-jobssystemd-analyze critical-chain 能快速找出阻塞的 Unit:

systemctl list-jobs
systemd-analyze critical-chain
journalctl -u NetworkManager -b --no-pager

三、高负载排查实战

3.1 读懂 load average

uptime 输出的 1.00, 0.85, 0.72 分别是 1/5/15 分钟的平均负载。Linux 内核中,”处于运行队列或 D 状态(不可中断睡眠)的任务数”会被计入,因此 load > CPU 核数 不一定意味着 CPU 满,但 load 远高于核数 + iowait 高 则一定是 IO 瓶颈。

# 实时查看 CPU 核数与负载
nproc
uptime
cat /proc/loadavg

3.2 CPU 高负载定位

top 是最快的入口,使用 P 按键按 CPU 排序,再用 Shift+P 锁定排序:

top -o %CPU -b -n 1 | head -20
# 或 pidstat 查看单进程 CPU 耗时
pidstat -u -p <PID> 1 5

如果是”系统态(sy)”占比高(如 sy 80%),常见根因是内核中断风暴或大量 syscall,可用 perf top 定位:

perf top -g
perf stat -p <PID> -- sleep 5

3.3 内存与交换异常

# vmstat 查看上下文切换、swpd 使用情况
vmstat 1 5
# free -h 看缓存回收情况
free -h
# 查看进程内存占用
ps aux --sort=-%mem | head -10
# 若出现 OOM Killer
journalctl -k -b --no-pager | grep -i oom
dmesg -T | grep -i -E "out of memory|oom"

3.4 IO 瓶颈定位

# iostat -x 2 查看每块盘 await / %util
iostat -x 2
# pidstat -d 1 找出哪个进程写入/读取最多
pidstat -d 1
# lsof 看哪个进程持有了大量打开文件
lsof +L1   # 查找已删除但仍被占用的文件

3.5 高负载应急脚本

下面是一个 5 秒快照脚本,适合在事故现场一键采集:

#!/bin/bash
OUT="/tmp/hotspot-$(date +%Y%m%d-%H%M%S).log"
{
  echo "===== $(date) uptime ====="; uptime; nproc
  echo "===== vmstat ====="; vmstat 1 3
  echo "===== free ====="; free -h
  echo "===== top CPU ====="; ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu | head -15
  echo "===== iostat ====="; iostat -x 1 3
  echo "===== df ====="; df -hT
  echo "===== dmesg last 30 ====="; dmesg -T | tail -30
} > "$OUT" 2>&1
echo "Snapshot: $OUT"

四、网络异常排查实战

4.1 排查顺序:本地 -> 链路 -> 路由 -> 名字解析

# 1) 网卡是否 up、是否有 IP
ip addr show
ip -s link

# 2) 本机监听端口与连接状态
ss -tulpn
ss -s

# 3) 路由表与策略路由
ip route show
ip rule show

# 4) ARP 与邻居
ip neigh show

4.2 DNS 异常定位

# 查看 resolv.conf 是否被覆盖
cat /etc/resolv.conf
# systemd-resolved 场景
resolvectl query example.com
resolvectl status

# 使用指定 DNS 测试
dig @8.8.8.8 example.com +short
dig example.com +trace

4.3 抓包定位连接异常

# 抓目标 IP 的所有 TCP 流量,前 100 包
sudo tcpdump -i any -nn host 10.0.0.5 and tcp -c 100 -w /tmp/cap.pcap

# 快速看包统计
tcpdump -r /tmp/cap.pcap -nn

4.4 防火墙与 iptables 排查

# 查看 UFW 状态与规则
sudo ufw status verbose
sudo iptables -L -v -n --line-numbers

# 临时放行某端口
sudo iptables -I INPUT -p tcp --dport 8080 -j ACCEPT

4.5 网络性能排查

# mtr 替代 ping+tracert
mtr -rwzbc 100 8.8.8.8

# iperf3 测带宽(服务端)
sudo apt install -y iperf3
iperf3 -s

# 客户端测试上行/下行
iperf3 -c 10.0.0.100 -t 30 -P 4

五、常见问题与应急处理速查

Q1:systemctl 提示 “failed to get unit file state”

通常是 /etc/systemd/system/*.wants 目录里有损坏的符号链接。用 systemd-analyze verify /etc/systemd/system/ 检查,删除无效链接即可。

Q2:journalctl 报 “No journal files were found”

可能是 /var/log/journal 权限错误或 Storage=volatile。检查 /etc/systemd/journald.conf,并执行 sudo systemctl restart systemd-journald

Q3:tcpdump 抓到大量 RST

RST 通常由应用主动关闭或防火墙丢弃触发。先 ss -tan state established 看连接状态,再对照 iptables -L -v -n 的计数器,定位是哪条规则丢弃了包。

Q4:开机后某服务随机未启动

systemd-analyze blame 找最慢的 Unit,再查其 ExecStart 是否依赖尚未就绪的资源(如网络、磁盘挂载)。可改用 After=network-online.targetRequiresMountsFor=

Q5:load 高但 CPU 空闲(iowait 高)

这是典型的 IO 瓶颈。用 iostat -x 1%util 是否接近 100%,pidstat -d 找出写盘大户。若是日志写入,开启异步日志或调整 fsync 策略;若是数据库,考虑分离数据盘或升级为 NVMe。

六、总结

故障排查并非玄学,而是一套 可复用、可训练 的流程。掌握以下要点即可覆盖 80% 的 Ubuntu 生产故障:

  • 分层定位:先硬件、再内核、再系统、最后应用,避免”一上来就看应用日志”。
  • 证据先行:所有结论必须基于 top/vmstat/iostat/ss/tcpdump 的输出,而不是猜测。
  • 现场保留:使用 journalctl -b -1 抓取上次启动日志,coredumpctl list 保留崩溃现场。
  • 快速止血:能重启先重启、能摘流量先摘、能降级先降级,事后再做根因分析。
  • 沉淀 Runbook:每次 P1 故障都应产出一页可执行手册,下次 3 分钟解决。

把今天的五步法、命令清单与应急脚本整理成你团队的 Runbook,下一次故障来临时,你需要的只是一次复制粘贴。

下期预告

下一篇(第 29 天)我们将进入 云原生运维——公有云 Ubuntu 实例管理与弹性伸缩,涵盖 AWS/GCP/阿里云的 Ubuntu AMI/镜像管理、实例规格选型、Auto Scaling 策略、跨可用区容灾与成本优化,带你从”单机运维”平滑过渡到”弹性集群运维”。敬请期待。

微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容