资讯动态

Linux故障排查实战手册:从系统启动到内核安全的运维方法论

发布时间:2026/9/16 0:48:13 来源:尧图企业网站定制
这份191页手册我翻了三遍说实话真正值钱的不是那些“一执行就恢复”的命令而是它把故障排查这件事从“手感流”变成了“方法流”。我见过太多运维同行平时背了一堆命令机器一宕照样手忙脚乱——不是命令不够多是脑子里没有一张完整的排查地图。这篇文章我就把手册里最核心的东西抽出来按我自己的理解重新梳理一遍结合这些年踩过的坑给你一份能直接拿去用的实战笔记。1. 故障排查的本质先别急着敲命令很多人拿到故障第一反应是“重启试试”或者看到什么报错就百度什么。这样做不是不行但效率极低而且经常治标不治本。我自己的习惯是无论多急的故障先花两分钟回答三个问题——影响范围有多大最近变更了什么故障是从什么时候开始的1.1 影响范围决定排查策略影响范围直接决定了你要用“外科手术”还是“全面体检”。比如公司内部测试环境的一台机器挂了和线上核心数据库所在的物理机告警处理节奏完全不一样。单机故障优先查OS层面、服务层面、硬件健康状态。多台机器同时故障优先查网络设备、交换路由、DNS解析、公共配置中心。整个机房或某个区域不可用优先联系网络团队检查光缆、交换机、防火墙策略。这个判断能帮你少走很多弯路。我见过有同事排查数据库连接超时在一台应用服务器上抓包抓了一上午最后发现是另一台机器上的防火墙规则被误改把整个子网的流量拦了。如果一开始就确认“所有客户端都连不上”直接查网络策略五分钟就能定位。1.2 变更记录是故障排查的第一线索“最近改了什么”这个问题太关键了甚至可以说是运维排查的“第一性原理”。大部分故障都不是无缘无故发生的而是某个变更触发的。系统更新、内核升级后出现异常 → 内核模块不兼容、驱动版本不匹配。新部署应用后内存飙升 → 代码内存泄漏或配置了过大的JVM堆。修改了DNS配置后无法解析 → 配置语法/权限/缓存问题。扩缩容后负载不均 → 负载均衡算法或会话保持策略问题。所以日常运维中变更管理一定要做。哪怕只是在服务器上改了一个配置文件也建议在运维工单或者群公告里留一条记录。排查故障的时候翻变更记录往往比抓包看日志更快。1.3 建立时间线让故障“过程化”故障不是瞬间发生的一定有一个过程。可能是监控系统发出告警可能是用户反馈开始出现异常可能是日志里某个报错开始高频出现。我建议你在排查时顺手在纸上或者文档里画一条时间轴第一次出现异常的时间点。每个异常现象出现的时间点。有无做过任何干预操作以及操作的时间点。这条时间线在后续分析日志时特别有价值。比如系统负载在凌晨3点开始升高你就能把排查范围缩小到凌晨3点左右启动的定时任务、备份脚本或日志切割任务而不是漫无目的地翻几个小时的数据。手册里很多案例都是靠这种“时间倒推法”快速圈定范围的。2. 系统启动类故障从按下电源到登录Shell的每一步排查系统启动是故障高发区。这类故障的特点是一旦发生你往往连命令都敲不了只能靠肉眼和启动日志来排查。2.1 GRUB引导失败的典型场景开机黑屏、卡在GRUB界面、或者直接显示“grub rescue”这个问题大多数和/boot分区损坏、启动项配置错误或磁盘分区表变化有关。排查思路是这样的如果卡在GRUB命令行界面先用ls命令查看所有磁盘分区找到Linux根分区所在位置。设置正确的根分区并启动set root(hd0,msdos1) linux /vmlinuz-xxx root/dev/sda1 initrd /initramfs-xxx.img boot进入系统后重新生成GRUB配置grub2-mkconfig -o /boot/grub2/grub.cfg这个过程中最容易踩的坑是分区编号搞错。磁盘上的分区编号在GRUB里从1开始但Linux设备名从0开始。比如(hd0,1)对应的是/dev/sda1而(hd0,0)对应的是/dev/sda或/dev/sda0GPT分区表情况下。搞混了就直接启动失败。现代UEFI引导环境下还要额外检查EFI分区是否挂载正常。我遇到过一台服务器因为Windows更新偷偷修改了UEFI启动顺序导致Linux引导项被挤掉开机直接进了Windows——这种问题在GRUB里折腾半天也没用得进BIOS设置里把启动顺序调回来。2.2 initramfs阶段的异常处理系统启动到一半屏幕提示找不到根文件系统、或者卡在Welcome to emergency mode八成是initramfs没有正确加载磁盘驱动或根分区无法挂载。这类问题的常规处理步骤在initramfs的救援Shell里检查磁盘是否能被识别ls /dev/sd* fdisk -l如果磁盘存在但挂载失败检查文件系统是否有损坏fsck /dev/sda1如果提示UUIDxxx does not exist用blkid查看分区实际UUID然后修改/etc/fstab或添加内核启动参数rootUUID实际值。我特别想提醒一点很多人在这种场景下会手忙脚乱地执行fsck但对一个正在运行的、数据量大且没有备份的文件系统来说盲目的fsck可能带来二次伤害。正确做法是先确认文件系统类型ext4还是xfsxfs文件系统不能用fsck直接修复需要用xfs_repair而且必须在卸载状态下执行。2.3 启动到登录界面的隐藏问题很多故障发生在服务完全启动后但表现被误认为是“启动失败”。比如某台机器重启后Nginx服务没有随系统启动但系统本身是正常启动的。这种问题的排查重点是systemd服务单元的状态systemctl list-unit-files --typeservice | grep enabled systemctl status nginx journalctl -u nginx --since today有个细节很多人不知道systemd的enable和start是两个独立操作。enable只是创建软链接让服务在开机时自动启动start是立即启动服务。如果服务重启后没有启动先检查systemctl is-enabled nginx很可能是服务虽然安装了但从未enable过。另外开机自启服务之间存在依赖关系。如果你的业务服务依赖数据库服务但服务单元的After和Requires字段没写对就可能出现数据库还没起来业务服务已经尝试连接并失败了。这种故障在日志里表现为“Connection refused”但在启动顺序逻辑里根因是依赖声明缺失。3. 磁盘与文件系统故障运维日常遭遇战的重灾区磁盘故障是运维日常处理频率最高的问题。很多时候看起来只是“应用报错”“服务启动失败”实际查下去根因是磁盘满了或者文件系统出了问题。3.1 磁盘空间满但df -h看不出异常的坑经典案例df -h显示磁盘使用率才60%但应用就是写不进文件。这时候十有八九是inode耗尽了。df -iinode是文件系统用来记录文件元数据的数据结构。文件系统在格式化时inode的数量就固定了动态inode的文件系统除外。如果磁盘上有大量小文件比如定时任务每分钟创建一个几千字节的日志文件、邮件队列积压了大量未发出邮件inode耗尽的速度远比磁盘空间耗尽快得多。排查和处理方式# 查看哪个目录占用了大量小文件 find / -xdev -type f | awk -F/ {print $2} | sort | uniq -c | sort -rn | head # 找到后直接清理过期文件 find /data/logs -type f -mtime 30 -delete还有一个更隐蔽的坑已删除的文件仍被进程占用。某个进程打开了一个日志文件后来你用rm把它删了但进程没有重启它仍然持有该文件的句柄磁盘空间不会释放。这种情况df -h会显示磁盘已满但du -sh *统计出来的总大小却对不上。# 找出已删除但仍被占用的文件 lsof | grep deleted确认后直接重启对应进程或kill掉空间就会释放。3.2 解压文件乱码的根源不是压缩包是编码热词里提到“linux 解压文件乱码”这个在ZIP格式的压缩包上特别常见。原因很简单ZIP压缩包内记录的文件名使用了GBK/GB18030编码而Linux默认使用UTF-8编码。用unzip直接解压就会出现乱码。解决办法是安装unzip的补丁版本或其他解压工具# 使用 unar 替代 unzip unar filename.zip # 或者使用 python3 的 zipfile 模块指定编码 python3 -c import zipfile; zf zipfile.ZipFile(filename.zip); [zf.extract(f, pathout, pwdNone) for f in zf.namelist()]对于使用标准tar格式打包的文件遇到乱码通常是系统locale没设置好。检查locale命令输出如果LANG为空或者C中文文件名就会显示乱码。设置export LANGen_US.UTF-8后重新解压即可。我习惯在服务器上预装unar并写进初始化脚本遇到乱码ZIP直接用它解压几乎不用再纠结编码问题。3.3 文件系统变成只读看到这个就要高度警惕Read-only file system这个报错出现时别只想着remount解决。这是内核为了保护数据主动挂起的只读状态通常意味着底层I/O错误或文件系统检测到严重的一致性损坏。正确做法先看dmesg里有没有磁盘I/O错误、RAID降级、SCSI错误等信息。检查硬件健康状态smartctl -a /dev/sda查看S.M.A.R.T.信息重点看Reallocated_Sector_Ct和Current_Pending_Sector。如果是硬件问题磁盘该换就换。只读挂载是内核在帮你止损不是故障本身。如果确认是文件系统逻辑损坏# 卸载文件系统如果是根分区可能需要进入救援模式 umount /data fsck -y /dev/sdb13.4 磁盘性能问题的判断很多时候应用慢不是代码问题而是磁盘性能扛不住了。排查手段依赖几个指标的组合iostat -x 1重点看%util、svctm、await、r_await和w_await。%util接近100%说明磁盘打满。await远高于svctm说明I/O在排队系统性能瓶颈在存储层。w_await明显高于r_await说明写放大严重可能和日志同步模式fsync频繁有关常见于数据库场景。如果是云服务器先确认是不是和邻居争抢磁盘I/O如果是物理机用hdparm -t /dev/sda做简单基准测试看看是不是硬件退化。另外别忘了看dmesg有没有TCP丢包相关的报错——听起来矛盾但网络文件系统NFS、Ceph的延迟会直接表现为本地磁盘I/O变慢。4. 网络故障排查从DNS到TCP的完整链路网络是运维排查中信息量最大的领域但如果没头绪也是最容易让人崩溃的领域。我常用的排查顺序是先应用层DNS、HTTP状态再传输层端口、连接数、TCP状态最后网络层路由、抓包。4.1 DNS配置的经典问题热词里有“linux中配置dns出现的问题”我几乎每个月都能遇到。最常见的几个系统解析慢或超时/etc/resolv.conf里配置了不可达的DNS服务器导致每次解析都要等超时。# 测试DNS服务器连通性 nslookup www.example.com 223.5.5.5 # 使用dig观察解析耗时 dig www.example.comping通IP但ping不通域名这种情况基本就是DNS解析问题优先检查resolv.conf和/etc/nsswitch.conf中hosts:行的配置顺序。公司内部域名解析失败检查是否配置了正确的search domain例如search internal.example.com。比如访问gitlab系统会自动补全为gitlab.internal.example.com如果search没配就没法用短域名访问。systemd-resolved占用53端口新版Ubuntu/CentOS上systemd-resolved会监听127.0.0.53:53如果你自己装了dnsmasq或使用了Docker可能和这个端口冲突。解决办法是关闭systemd-resolved或调整dnsmasq监听地址。4.2 端口与连通性排查必备技能判断一个服务是否正常监听最先用的命令当然是ss -lntp。但怎么从中精准定位问题还是有讲究的。# 查看所有监听端口 ss -lntp # 查看已建立的连接数量按状态统计 ss -ant | awk {print $1} | sort | uniq -c # 查看某个端口的连接数 ss -ant | grep :3306 | wc -l如果服务端口明明在监听但外部访问不通按这个顺序排查本机回环测试curl http://127.0.0.1:8080确认服务本身正常。检查防火墙iptables -L -n或firewall-cmd --list-all看是否有规则拦截了源IP或目标端口。检查监听地址ss -lntp里看服务是监听在0.0.0.0还是127.0.0.1。如果只听在127.0.0.1上外部当然访问不了。这个配置很多新手会忽略。检查云安全组/网络ACL这是云环境里独有的坑经常有安全组规则限制了来源IP。4.3 TCP连接数满与TIME_WAIT堆积“Too many open files”是应用报错“connection timed out”是客户端看到的表象但追溯到服务端往往就是连接数满了。分两个层面排查文件描述符限制修改/etc/security/limits.conf调高nofile限制。* soft nofile 65535 * hard nofile 65535TCP连接表耗尽高并发下本地端口范围ip_local_port_range不够用时客户端会报Cannot assign requested address。# 扩大本地端口范围 sysctl -w net.ipv4.ip_local_port_range1024 65535TIME_WAIT堆积是个老生常谈的话题。如果短连接特别多TIME_WAIT连接会大量堆积占用内存和连接表项。常规调优方式sysctl -w net.ipv4.tcp_tw_reuse1 sysctl -w net.ipv4.tcp_fin_timeout30顺带提一句tcp_tw_recycle这个参数在NAT环境下有严重问题千万别开。它会导致NAT后面不同客户端的时间戳被比较出现随机丢包。这也是手册里明确提醒过的“坑中之坑”。4.4 外接显示器无画面与GPU相关排查这个看着像硬件问题但Linux下很多时候是显卡驱动或显示服务的锅。排查步骤先确认显示器有没有被系统识别xrandr。如果识别到了但没画面检查显示输出端口手动指定分辨率xrandr --output HDMI-1 --mode 2560x1440 --rate 60如果完全没有识别大概率是显卡驱动问题。查看lspci | grep VGA确认显卡型号然后看系统日志journalctl -b -p err | grep -i drm。常见场景是NVIDIA显卡装好驱动后外接显示器无画面。这时需要检查NVIDIA驱动和Xorg配置的兼容性考虑用nvidia-settings重新生成配置。如果是笔记本还要考虑双显卡切换Prime/optimus的配置问题设置prime-select输出显卡。5. 内核与安全突发事件运维的终极试炼这类问题平时遇不到遇到就是大事件。故障表现诡异日志指向不明排查难度直线上升。5.1 内核模块异常与read/write拦截热词里有“linux 内核 动态加载 file_operations 拦截 read write”这通常出现在三类场景透明加密对磁盘上落盘文件进行实时加解密。安全审计监控应用程序对敏感文件的读写行为。恶意后门通过内核模块hook掉syscall来窃取数据或隐藏进程。正常运维场景下我们主要接触前两类。排查可疑内核模块的方法# 列出已加载模块 lsmod # 查看模块详细信息 modinfo module_name # 查看模块对应的设备文件 cat /proc/devices如果是透明加密场景要注意文件系统层面的加解密对性能的影响。CPU占用可能飙升到接近100%而且随机读写性能会明显下降。排查时用iostat和top联合观察确认是加密模块的CPU消耗还是I/O排队消耗。另外如果某个内核模块加载失败导致系统不稳定# 从启动黑名单中移除或添加 vim /etc/modprobe.d/blacklist.conf # 或临时卸载 modprobe -r module_name5.2 内核动态跟踪工具的用法面对这类问题strace和perf往往比翻日志更快。strace -p PID可以动态查看进程正在执行的系统调用。strace -e traceopen,read,write -p PID只看文件读写相关调用。perf top可以实时查看内核函数级别的CPU热点。我处理过一起诡异故障某个应用启动后每隔几分钟就卡死一次日志无报错dmesg也没异常。用perf trace -p跟进后发现是应用在频繁读取一个配置目录下的所有文件而这个目录挂在NFS上NFS服务端响应超时导致每次读取都阻塞。这类问题如果不用内核级追踪工具光看应用日志很难定位。5.3 Linux提权事故的安全排查视角热词里出现的“linux提权”从运维防御视角看排查的是“系统是否被攻击者利用了提权漏洞”。我一般按以下顺序排查检查当前系统的异常登录记录last和lastb重点看非常用IP和非常用时间段的登录。查看系统用户文件是否有异常新增awk -F: $30{print $1} /etc/passwdUID为0的用户理论上只能有root一个。检查计划的定时任务crontab -l以及所有用户下的/etc/cron.*目录。查看历史命令history如果被清除过结合/var/log/auth.log或者shell的history文件时间戳判断。用rkhunter或chkrootkit做一次基础检查。真实案例里提权攻击后攻击者通常会做三件事创建后门账号、植入定时任务、替换系统命令。所以排查顺序也对应这三点来。发现异常后第一时间隔离网络然后备份日志再做深入分析。千万别在受感染的机器上直接清理那样会毁了取证数据。5.4 内核panic与kdump系统直接黑屏重启、或卡在内核panic界面这是运维的噩梦。处理这种问题关键信息在panic时的调用栈里。内核启动参数里配置了crashkernelauto并且安装了kdump服务的话panic时/var/crash/目录下会生成vmcore文件。用crash工具分析crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/xxx/vmcore不过很多时候kdump服务都没配置。这种情况下只能通过两种方式定位启用串口或BMC控制台捕获完整的内核日志。配置pstore/ramoops让内核panic时把日志写到内存保留区。我处理过的一起panic事件根因是某个公司自研的内核模块在内存分配失败时没有判空就直接解引用最后在驱动代码里加了一个NULL检查就彻底解决了。这类问题任何用户态日志都看不到只能靠内核崩溃信息定位。6. 性能排查与命令组合用最少操作获得最多信息手册191页里大量内容其实是性能排查的命令组合。同样的命令不同的人用出来效果完全不同区别在于组合方式和观察顺序。6.1 系统负载高的第一梯队命令负载高load average很高是个模糊的症状可能是CPU瓶颈也可能是不可中断的I/O等待。第一步永远是拆分top # 或 htop观察两个核心指标us用户态CPU和sy内核态CPU占用高 → CPU密集型问题。waI/O等待占用高 → 磁盘或存储层瓶颈。hi和si硬件/软件中断占用高 → 网络中断或驱动问题。如果是CPU问题用top找到PID后进入单线程视角top -H -p PID # 或 pidstat -t -p PID 1确定是哪个线程在消耗CPU再配合strace或jstackJava应用分析线程的调用栈就能定位到具体代码逻辑。如果是I/O问题回到iostat -x 1结合pidstat -d 1定位是哪个进程在疯狂读写pidstat -d 1 | awk $NF 06.2 内存问题的排查思路内存问题比CPU问题隐蔽得多。free -h显示内存不多时先别急着加内存分清楚是哪些进程占用的。# 查看内存占用TOP10进程 ps aux --sort-%mem | head -11 # 查看页缓存和可回收内存 cat /proc/meminfo | grep -E ^(MemTotal|MemFree|Cached|Buffers|SReclaimable)Linux的内存管理机制下空闲内存会被当成页缓存使用free看到的used高不代表内存不够。真正需要关注的是swap的使用情况# 查看swap占用 free -h # 查看使用了swap的进程 for file in /proc/*/status; do awk /VmSwap/{swap$2} /Name/{name$2} END{if(swap0) print name, swap/1024 MB} $file 2/dev/null; done | sort -k2 -rn | head如果swap换入换出频繁说明内存确实吃紧。先用sysctl vm.swappiness10降低swap使用倾向再看有没有进程能优化或重启。内存泄漏问题用top观察结论可能滞后长期排查建议用valgrind或jemalloc的profiling功能。6.3 黄金五分钟排查法我习惯把故障发生后最初的五分钟叫做“黄金五分钟”。这五分钟里做的操作决定了后续排查是高效还是抓狂。按顺序执行下面这组命令把输出保存到文件里后面慢慢分析date uptime dmesg -T | tail -50 free -h df -h df -i top -b -n 1 | head -30 ss -ant ss -lntp last -5 ps aux --sort-%cpu | head -15 ps aux --sort-%mem | head -15这组命令看着简单但能覆盖系统状态、内核日志、磁盘空间、磁盘inode、CPU/内存占用、网络连接状态、监听端口、登录记录、进程列表这些核心信息。故障排查看似复杂核心就是“留痕”——把关键时刻的系统快照留下来再逐项缩小范围。6.4 日志分析的正确打开方式排查任何问题之前先把日志这步做扎实了能省一半时间。系统全局日志/var/log/messagesCentOS或/var/log/syslogUbuntu。登录认证日志/var/log/secureCentOS或/var/log/auth.logUbuntu。内核日志journalctl -k或dmesg。应用日志通常应用自己管理路径五花八门但可以通过systemd的unit确认输出去向journalctl -u service-name。一个很容易被忽略的点日志时间同步。如果服务器没有配置NTP各台机器时间漂移严重排查看日志时对不上时间线会非常痛苦。我就试过两台机器日志时间差了20分钟导致排查方向完全错误。所以基础配置里NTP同步这一步千万别省。7. 常见问题速查从现象到处理一步到位结合手册内容和实操经验我把最常遇到的典型问题整理成一个速查表。这张表的价值在于在压力状态下人很容易大脑空白有一张表照着做至少不会乱现象可能原因快速检查命令处理动作系统负载高但CPU空闲I/O等待过高iostat -x 1定位读写进程优化或更换存储磁盘空间显示满但删不掉文件被进程占用lsof | grep deleted重启占用进程确认空间释放df空间有余但写文件报错inode耗尽df -i清理小文件调整定时任务策略应用端口无法访问防火墙/监听地址错误ss -lntp、iptables -L -n调整防火墙规则修改监听配置DNS解析超时resolv.conf配置异常dig 223.5.5.5 domain修改DNS配置排查53端口占用服务重启后未自动启动systemd未enablesystemctl is-enabled name执行systemctl enable name服务器响应慢且内存吃紧swap频繁vmstat 1、free -h优化应用内存调整swappiness文件系统变只读硬件I/O错误或文件系统损坏dmesg、smartctl -a备份数据、更换磁盘、fsck系统时间与标准时间不一致NTP未同步timedatectl、ntpdate -q配置chrony或systemd-timesyncd内核模块加载失败模块依赖缺失或内核版本不匹配dmesg | grep -i module重编模块确认内核头文件版本8. 最后再分享几个日常排查的实用习惯刷完这份手册我最大的感触是运维的功夫不在故障发生时而在故障发生前。如果你平时没积累排查工具、没优化过系统参数、没做过压测演练那遇到故障时只能靠临场发挥对经验和运气的要求太高。第一建立属于自己的排查Checklist。手册里给的模板只能当参考每个公司的业务和技术栈都不一样你需要根据自己的环境往里面补充内容。比如你的环境里有MySQL那就把mysqladmin status、SHOW PROCESSLIST;、慢查询日志路径这些写进去有Redis就把redis-cli info的关键指标加进去。第二训练自己“不看文档也能敲出关键命令”的能力。故障发生时往往压力山大临时翻文档会耽误时间。我建议每个运维至少闭着眼能敲出来这组df -h、free -h、top、ss -lntp、dmesg -T | tail -50、journalctl -xe、iostat -x 1、pidstat -d 1。这8条命令覆盖了大部分故障的第一轮排查。第三执行任何破坏性操作之前先想为什么。删文件、清日志、重启服务、重装依赖这些动作做了就回不了头了。先确认这个操作能解决什么问题、会不会引发别的问题、有没有更保守的替代方案。尤其在拿不准的时候先备份再操作。备份的成本永远比恢复数据低很多。第四把每次故障处理记录成文档。故障处理完趁着记忆还热把背景、现象、排查过程、根因、处理动作、后续改进点写成一篇复盘文档。这份文档比任何培训材料都有价值因为它本质上是为你自己的场景量身定制的知识库。手册写得再全也不如你自己记录的“实战笔记”来得对症。Linux运维这条路上故障是躲不掉的但痛苦可以避免。方法无非就是平时多积累故障时别慌按方法一步步来处理完记得复盘。希望你以后遇到服务器报警时能多一分从容少一分手忙脚乱。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价