
1. 凌晨两点四十七分九台机器同时失联手机震动起来的时候我正睡得迷迷糊糊。抓过手机一看监控平台的告警推送像开闸一样往外冒——服务器离线HTTP探测失败数据库无法连接一条接一条全部来自生产环境。我揉了揉眼睛数了数坏消息足足覆盖了九台服务器时间点几乎都落在凌晨2:47前后。老实说那几分钟我确实有点懵。做运维这些年单台虚拟机宕机见过不少但九台虚拟机在同一个时间窗口集体罢工绝对不是巧合。这里先交代一下背景这九台服务器无一例外全是虚拟机分布在三台物理宿主机上承载着公司的ERP、文件共享、OA、报表等核心业务。换句话说白天的业务全靠这些虚拟化出来的看不见的服务器在撑着它们一旦集体撂挑子第二天早上所有人都得瞪眼。1.1 告警刷屏的那一刻我先干了三件事遇到群体性故障最忌讳的就是一慌就到处乱点。我按习惯先做三件事第一确认告警范围。把告警列表完整拉出来逐条看是哪些IP、哪些服务、用的什么方式探活。这一步看的是面用来判断故障是局部还是全局。当时的结果很明确九台虚拟机跨三台宿主机全部异常。第二判断网络层是否正常。去监控机上直接Ping几个故障IP再看网关和核心交换机的状态。如果Ping得通说明二层三层链路没问题问题大概率出在主机或存储层面。第三远程登录宿主机。用SSH连上去看CPU、内存、存储挂载情况确认物理宿主机本身没有宕机。这三件事做完我基本能确定一个方向宿主机没死网络也没断但虚拟机的心脏——磁盘I/O——大概率出了大问题。1.2 9台服务器背后的物理家底很多人会把服务器理解成一堆实体铁疙瘩但在虚拟化环境里你看到的服务器列表本质上只是宿主机上的一组文件。我这边的情况是这样的三台ESXi宿主机每台双路CPU、256GB内存、双口万兆网卡后端接了一台双控制器的中端存储阵列通过iSCSI协议走万兆交换机把存储以LUN的形式挂给宿主机。九台虚拟机全部存放在共享存储的数据存储Datastore上。用生活化的打比方来说三台宿主机是房子共享存储是地基和仓库九台虚拟机是住在房子里的租户。虚拟机的文件、快照、日志、交换文件都存放在共享存储里。一旦存储这块地基出问题三台宿主机上的所有租户都会跟着遭殃。这也是很多运维新手容易忽略的一点虚拟机之间看似相互独立实际上共享的底层资源决定了它们之间存在天然的连坐关系。1.3 为什么虚拟服务器挂掉反而比物理机更让人头皮发麻物理机挂了那台机器上的业务中断影响范围是明确的。但虚拟服务器只是一个文件形态它罢工的形式更复杂有的是进程还活着、但磁盘I/O卡死有的是VM直接被强制Power Off有的是宿主机上冒出诡异的锁文件、挂载点异常。更麻烦的是故障表现各不相同根因却往往只有一个还藏得很深。这几年服务器虚拟化普及以后单台物理机的故障被大幅度消化了但公共层故障的杀伤力反而更集中。虚拟化的故障排查比物理机更需要抽象思维——忽略掉花花绿绿的监控界面紧盯CPU、内存、存储、网络这四样最底层的东西。这九台虚拟机集体失联的案例恰好就是一次抽象思维的实战检验。2. 排查纪实从宿主机到存储一步步逼近真相2.1 第一站宿主机还活着吗凌晨那一刻我第一件事就是登录三台ESXi宿主机。SSH连上去命令敲下去响应非常及时说明宿主机操作系统层面是通的。再看/vmfs/volumes目录问题就来了多个数据存储路径底下空空如也挂载点看不到设备状态异常。执行esxcli storage core device list看到的iSCSI磁盘设备状态不正常设备名对应的NAANetwork Address Authority网络地址标识还在但路径状态已经变成dead。再看esxcli storage core adapter listiSCSI适配器显示会话已断。这个现象几乎可以直接断定宿主机和存储阵列之间的链路出了问题。要么是万兆交换机端口down掉要么是存储阵列自身故障要么是iSCSI会话被异常终止。当时的排查顺序是我临时定的先查交换机再看存储阵列管理界面最后回头查宿主机日志。原因是交换机排查最快——登录核心交换机查看与存储阵列连接的两个万兆端口端口状态正常没有flap迹象光模块功率也正常。也就是说问题不在网络链路上。2.2 多路径的备份变成了摆设iSCSI存储通常会配置多路径MPIO也就是宿主机通过两个不同的物理路径去访问同一个LUN。正常情况下一条路径断了另一条还能顶上这正是双控制器存储号称高可用的底气所在。我查看esxcli storage core path list时傻眼了所有LUN的所有路径全部显示dead。交换机没问题光纤没问题那问题只能出在存储阵列本身了。可存储阵列是双控制器的怎么可能两个控制器同时消失这时候我登录存储阵列的管理界面看到的信息让人心里一沉控制器A显示状态异常控制器B显示正在启动后台日志里密密麻麻全是某个固件模块的报错。再往前翻发现大约在凌晨2:45控制器A在磁盘巡检过程中触发了一个固件缺陷导致控制器内部进程异常随即发生了一次控制器切换但切换动作没有干净利落地完成控制器B接管过程中也出现了同样的固件错误两个控制器在短短两分钟内双双重启。这才是假高可用的典型表现硬件上确实有冗余控制器也确实有两个但固件里的同一个缺陷会让冗余变成摆设——一个挂了另一个也被同一个毛病拖下水。2.3 共同点浮出水面它们都在同一块共享存储上回头看那九台虚拟机它们的共同点比我们想象的更简单所有虚拟磁盘文件都存在那两个数据存储上而这两个数据存储恰好都建在同一个存储池里。存储阵列两个控制器一重启LUN暂时从宿主机侧消失iSCSI会话全部中断九台虚拟机瞬间全部失联。其中六台虚拟机表现为主机无法访问、业务无响应另外三台因为配置了SCSI设备重置超时策略直接触发了虚拟机层面的强制重启或异常关机。这里也提醒大家一个细节当存储LUN消失时ESXi并不总是立刻把虚拟机杀掉有些虚拟机可能卡在一个假活状态——界面看起来是开机实际上内部已经完全死掉。这也是我当时没有立刻把九台虚拟机全部强制重启的原因。先恢复存储让宿主机的I/O重新可用是成本最低、风险最小的第一步。2.4 根因落定双控制器存储的假高可用事后我通过存储厂家的官方渠道确认这次事件属于一个已知固件缺陷在特定固件版本下后台RAID一致性巡检与控制器间心跳通信存在竞争条件Race Condition会触发控制器的异常重启。厂家给出的临时规避方案是关闭一致性巡检的自动执行把巡检时间挪到业务低峰期并人工监控长期方案是升级固件到修复版本。这个结果让我感触很深。存储阵列、服务器虚拟化平台、网络设备这些层面全都号称有冗余设计但冗余是分层的控制器冗余、路径冗余、主机冗余、机房冗余每一层都独立测试通过不等于合在一起就绝对高可用。固件层面的同一个缺陷能把硬件冗余瞬间打成一张白纸。3. 原理拆解虚拟化环境为什么容易连坐3.1 单一故障域一损俱损虚拟化提高了资源利用率也把风险收敛到了一个公共故障域。所谓故障域就是哪一个组件坏了会连带多少东西一起坏的边界范围。物理服务器时代一台机器坏掉故障域可能就是一台虚拟化时代一台宿主机上可能跑二三十台虚拟机如果宿主机本身故障故障域就扩大到二三十台。而存储是整个虚拟化环境里最大的公共故障域。九台虚拟机可以分散在三台宿主机上但只要它们的磁盘文件都落在同一个存储池里这个存储池就是它们共同的命门。这不是说不能用共享存储而是在规划时就必须清醒地认识到越是集中的共享组件越要有对应的检测、容错和应急方案。3.2 iSCSI路径、心跳与脑裂iSCSI的工作机制可以理解成以网络为线缆的硬盘连线。宿主机通过iSCSI协议把远端的LUN当作本地磁盘来用。为了让链路可靠通常会配置多路径让主机和存储之间有多条路可以走。但在双控制器的配置下多路径的前提是控制器能够正常协作谁负责这个LUN谁负责另一个LUN监听端口是什么状态心跳是否正常。如果控制器之间心跳紊乱就可能出现脑裂——两个控制器都认为自己应该接管某个LUN或者都认为对方已经退出结果谁也没能对外正常提供服务。这次的固件缺陷恰好把存储阵列的内部协作机制打乱了控制器A重启时B的接管没有成功随后B自己也触发同样错误重启两条路径自然全部挂掉。脑裂和双双击穿看着很像实际原理都是冗余组件的协同逻辑出了问题。3.3 HA不是保险柜vMotion也救不了存储故障很多团队对虚拟化平台有过度信任倾向开了vSphere HA就觉得万事大吉有vMotion就觉得可以随时迁移。但HA和vMotion都有一个共同前提——共享存储必须可用。HA监控的是宿主机的心跳宿主机以为存储正常时不会触发任何动作vMotion迁移的是虚拟机内存状态它同样依赖源和目标的存储路径。换句话说如果故障出在存储层HA不一定能感知vMotion根本无处可迁。当所有LUN消失时HA甚至可能出现误判某些宿主机可能会因为虚拟机的响应超时而认定对方故障进一步触发集群层面的保护性动作。所以运维人员必须清楚虚拟化平台的高可用能力是分场景的它对主机故障有效对存储故障部分有效甚至无效。3.4 控制面与数据面宿主机活着不等于业务活着这次排查中宿主机一直能ping通、能SSH登录但上面的虚拟机业务全线崩盘。这就是虚拟化里典型的控制面正常、数据面异常ESXi的管理服务控制面运行在宿主机的内存和本地盘上不需要存储阵列也能工作但虚拟机的磁盘I/O数据面依赖后端的共享存储存储一断数据面就塌了。理解这个区别很重要。排障时不要看到宿主机能登录就判定平台没问题要先确认存储是否挂载、I/O是否可用。我见过不少同行在宿主机上反复重启管理服务完全没意识到问题其实出在后端存储阵列上。4. 恢复实录九台虚拟机怎么一台台拉回来4.1 恢复前先想清楚的三件事存储阵列的两个控制器在凌晨2:52左右陆续完成重启管理界面恢复正常LUN重新在线。那一刻我当然想赶紧把所有虚拟机立刻开机但还是强迫自己先想清楚三件事第一是否确认所有LUN的状态稳定。控制器刚重启完存储后台还有自检、缓存回写等动作如果马上把大量虚拟机的I/O压上去容易引发二次故障。我当时先等待了大约10分钟再逐块确认LUN状态、重建iSCSI会话。第二是否确认宿主机上的存储链路全部回来。我逐台宿主机执行了esxcli storage core path list看到设备路径从dead恢复到active并且确认多路径的路径数正确后才继续下一步。第三是否有虚拟机处于假活状态。前面说了有些虚拟机看起来是开机状态实际内部I/O已经卡死。这类虚拟机不需要手工开机但需要在业务层面重启其中的应用服务或者干脆冷启动虚拟机一次把内部状态彻底重置。4.2 存储回归后的启动顺序存储恢复后我没有一次性把九台虚拟机全部启动。这里涉及到业务依赖关系数据库服务不可用时先启动应用和Web服务没有任何意义它们起来后连不上数据库反而会报错、写脏日志、产生混乱的临时数据。我当时的启动顺序是这样的批次虚拟机启动理由第一批ERP数据库、OA数据库所有应用的数据底座必须最先恢复第二批文件服务器、中间件/应用服务器依赖数据库启动后的连接文件服务独立可先上第三批Web前端、报表服务面向用户的服务放在最后等后端稳定第四批CI构建、监控代理等辅助系统低优先级避免抢占I/O资源每启动一台虚拟机我都先确认系统层面启动完毕、关键服务端口正常监听再启动下一台。当时三台宿主机存储刚恢复后端还在做RAID降级数据的同步I/O带宽有限分批启动能明显降低整体压力。4.3 数据一致性检查与业务验证九台虚拟机全部起来之后不等于事故处理结束。接下来是更重要的数据一致性检查。存储控制器异常重启时最怕的是缓存数据没有完整回写导致文件系统或数据库层面出现逻辑损坏。我的处理办法是分层检查先看虚拟机的系统盘是否能正常挂载、文件系统有无报错再看数据库能否正常启动并在启动后执行一次完整性校验最后让业务方做一次关键功能的冒烟测试。这里要说一个实操经验异常的虚拟机冷启动后尽量先看宿主机的事件日志确认虚拟机的磁盘没有出现SCSI reservation conflict或文件锁异常再进入虚拟机内部操作。因为虚拟化层的数据锁机制有时会在故障恢复后残留直接操作系统层面操作反而会遇到莫名其妙的I/O错误。这一次运气不错因为存储控制器在重启前完成了缓存数据的保护性落盘九台虚拟机里没有出现文件系统级别的损坏。但即便如此我仍然手工触发了一次备份任务因为这些备份才是真正的后悔药。4.4 恢复过程中的几个关键命令与操作把这次事故中用到的、能直接照抄的操作命令整理在这里方便也好排障也好都能用查看存储设备列表esxcli storage core device list查看设备路径状态esxcli storage core path list查看iSCSI适配器会话esxcli storage core adapter list重新扫描存储esxcli storage core adapter rescan --all挂载数据存储esxcli storage filesystem list查看虚拟机状态vim-cmd vmsvc/getallvms和vim-cmd vmsvc/power.getstate vmid如果iSCSI会话没有自动恢复可以手动执行esxcli storage core adapter rescan --all让宿主机重新扫描存储适配器并恢复会话。这个操作不会影响已经运行的虚拟机可以放心执行。注意在没有确认LUN和路径恢复之前不要对虚拟机执行强制关机或移除注册。存储恢复后虚拟机可能自动回到可用状态强行操作反而可能造成额外风险。5. 复盘笔记常见问题速查与避坑技巧5.1 本次事故时间线02:45存储阵列控制器A在巡检中触发固件缺陷异常重启02:47控制器B接管失败并出现相同错误存储阵列全面异常02:47-02:52九台虚拟机因LUN不可用而集体失联其中三台触发异常关机02:52两个控制器陆续完成重启LUN恢复在线03:00-03:10确认宿主机多路径恢复逐批启动虚拟机03:40九台虚拟机全部恢复业务冒烟测试通过第二天与存储厂家确认根因申请固件升级窗口整个事故从发生到业务恢复大约50分钟。说实话不算快但在存储控制器双双击穿的情况下这个结果已经可以接受。能在50分钟内把九台虚拟机全部拉回来的关键在于没有慌乱中反复重启而是先让存储和路径稳定再有条不紊地分批恢复。5.2 虚拟化环境集体罢工常见原因对照表常见原因典型表现排查入口应急动作共享存储LUN失联多台虚拟机同时无响应宿主机存储路径deadesxcli storage core path list先恢复存储链路再分批启动虚拟机数据存储空间满虚拟机I/O卡死服务无响应但管理界面正常查看Datastore容量与快照大小清理快照、扩容或迁移虚拟机宿主机批量故障同一宿主机上的虚拟机全部异常查看宿主机CPU、内存、日志重启宿主机优先找回虚拟机HA误触发集群内虚拟机被反复重启查看vCenter HA事件暂停HA自动动作手工控制恢复网络广播风暴/环路所有虚拟机网络极慢或不通检查交换机端口、CPU占用找出环路端口并阻断数据存储空间满是个特别常见又特别容易忽略的坑。虚拟机的快照文件会随着运行持续增大一旦数据存储被撑满所有落在上面的虚拟机都会开始卡死。我处理过几次类似事件现象和存储失联几乎一样但根因完全不用动存储阵列。平时一定要给数据存储预留至少20%的余量并设置快照大小的实时监控告警。5.3 排障时最好用的几个顺手工具除了esxcli这一套命令有条件的团队还可以准备以下工具vCenter的事件日志和告警定义所有虚拟机的异常事件都会集中记录排查时能省掉大量逐台登录的时间存储阵列的管理界面和告警邮件通知这次的根因最终就是在阵列日志里找到的带外管理BMC/iDRAC/ILO宿主机系统层面卡死时还能远程重启是最后一道保险监控平台的历史曲线用来回看故障前CPU、内存、I/O的变化趋势很多问题在爆发前其实有征兆工具不在多关键是故障发生时你能快速拉到哪一层的证据。我建议运维团队平时就把这些工具的访问账号、操作手册整理一份贴在内网知识库里真出了事才不会到处找密码。5.4 事后加固清单这次事故之后我做了几件事也建议所有虚拟化环境的管理者对照检查一下把存储阵列固件升级到修复版本并确认厂家已解决已知缺陷禁止后台一致性巡检在业务高峰期自动执行改为低峰期手动执行并监控给核心数据存储增加容量告警阈值设在80%和90%两级针对存储失联场景建立恢复演练计划每季度至少做一次模拟完善虚拟机启动依赖清单保证在集体故障恢复时有明确的开机顺序为三台宿主机和高危虚拟机配置独立的带外管理与远程电源控制我在实际运维中反复体会到事故后最重要的不是追责而是把故障模式变成制度。这次九台虚拟机集体罢工说到底是一次存储固件缺陷但它暴露出来的问题——对冗余的过度信任、监控项覆盖不全、恢复流程没有预案——才是真正需要长期改的。最后再分享一个小技巧建议在共享存储上单独划分一个小的数据存储专门用来存放宿主机的日志、脚本和应急工具。这样就算主存储阵列出了事你的排障工具和日志还在不会沦落到连诊断信息都取不出来的尴尬境地。这个细节在关键时刻真的能救命。