ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux运维实战:从系统管理到性能调优的完整问题排查指南

Linux运维实战:从系统管理到性能调优的完整问题排查指南 1. 项目概述为什么我们需要一本“Linux常见问题”手册干了这么多年运维和开发我电脑里一直有个叫“救火笔记”的文件夹里面密密麻麻记满了各种稀奇古怪的Linux问题。从“系统突然连不上网了”到“磁盘空间一夜之间神秘消失”再到“某个服务死活起不来日志还一片空白”。这些问题教科书上不会写官方文档也常常语焉不详但它们却是每个Linux使用者无论是新手还是老鸟都必然会遇到的“坎”。“Linux常见问题01”这个标题听起来平平无奇甚至有点像是那种敷衍了事的文档合集。但在我看来它应该是一份“生存指南”。Linux系统以其稳定和强大著称但它的“沉默寡言”也常常让人抓狂。一个命令输错可能不会立刻报错但会在几天后引发一场灾难一个配置文件的某个参数没理解透服务就可能以你完全意想不到的方式运行。这份手册的目的不是罗列命令而是聚焦于那些真正卡住过无数人的、具有代表性的“坑”并讲清楚背后的原理和“一脚踢开”这个坑的实操方法。它适合所有正在或即将与Linux打交道的人刚入门的新手可以把它当作避坑地图有经验的工程师可以把它作为疑难杂症的速查手册甚至能从中发现一些自己未曾留意的系统细节。2. 核心问题域与分类解析面对海量的Linux问题眉毛胡子一把抓肯定不行。根据我多年的“救火”经验可以将高频问题归纳为几个核心领域这不仅能帮助我们系统化地学习也能在遇到问题时快速定位方向。2.1 系统管理与运维类问题这类问题是运维人员的日常也是新手最容易感到困惑的地方。它们通常围绕着系统的生命周期和资源状态。系统启动与初始化问题这是问题的“源头”。比如常见的GRUB引导失败屏幕上出现grub rescue提示符或者系统启动后卡在某个服务如network、plymouth-quit-wait无法进入图形界面。这类问题的排查需要理解 Linux 的启动流程BIOS/UEFI - Bootloader - Kernel - Initramfs - systemd并掌握使用 Live CD 或救援模式进行修复的技巧。用户、权限与文件系统问题Permission denied是每个Linux用户的“老朋友”。但更深层的问题包括sudo配置错误导致权限提升失败/etc/passwd或/etc/shadow文件损坏导致无法登录磁盘inode用尽df -i查看即使磁盘空间充足也无法创建新文件以及SELinux或AppArmor安全模块导致的“明明权限都对就是访问不了”的诡异情况。软件包管理与安装问题不同发行版Debian/Ubuntu的apt RHEL/CentOS的yum/dnf Arch的pacman的包管理机制各异。典型问题有软件源配置错误或失效导致的404 Not Found依赖关系地狱Dependency Hell编译安装时缺少头文件或开发库如-devel、-dev包以及动态链接库丢失error while loading shared libraries。2.2 网络与服务配置类问题Linux作为服务器操作系统网络和服务是其核心价值所在相关问题也最为复杂和关键。网络连接与配置故障这是最常遇到的问题之一。现象包括网卡无法获取IPDHCP失败、手动配置静态IP后无法上网、防火墙iptables/nftables或firewalld规则阻断了关键端口、DNS解析失败ping通IP但无法解析域名。排查这类问题需要熟练使用ip addr、ip route、ss、dig、nslookup等网络诊断工具并理解网络配置文件的层次Netplan、NetworkManager、systemd-networkd。服务进程管理与调试在systemd成为主流的今天服务管理看似简单systemctl start/stop/status xxx但背后隐藏着许多细节。例如服务状态显示active (exited)或failed时分别意味着什么如何查看和分析服务的详细日志journalctl -u service_name -f如何自定义服务的启动顺序、依赖关系和资源限制通过.service文件这些问题直接关系到服务的可用性和稳定性。远程访问与安全加固SSH无法连接是一个经典问题。原因可能包括服务未监听、防火墙拦截、sshd_config配置过于严格如禁止密码登录、禁止root登录、客户端与服务端的密钥交换算法不匹配。此外如何安全地配置SSH密钥对登录、禁用密码登录也是必须掌握的实操技能。2.3 性能与资源排查类问题当系统变慢、服务响应延迟时就需要像侦探一样使用各种工具来定位瓶颈。资源瓶颈定位核心是四大资源CPU、内存、磁盘I/O、网络I/O。你需要知道CPU使用top或htop查看哪个进程的%CPU或%us用户态过高。是计算密集型任务还是陷入了无尽的循环内存free -h显示内存总量但更要关注available字段。top中的VIRT、RES、SHR、%MEM分别代表什么什么是缓存cache和缓冲buffer何时需要警惕Swap的使用磁盘I/O使用iostat、iotop工具。是哪个进程在疯狂读写磁盘是磁盘本身速度慢await值高还是遇到了大量随机小文件读写网络I/O使用iftop、nethogs查看带宽占用和进程级流量。日志分析与监控/var/log/目录下的日志文件如messages、syslog、secure、 特定服务的日志是排查问题的金矿。你需要熟练使用grep、awk、sed、tail -f等文本处理工具来快速过滤和定位关键错误信息。同时理解rsyslog或systemd-journald的日志管理系统对于集中化日志收集和分析至关重要。2.4 开发与编译环境类问题对于开发者而言在Linux上搭建顺手的开发环境本身就是一个挑战。编译工具链问题安装gcc/g、make、cmake后编译开源项目依然报错“找不到xxx.h文件”或“对xxx函数未定义的引用”。这通常是因为缺少对应的开发库libxxx-dev。你需要理解头文件-I指定路径、库文件-L指定路径-l指定库名在编译和链接阶段的作用。环境变量与路径问题command not found是家常便饭。这涉及到$PATH环境变量的设置。如何为当前会话临时添加路径如何为用户永久修改~/.bashrc或~/.profile如何为所有用户修改/etc/profile或/etc/environment此外JAVA_HOME、PYTHONPATH等特定于语言的环境变量配置也经常是坑点。容器与虚拟化相关随着Docker和Podman的普及相关问题也多了起来。比如容器内无法解析外部域名DNS配置问题、容器时间与宿主机不一致时区挂载、docker.sock权限问题、以及使用WSLWindows Subsystem for Linux时遇到的“适用于 linux 的 windows 子系统必须更新到最新版本”这类跨平台特有的问题。3. 典型问题深度拆解与实战解决理论归理论实战才是检验真理的唯一标准。下面我挑选几个极具代表性且折磨过无数人的问题进行深度拆解并给出一步步的解决方案和原理剖析。3.1 问题一磁盘空间告急但du和df结果对不上问题现象服务器监控报警磁盘使用率超过90%。你用df -h查看确实如此。但当你用du -sh /去统计根目录下所有文件大小时发现总和远小于df显示的使用量。空间被谁“偷”了原理剖析dfdisk free报告的是文件系统层面的磁盘块使用情况它统计的是所有被占用的数据块包括文件数据和元数据。dudisk usage报告的是目录树层面的磁盘使用情况它通过遍历文件系统树累加每个文件的块数。两者不一致的常见原因有已删除文件但未释放空间一个进程打开了一个大文件然后这个文件被删除rm。在进程结束前该文件所占用的磁盘空间不会被释放因为进程仍持有其文件描述符。df会显示空间被占用但du找不到这个已删除的文件所以不计入。这就是著名的“文件删除但空间未释放”问题。文件系统元数据或日志占用某些文件系统如ext3/4的日志xfs的元数据会预留或占用一部分空间这部分空间du无法统计到。磁盘配额Quota如果启用了用户或组的磁盘配额df显示的是整个文件系统的使用情况而du统计的是当前用户可见的文件可能因配额限制而不同。实战解决步骤首先定位被进程占用的已删除文件。使用lsof命令。lsof | grep deleted这条命令会列出所有状态为“deleted”但文件描述符仍被进程打开的文件。输出会显示进程PID、命令名和文件大小。这是最可能的原因。处理这些“僵尸”文件。找到对应的进程PID。如果该进程不重要可以直接重启kill -9 PID空间会立即释放。但务必谨慎如果是一个重要的数据库或Web服务进程盲目杀死可能导致数据损坏或服务中断。正确的做法是联系相关服务负责人优雅地重启该服务例如systemctl restart mysql。如果不是已删除文件的问题检查是否是文件系统本身的问题。可以尝试检查是否有挂载点mount异常。对于ext系列文件系统使用tune2fs -l /dev/sdX查看保留块比例默认为5%。使用xfs_db或btrfs相关工具检查对应文件系统的内部状态此操作风险较高建议在了解或备份后进行。实操心得养成习惯在删除大文件尤其是日志文件前先确认是否有活跃进程正在写入它。更安全的做法是使用truncate或echo ‘’ file.log清空内容而不是直接rm。对于日志文件最佳实践是使用logrotate工具进行轮转和管理。3.2 问题二SSH连接超时或被拒绝如何一步步排雷问题现象尝试从客户端ssh userserver_ip长时间等待后提示Connection timed out或者立刻返回Connection refused。原理与排查思路 这是一个经典的网络排查问题需要遵循从宏观到微观、从外到内的顺序。Connection timed out通常意味着网络不通。可能是IP错误、防火墙客户端、服务器、中间网络设备阻断了连接请求或者服务器根本就没开机。Connection refused通常意味着网络是通的连接请求到达了服务器但目标端口默认22上没有服务监听。可能是sshd服务没启动或者监听了其他端口。实战解决步骤从客户端到服务端层层排查基础连通性检查ping server_ip如果不通检查IP地址是否正确、服务器是否在线、客户端网络配置网关、DNS是否有问题。端口可达性检查telnet server_ip 22 # 或者使用更专业的 nc (netcat) nc -zv server_ip 22如果telnet卡住或nc超时说明请求可能被防火墙拦截。如果立刻返回Connection refused说明端口无服务监听。如果成功连接并看到类似SSH-2.0-OpenSSH_xxx的横幅说明端口和服务正常问题可能出在SSH协议或认证层面。服务端检查 如果前两步失败你需要通过其他方式如云控制台VNC、本地终端登录服务器进行检查。检查服务状态systemctl status sshd确保服务是active (running)。检查监听端口ss -tlnp | grep :22 # 或 netstat -tlnp | grep :22 (较老系统)确认sshd进程正在监听0.0.0.0:22或[::]:22表示监听所有IPv4/IPv6接口。检查防火墙如果使用firewalldfirewall-cmd --list-all查看services:中是否包含ssh或者ports:中是否开放了22/tcp。如果使用iptablesiptables -L -n查看是否有针对22端口或ssh的ACCEPT规则。注意链的顺序INPUT, FORWARD, OUTPUT。检查SELinux如果启用getenforce如果结果是Enforcing可以尝试临时设置为Permissive来测试是否是其导致的问题setenforce 0注意这只是测试生产环境需谨慎并应配置正确的SELinux策略。SSH配置检查 如果服务运行且端口开放但连接仍有问题检查/etc/ssh/sshd_configPort是否修改了默认端口ListenAddress是否只监听了特定IP如127.0.0.1PermitRootLogin是否禁止了root登录这通常导致认证失败而非连接拒绝。AllowUsers/DenyUsers是否限制了可登录的用户 修改配置后务必重启服务systemctl restart sshd。避坑技巧在云服务器如AWS EC2, 阿里云ECS上除了系统内部的防火墙更重要的是**安全组Security Group**规则。务必在云控制台检查入站规则是否允许来自你客户端IP的22端口TCP流量。这是新手最常忽略的一点。3.3 问题三sudo执行命令报错 “user is not in the sudoers file”问题现象新创建了一个普通用户尝试使用sudo提权时失败。原理剖析sudo的权限控制核心在于/etc/sudoers文件。该文件定义了哪些用户、在哪些主机上、可以以哪些其他用户的身份、运行哪些命令。普通用户默认不在这个授权列表里。直接编辑这个文件是危险的语法错误可能导致所有sudo权限失效。因此推荐使用visudo命令它会在保存前进行语法检查。实战解决步骤使用root用户或已有sudo权限的用户登录。运行visudo命令。这会用默认编辑器通常是vi打开/etc/sudoers文件。找到授权规则部分。你会看到类似这样的行root ALL(ALL:ALL) ALL %sudo ALL(ALL:ALL) ALLroot是用户名。%sudo表示sudo用户组。在Debian/Ubuntu系发行版中将用户加入sudo组是更常见的做法。ALL第一个适用于所有主机。(ALL:ALL)可以以任何用户第一个ALL和任何用户组第二个ALL的身份执行命令。最后一个ALL可以执行所有命令。为用户授权。有两种主流方式方式一将用户加入sudo组推荐便于管理usermod -aG sudo your_username-aG参数表示“追加append到某个组Group”避免将用户从其他组中移除。方式二在/etc/sudoers中直接添加一行 在visudo中找到User privilege specification部分添加一行your_username ALL(ALL:ALL) ALL这赋予了该用户与root相同的sudo权限需要输入自己的密码。如果你想更精细地控制可以限制命令例如your_username ALL(ALL:ALL) /usr/bin/systemctl restart nginx, /usr/bin/apt update这样该用户只能sudo执行重启nginx和更新软件源这两个命令。保存并退出。在vi编辑器中按Esc输入:wq回车。验证。切换到新用户su - your_username然后尝试执行sudo whoami。系统会提示输入该用户的密码不是root密码输入正确后应返回root。重要警告永远不要给sudo权限设置NOPASSWD无需密码除非在极其特殊和受控的环境下。这是巨大的安全风险。另外visudo的语法检查是你的安全网切勿直接使用普通文本编辑器修改/etc/sudoers。4. 高效排查工具箱与命令精讲工欲善其事必先利其器。掌握一套高效的命令组合能让你在问题面前快人一步。4.1 系统状态一览top/htop、vmstat、dstattop经典的动态进程查看器。重点关注load average1, 5, 15分钟的系统平均负载。对于单核CPU持续大于1表示有进程在排队多核CPU则需除以核心数看。%Cpu(s)us用户态、sy系统态、id空闲、waI/O等待。高wa通常意味着磁盘瓶颈。进程列表按PCPU排序、M内存排序、T时间排序。htoptop的增强版彩色界面支持鼠标操作横向柱状图显示CPU和内存体验更好。通常需要额外安装apt install htop/yum install htop。vmstat 1以1秒为间隔报告虚拟内存统计。关键列r运行队列中的进程数。b等待I/O的阻塞进程数。swpd使用的交换分区大小。si/so每秒从磁盘交换进内存/从内存交换出磁盘的数据量KB。如果so持续大于0说明内存严重不足正在发生频繁交换性能会急剧下降。dstat全能型系统资源统计工具可以同时看CPU、磁盘、网络、内存、中断等。例如dstat -cdngy 1可以综合查看。4.2 网络诊断利器ss、netstat、tcpdumpssnetstat的现代替代品速度更快信息更详细。常用组合ss -tlnp查看所有TCP监听端口及对应进程。ss -tan state established查看所有已建立的TCP连接。ss -s查看 sockets 统计摘要。netstat虽然较老但依然广泛使用。netstat -tulnp功能类似ss -tulnp。tcpdump网络抓包分析的瑞士军刀。基础用法tcpdump -i eth0 port 80 -w capture.pcap监听eth0网卡上80端口的流量并保存到文件。用Wireshark分析.pcap文件更直观。更复杂的过滤表达式可以精确抓取特定主机、协议的数据包。4.3 文件与文本处理find、grep、awk、sed这些是Linux命令行下的“四大天王”组合使用威力无穷。find查找文件。示例查找/var/log下7天内修改过的、大于10M的.log文件。find /var/log -name *.log -mtime -7 -size 10Mgrep文本搜索。-r递归-n显示行号-i忽略大小写-v反向选择。结合正则表达式功能强大。grep -r -n error /var/log/nginx/awk文本分析处理语言。最常用的是按列处理。例如打印ps aux输出的第2列PID和第11列命令ps aux | awk {print $2, $11}sed流编辑器用于对文本进行替换、删除、插入等操作。例如将文件中的所有 “foo” 替换为 “bar”sed -i s/foo/bar/g filename.txt-i表示直接修改原文件务必先备份或测试。4.4 进程与调试strace、lsof、psstrace跟踪进程的系统调用和信号。这是调试程序“在干什么”的神器。例如查看一个命令启动了哪些文件strace -e traceopen,openat ls 21 | grep \.so\|\.conf或者跟踪一个正在运行的进程strace -p PIDlsof列出打开的文件。如前所述可以找已删除文件也可以查看某个端口被谁占用lsof -i :8080ps进程快照。aux或ef参数组合最常用。结合grep和awk进行过滤和格式化输出。5. 进阶场景与深度问题探讨解决了常见问题后我们会遇到一些更复杂、更深层次的挑战。这些问题往往涉及系统底层原理和多组件协同。5.1 系统性能调优实战从发现瓶颈到解决假设一个Web服务器响应变慢top显示CPU的waI/O等待很高。确认瓶颈使用iostat -x 1查看磁盘I/O状况。关注%util设备利用率接近100%表示饱和和await平均I/O等待时间单位毫秒值越大越慢。定位元凶使用iotop需安装查看是哪个进程在进行大量I/O操作。分析原因如果是数据库进程如mysqld可能是查询未优化、索引缺失、缓冲池innodb_buffer_pool_size太小导致大量物理磁盘读。如果是日志写入进程检查是否开启了过于详细的调试日志或者日志轮转logrotate配置不当导致单一日志文件巨大。如果是应用进程可能是它在频繁读写临时文件或进行大量的序列化/反序列化操作。实施优化数据库优化慢查询增加索引调整内存参数。考虑将数据和日志放在不同的物理磁盘上。磁盘如果硬件允许使用SSD替代HDD。使用RAID提升I/O性能如RAID 10。文件系统根据负载特性选择合适的文件系统如XFS对大型文件和高并发写入有优势。内核参数调整vm.dirty_ratio、vm.dirty_background_ratio等参数控制脏页待写回磁盘的数据的回写策略避免瞬间大量I/O堵塞。修改内核参数需极其谨慎并充分测试。5.2 容器化环境下的特殊问题在Docker/Podman环境中问题往往具有“隔离性”。容器内时间错误容器默认使用UTC时间且与宿主机共享时钟。如果容器内应用需要特定时区可以在运行容器时挂载宿主机时区文件docker run -v /etc/localtime:/etc/localtime:ro ...或者在Dockerfile中设置环境变量TZAsia/Shanghai并安装tzdata包。容器网络问题容器无法访问外网。首先在容器内ping 8.8.8.8测试基础连通性。如果不通检查宿主机的网络和防火墙设置。Docker的网桥配置docker network ls,docker network inspect。容器的DNS配置docker run --dns 8.8.8.8或在daemon.json中配置。“WSL需要更新”问题在Windows上使用WSL时如果遇到“适用于 linux 的 windows 子系统必须更新到最新版本”的提示这通常意味着WSL 1到WSL 2的转换或内核组件需要更新。解决方案是以管理员身份打开PowerShell。更新WSL内核组件wsl --update。如果问题依旧可能需要设置默认版本wsl --set-default-version 2。确保Windows系统本身已更新到支持WSL 2的版本。5.3 内核与驱动相关疑难杂症这类问题通常比较棘手需要一定的内核知识。内核模块KO文件问题加载第三方驱动.ko文件时失败报错“Invalid module format”或“Unknown symbol”。这通常是因为内核版本不匹配。你需要为当前运行的内核重新编译该驱动模块。使用uname -r查看内核版本并确保你有对应版本的内核头文件kernel-headers或linux-headers包。“No space left on device”但磁盘有空间除了之前提到的inode用尽还可能是因为进程打开了太多文件达到了用户或系统的文件描述符限制。使用ulimit -n查看当前用户的限制使用cat /proc/sys/fs/file-nr查看系统级别的已用/最大文件句柄数。可以在/etc/security/limits.conf中永久修改限制。6. 构建个人知识体系与持续学习Linux的世界浩如烟海记住所有命令和问题解决方案是不可能的。比记忆更重要的是建立一套属于自己的问题排查方法和知识管理体系。建立你的“命令手册”不要死记硬背复杂的命令参数。而是为最常用的复杂命令创建别名Alias或简易脚本Shell Script。例如在~/.bashrc中添加alias mydfdf -hT | grep -v tmpfs alias mypsps auxf | head -20 function findlarge() { find ${1:-.} -type f -size ${2:-100}M 2/dev/null | xargs du -h | sort -rh | head -20; }这样mydf查看磁盘myps看关键进程findlarge . 50找当前目录下大于50M的文件。善用手册和文档遇到陌生的命令第一时间man command。man手册是权威。对于复杂工具如systemd、iptables其官方文档通常以.service、.target、.socket等 unit 文件的形式存在或在线文档比任何博客都可靠。记录与复盘像开头说的准备一个笔记可以用vimmarkdown也可以用Joplin、Obsidian等工具。记录下每次解决复杂问题的完整上下文、排查思路、最终命令和根本原因。定期回顾你会发现很多问题的模式是相似的。理解原理而非死记步骤为什么kill -9有时是危险的因为进程没有机会清理资源。为什么修改了~/.bashrc需要source一下因为source是在当前shell进程中执行脚本而直接执行是在子shell中。多问几个“为什么”你对系统的理解会深刻得多。Linux的修行之路漫长而有趣每一个踩过的坑都是通往更深处理解的阶梯。这份“常见问题手册”只是一个开始真正的秘籍是你自己在无数次“救火”与探索中积累下来的那份独一无二的经验。保持好奇保持耐心命令行终将成为你手中最得心应手的武器。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进