
凌晨1:47我手机上的监控报警像连环夺命call一样开始振动。业务群里的消息一瞬间就刷了屏——“9台服务器全部失联”。我揉着眼睛坐起来第一反应是觉得哪里搞错了晚上巡检的时候明明一切正常怎么一下子就全没了更让我头皮发麻的是这9台服务器并不是物理机而是一套虚拟化平台上跑着的9台虚拟机。也就是说就算某台物理宿主机出问题最多只影响在上面运行的几台虚机可现在9台虚机同时“罢工”还跨越了多台宿主机这个故障面明显不对等。在虚拟化环境里一台虚机失联是家常便饭但9台集体消失绝对是大事。先把结论放在前面这次惊魂不是因为哪台物理服务器彻底坏了而是虚拟化架构里一个非常容易被忽视的共享环节出了问题。服务器虽然是虚拟的但业务中断的冲击却是实实在在的整个排查过程堪称一次心脏骤停又复苏的体验。1. 故障现场9台虚拟服务器集体“失联”意味着什么1.1 事故初发不是一台而是一个“面”故事发生的环境是一家公司内部的业务系统虚拟化集群。整个平台由3台物理宿主机组成上面一共运行着9台虚拟机分别对应数据库节点、应用服务节点、文件服务节点等。所有虚拟机都放置在同一个共享存储LUN上宿主机启用了高可用功能。那天夜里先是数据库节点CPU使用率告警紧接着是通讯中断然后应用虚拟机和文件虚拟机也相继失联。监控大屏从绿色变成黄色再到深红前后不过五六分钟。我第一时间进入网络层去Ping那几个业务IP结果一个都不通。当时我心里咯噔一下如果只有数据库虚机挂掉可能是数据库自身的问题但现在9台全挂跨越所有宿主机这一定不是某个虚拟机内部的崩溃而是“整个平台”出事了。需要立刻判断的是这个“整个平台”的范围到底有多大是物理宿主机全挂了还是共享存储、共享网络出了问题。1.2 第一步连线宿主机能通说明什么接到告警后我做的第一件事不是去看虚拟机而是先Ping三台物理宿主机的管理IP。结果非常关键3台宿主机全部能Ping通登录宿主机的管理界面也正常CPU、内存、物理网卡资源看起来都还健在。说明物理服务器硬件本身大概率没有断电、没有宕机机房网络也基本正常。但接下来登录虚拟化控制台时情况就开始诡异了虚拟机列表全部显示为已启动可打开控制台却无法看到操作系统界面虚拟机的网络也是完全不通。从平台层面看虚拟机的状态是“running”但实际上它们已经全面假死。这种“活着的尸体”最让人抓狂。因为我无法通过常规重启虚拟机来恢复甚至无法判断是系统卡死还是底层资源阻塞。1.3 为什么说“虚拟的”反而更可怕物理服务器宕机通常只是一个单点故障虚拟机的群体失联背后往往意味着底层架构中某个共享环节已经崩溃。假设只是某一台物理宿主机坏了那么它上面最多两到三台虚机会受影响另外两台宿主机上的虚机应该安然无恙。可这次9台虚机全部断掉问题已经跨越了宿主机边界故障域指向了所有宿主机的公共依赖。在虚拟化架构里最容易成为公共依赖的东西就是存储和网络。想象一下如果9个人住在3栋楼里每栋楼的自来水都来自同一个水厂那么水厂一旦停水所有楼里的人都会口渴。虚拟机也是一样虽然宿主机各自独立但只要它们共享同一块存储、同一条网络链路的汇聚点任何一方出问题都会变成整个集群的灾难。因此“虚拟的”这个词从来就不代表更安全反而意味着故障影响范围会被成倍放大。2. 拆解虚拟化故障哪些环节能同时干掉9台虚机2.1 虚拟机的“生命线”计算、存储、网络三条链一台虚拟机能不能正常运行依赖三条生命线计算资源、存储资源、网络资源。计算资源CPU和内存来自宿主机宿主机出了故障虚机自然跑不了。存储资源虚拟机的磁盘文件一般放在共享存储或本地存储上虚机启动、读写都需要持续访问磁盘。网络资源虚机的网卡通过虚拟交换机、上行链路、物理交换机连接到外部网络任何一个环节断开虚机都会“失联”。在标准高可用集群里计算资源会尽量分散在多台宿主机上物理网络也会做链路聚合和冗余。但存储往往是集中式的比如SAN、NAS或者超融合的分布式存储。集中式存储的优点是便于统一管理和高可用但缺点也很明显一旦存储整体出现性能劣化或者连接中断所有依赖它的虚拟机都会同时停止响应。这个特性决定了在“9台虚机集体罢工”这类故障中存储通常是最值得怀疑的头号目标。2.2 最可能的“群体罢工”原因清单根据我的经验能够一次性让多台虚拟机全部“消失”的原因其实不算特别多。我做了一张排查速查表列一下最常见的几类故障类别具体故障点影响范围出现的可能性共享存储故障存储阵列控制器降级、LUN丢失、光纤通道断开、存储网络丢包所有访问该存储的虚拟机全部假死或崩溃很高虚拟网络故障上行链路中断、VLAN配置错误、虚拟交换机异常所有虚拟机的网络中断但虚机本身进程还在中等宿主机集体故障机房断电、精密空调失效、宿主机强制关机所有宿主机及其上的虚机全部失联中等高可用“风暴”某个宿主机出现资源问题高可用组件反复重置虚拟机多台虚机反复重启、业务长时间中断中等资源超配宿主机内存爆掉、CPU等待过高导致所有虚机无响应同一宿主机上的虚机全挂如果集群负载均衡异常也可能扩大到整个集群中低对于这次事故宿主机能Ping通说明“宿主机集体故障”基本排除虚拟机全部假死而不是全部无网络进程所以虚拟网络故障可能性较低。那么剩下的最可疑对象自然就是共享存储。2.3 为什么物理机看起来正常虚机却全部“挂”了我在排查时发现一个很反直觉的现象打开宿主机管理界面CPU曲线平稳内存没有爆掉网络也正常。可虚拟机就是像被施了定身术一样无法响应。后来才想明白这是存储IO阻塞导致的虚拟机进入“不可中断睡眠”状态。在Linux系统里如果一个进程在等待磁盘IO完成它会处于D状态uninterruptible sleep此时进程无法响应任何信号包括kill指令。虚拟机操作系统的内核同样如此当它底层的虚拟磁盘不断等待存储返回IO结果而存储迟迟不给回应时整个虚拟机就卡死在中途。由于CPU还在运转、内存在工作、网络栈还保留着从平台层面看虚拟机的状态仍显示为“运行中”。但实际上它已经无法处理任何新的请求更不能响应外部的Ping和登录。这就是“假死”。它比真正死机更麻烦因为正常重启虚拟机的操作可能都无法执行或者执行了也没有效果——只要存储IO没有恢复虚拟机重启到一半依然会卡住。2.4 从“现象”到“根因”的缩小范围方法遇到这类群体失联我一般会先判断“控制面”和“数据面”谁是好的。控制面是指管理通道比如宿主机SSH、虚拟化平台的Web和API数据面是指业务网络和存储IO路径。这次宿主机管理通道完全正常说明控制面是好的。坏的是数据面也就是虚拟机业务网络和存储路径。接着再进一步拆虚拟机和虚拟机之间能不能通信如果所有虚机都假死它们之间的通信自然也是断的如果是单纯的网络故障虚机进程还活着理论上虚机之间的内网是可以通的。这次从宿主机进入虚拟机控制台都看到不到登录界面说明虚机内的系统根本跑不动问题不在网络而在资源阻塞。再来看存储把所有虚机的磁盘文件位置一拉发现9台虚机的磁盘文件全部位于同一个数据存储LUN上。到这里怀疑对象就非常集中了。剩下要做的事情就是直接去存储系统里找病因。3. 实操复盘从告警到业务恢复的完整过程3.1 关键动作保留现场先别急着重启接警之后我最大的冲动是赶紧把虚拟机关机再开机。但我强行忍住了因为在存储故障没有恢复的情况下强制重启虚拟机只会让虚拟机进入“启动—卡死—再启动—再卡死”的死循环还有可能导致文件系统元数据损坏把原本只需要恢复存储的小事故变成需要从备份中恢复的大灾难。保留现场、采集证据永远是第一优先级。我先要求值班同事截图保存所有告警记录、事件详情、业务影响清单同时确认故障发生前是否有过任何变更操作。然后开始收集虚拟化平台的事件日志、宿主机的系统日志、存储侧的状态和日志。只有把时间轴对齐了才能判断某个事件是“因”还是“果”。3.2 检查宿主机资源水位与虚拟机状态登录每台宿主机后我依次执行了几个基础检查命令。先看负载和内存使用uptime、free -h和vmstat 1发现整体负载并不算高内存也没有耗尽。但再往后看就发现问题了所有宿主机的磁盘IO等待时间%wa都高得离谱有的甚至超过90%。这就说明宿主机本身并没有资源枯竭而是所有的磁盘读写请求都在堆积。为了看得更细我用iostat -x 1查看了每块存储设备的服务时间结果发现一组设备的svctm和await数值都呈现出极端状态平均IO等待时间涨到了几十秒。这个现象进一步印证了存储侧出问题。对于KVM环境我还会用virsh list --all查看虚拟机状态再用virsh dominfo看每个虚机的状态和配置。虽然列表里都写着running但配合系统日志里的block I/O超时报错基本可以确定所有虚机都在等待存储IO。3.3 深挖共享存储找到“共同敌人”宿主机检查完毕我把目光放到存储系统。登录存储的管理界面第一眼看到的景象就让我明白大事不妙承载这枚LUN的存储池处于“降级”状态两个控制器中有一个已经离线另一个控制器的缓存因为电池异常被强制停用导致读写性能直线下降。再看存储网络的接口统计发现其中一条主机链路对应的端口上出现了大量CRC校验错误和链路重置记录。到这里根因已经很清楚了。一波故障链路是这样的存储控制器离线导致所有IO请求都压到剩余控制器上而剩余控制器的缓存被停用只能以极低的性能处理写请求同时光纤链路又存在硬件故障反复触发路径重置。三个问题叠加在一起存储系统面对三个宿主机发来的密集IO请求彻底崩溃了。数据存储的IO请求全部卡死于是9台虚拟机一起进入了假死状态。3.4 恢复操作切存储链路观察IO恢复确认问题出在存储端口和控制器之后我没有立刻重启存储阵列——因为重启冷存储手段对于在线业务来说太冒险万一起不来就是真正的灾难。我的方案是先把故障端口以及离线的控制器隔离掉强制所有IO走剩下的健康路径看看上层能不能自动切过来。虚拟化平台通常都支持存储多路径功能例如使用原生多路径或者第三方路径选路插件。当存储侧故障端口被隔离后宿主机上的多路径软件会重新探测路径并将IO切换到备用路径。切换期间虚拟机仍然处于卡死状态我当时心里紧张得不行。大约过了几十秒宿主机的存储IO日志里开始出现“路径恢复”记录随后虚拟机控制台终于弹出了登录界面。我心里的大石头瞬间落地。之后我逐台恢复验证。先登录数据库虚机查询数据库是否正常启动再启动依赖它的应用服务最后验证外部访问是否恢复。整个过程从发现故障到完全恢复大约用了不到40分钟。这个时间看起来不长但对当时的我来说每一秒都像一年。3.5 用到的命令与排查工具清单这里把我本次事故中用到的核心命令整理一下方便其他同学遇到类似现场时直接参考。不同虚拟化平台的命令有差异但排查逻辑是通用的。# 查看系统负载和CPU/内存/IO等待 uptime vmstat 1 free -h # 查看磁盘IO状态重点看await和svctm iostat -x 1 # 查看虚拟机列表和状态KVM环境 virsh list --all virsh dominfo 虚机名 # 查看宿主机内核日志搜集存储IO错误 dmesg -T | tail -n 200 tail -f /var/log/messages在VMware vSphere环境里类似的命令是esxtop、esxcli storage core path list以及vCenter里的“存储状态”界面。重点关注的指标包括device latency、total latency、queue latency和路径状态。这些指标能帮你快速区分“存储有问题”还是“宿主机有问题”。注意有些平台自带的图形界面会掩盖底层细节。比如虚机状态显示为正常但实际存储延迟已经高得失控。命令行工具反而更直接。4. 事后反思把惊魂变成经验4.1 根因复盘为什么一个小模块故障能牵动9台虚机这次事故最值得反思的点不是“存储坏了”而是“为什么只坏了一个端口模块就导致全部虚机停摆”。复盘时发现这台存储阵列虽然设计上有冗余控制器但我们在配置虚拟化主机的存储路径时没有严格按照“跨控制器、跨链路”的原则。3台宿主机连接存储虽然表面上走了多条光纤但实际启动的IO路径都汇聚到了同一个离线控制器上。当这个控制器倒下之后所有路径同时不可用冗余完全没有发挥作用。这就像给汽车装了备胎但备胎和主胎一起被钉子扎穿等于没装。单纯“有冗余”不够必须验证“真冗余”——即每条链路都要经过不同的控制器、不同的交换机、不同的物理端口。否则看起来是双活的架构实际上还是单点。4.2 监控盲区我们漏掉了什么事故发生后我去翻监控平台的历史数据发现存储系统其实早就有异常信号存储控制器的缓存电池告警已经存在了两天只是这个告警级别被设置为“警告”没有触发群消息。而存储IO延迟在故障发生前几个小时也出现过一次短时飙升但因为持续时间不超过几分钟监控策略没有把它判定为告警事件也就没有通知到人。虚拟化平台的监控里我们只关注了虚机的CPU、内存、磁盘空间、网络丢包这类常规指标恰恰没有针对存储IO延迟、存储控制器状态、链路CRC错误这些底层健康指标设置基线。如果当时把这些指标纳入告警至少能在业务中断前半小时发现存储已经严重不稳定从而有机会提前切换路径或者维护窗口。4.3 架构优化与流程整改这次惊魂之后我牵头做了几项整改目前每一条都在后续的生产环境里发挥了作用。存储路径重新规划把所有宿主机的存储路径全部打散确保每个LUN都能通过两个控制器、两条独立光纤链路访问并且定期验证多路径切换能力。数据存储分散部署不再把所有鸡蛋放在同一个篮子里。原本9台虚机集中在一个LUN现在按照业务重要性拆分成两个数据存储跨存储配置HA和vMOTION降低单存储故障的影响半径。监控补盲新增存储控制器状态、存储网络丢包和CRC错误、LUN延迟和IO队列长度等监控项对存储的“警告”级告警重新评估升级条件不再让低级告警淹没了真正的风险。故障演练常态化每季度做一次存储链路切换演练让团队所有人都熟悉“拔光纤”后的现象和恢复流程。演练虽然不是真正的故障但能极大地提高战时反应速度。4.4 常见问题速查表像“群体罢工”这样的场景怎么快速定位最后把最常见的几种群体失联场景和对应的排查方向整理成速查表。个人经验这比背诵命令更实用。故障现象初步判断最先要做的操作所有虚拟机失联宿主机也无法Ping通物理层故障断电、温度过高、宿主机集体宕机联系机房查看硬件状态检查电源和温度告警所有虚拟机失联宿主机能Ping通存储IO等待极高共享存储链路或阵列故障登录存储管理界面查看控制器状态、链路错误、LUN健康状态多个虚拟机假死宿主机本身IO正常虚拟机内部系统或驱动问题尝试通过控制台进入虚拟机的单用户模式检查系统日志虚拟机反复重启但一直起不来高可用组件反复触发重启或文件系统损坏先暂停HA重启动作检查存储和文件系统必要时挂载快照只有部分虚拟机失联且它们都在同一个LUN上该LUN所在存储池或数据存储异常检查该LUN的状态尝试在线迁移虚拟机到其他正常存储这次事故的教训我一直和后来带的新人反复强调不要把“物理服务器正常”当成“虚拟化平台正常”也不要只看虚拟机层面多往下看一层看共享存储、看多路径、看控制器。服务器虽然是虚拟的但它依赖的物理设备、链路和配置每一环都是实实在在的。那次从凌晨干到天亮之后我给自己定了一条规矩任何涉及存储链路、存储控制器变更的操作必须提前做多路径切换演练并且准备好回滚方案。还有每次排查重大故障我都会把当时的截图、日志和命令记录保存到一个固定的复盘目录里沉淀成团队的故障案例库。惊魂不白经历把它变成流程里的一条“红线”以后每一个深夜才能睡得踏实。