前两天收到一条监控告警凌晨 2 点多某个业务虚拟机突然失联。到现场发现虚拟机关机了不是重启也不是被迁移。这种“故障关机”在虚拟化运维里属于高频事件但每次处理起来都有点折磨人——因为同样的现象背后可能藏着五六种完全不同的原因Guest OS 自己崩溃、ESXi 异常中止虚拟机、宿主机硬件告警触发断电、甚至存储链路断掉造成的假死。我处理完这套 ESXi 虚拟机故障关机后把从接警到根因定位、恢复、加固的整个过程完整复盘了一遍。这篇记录适合所有维护 ESXi 环境的朋友无论你是单机还是集群都可以按这个思路逐层排查。1. 故障现象与初始定位1.1 接到告警后的第一反应凌晨的告警通常不是一条而是一串。当时监控系统弹出的是虚拟机网络心跳丢失紧接着业务监控也报了站点无法访问。我习惯先把所有告警时间点拉出来对一下确认是同一时刻触发还是先后扩散。如果是同一时刻多半是虚拟化层或主机层出了事如果是先后扩散反而可能是业务进程自己挂了网络心跳只是最终表现。登录 vCenter 看这台虚拟机电源状态显示“已关闭”但事件记录里没有任何“关机”操作者也没有计划内关机任务。这个状态很重要说明不是管理员点过按钮也不是 vCenter 发过 guest shutdown 命令。那么方向就明确多了要么是 Guest OS 内部自己关了机要么是后端的虚拟化层出了岔子。先别急着开机。我习惯先做三件事确认宿主机的在线状态和其他虚拟机是否正常确认这台虚拟机在 vCenter 里有没有异常事件之前的“前序告警”截图保存当前 vCenter 界面和事件时间线。截图的习惯是从一次失败教训里养成的。很早之前遇到类似问题看完事件之后直接重启虚拟机结果后续追查根因时发现事件时间线被新状态冲掉了一部分。现在不管多急先保留现场记录再动手恢复。1.2 先把影响范围划清楚在处理故障的时候最怕的是只盯着那一台“失联虚拟机”忘了看看它周围的环境。影响范围决定了下一步的排查优先级。这台失联虚拟机所在主机上还跑着另外四五台虚拟机。我第一件事就是确认同主机的其他虚拟机是否还能正常访问。如果能说明宿主机没有整体宕机问题很可能局限在这台虚拟机的 Guest OS 或虚拟设备层。如果不能那就要优先考虑宿主机掉电、内核崩溃、存储链路中断这些大范围因素。确认过程中我记录了几个关键点同主机其他虚拟机 ping 测试全部正常业务响应没有异常vCenter 里主机显示为“已连接”硬件健康状态没有红色告警共享存储的其他虚拟机都能正常读写存储路径暂时没有异常。这一步做完基本可以把“宿主机整体故障”这个最严重的分支排除掉。剩下的重点集中在这台虚拟机的 Guest OS 和 ESXi 对这台虚拟机执行了什么操作。1.3 理解环境差异集群、单机、HA 配置不同的环境结构处理思路差别很大。我这次维护的是一个三节点 ESXi 集群启用了 vSphere HA虚拟机放在共享存储上。在这种结构下如果宿主机真的宕机HA 会自动把虚拟机在其他节点拉起。可实际情况往往没那么理想HA 触发有延迟虚拟机被拉起后可能还会遇到磁盘锁冲突。如果你是单机 ESXi没有 vCenter、没有 HA处理思路又不一样。单机环境下主机一挂所有虚拟机全部停摆恢复时只能先修主机再逐台开虚拟机。这时候“确认影响范围”可以直接简化成“整套虚拟化环境是否在线”。还有一点值得注意很多中小环境虽然搭了集群却共享存储和高可用策略配置得比较随意。之前我见过有人把虚拟机放在本地磁盘上却开着 HA主机一挂虚拟机根本没法在其他节点启动HA 触发了也只是空转。这个问题不在本次故障范围内但排查时顺手看一眼总没坏处。2. 拆解排查先分清“Guest关机”还是“Host宕机”2.1 vCenter 事件时间线是最好的第一证据定位故障类型最直接的工具是 vCenter 的“事件和时间”。我进入 vCenter找到这台虚拟机把事件筛选到凌晨 2:00 到 2:30 这个时间段然后逐条看事件序列。干净的事件记录大致会长这样时间事件操作者02:14:05VmCreated系统02:14:30Virtual machine is powered off未知02:14:31VmStopped系统注意这里没有“Power off”操作者没有 vCenter 用户触发的记录。事件类型里如果显示的是“Virtual machine is powered off”说明虚拟机确实经历了关机动作而不是直接从 vCenter 列表里消失。如果出现的是从 vCenter 移除或注册丢失那多半是主机和 vCenter 之间的心跳断了这种情况更吓人但本质不同。事件记录的粒度有限它只能告诉你“发生了什么”不能告诉你“为什么发生”。所以看完事件之后必须去日志里找原因。但事件的好处是给出了精确时间点后面所有日志搜索都可以以这个时间点为锚。2.2 用 esxcli 和 uptime 确认宿主机状态确认了虚拟机关机之后下一步是用 SSH 登录 ESXi 宿主机确认主机自己是否重启过。这一步能省不少时间因为如果宿主机 uptime 是从凌晨某个时间点重新开始计数的说明这台主机经历了重启或掉电那虚拟机被关闭就是连带结果。登录后先跑几个最基础的命令uptime esxcli system version get esxcli hardware platform getuptime的输出会显示当前时间和开机持续时长。如果宿主机已经连续运行了几十天说明凌晨并没有发生主机重启。那次排查中主机 uptime 显示连续运行超过一个月当场排除宿主机重启。接下来再看系统事件和硬件告警esxcli system syslog log calc esxcli hardware ipmi sdr listipmi sdr list这条命令能拉出传感器数据记录包括电源、风扇、温度、电压等当前状态和阈值。如果主机晚上出现过温度过高或者风扇异常这里往往能看到痕迹。不过要注意很多服务器的 IPMI 传感器只有在故障期间才记录告警事后看可能已经恢复正常所以如果带了外管理口最好也去那边翻一下硬件事件日志。2.3 “故障关机”的几种可能表现根据现象不同“故障关机”可以分为几类我在排查时会先做一次分类Guest OS 内部崩溃或主动关机虚拟机的电源状态变为“已关闭”但宿主机无异常ESXi 因为存储路径失联、CPU 超分配等触发 VM 停止虚拟机会有“VM stopped”事件宿主机掉电或 vmkernel 崩溃同主机上的所有虚拟机会同时断电vCenter 里面宿主机会短暂失联内存机器检查MCE或 NMI 中断导致宿主内核 panic表现为整个主机的所有服务瞬间消失。如果只有单台虚拟机关机宿主机在线、其他虚拟机正常那大概率是 Guest OS 或虚拟设备级问题。如果整个宿主机带虚拟化一起不可用那就要按主机故障处理。分类明确后排查路径就清晰了。3. 关键证据从日志里找到“临终信息”3.1 宿主机 vmkernel.log 里的关键线索ESXi 的问题排查绕不开/var/log/vmkernel.log。这是 vmkernel 的主日志记录了内存、存储、网络、驱动等整个内核系统的运行情况。虚拟机异常关机前这里通常会出现一些蛛丝马迹。登录宿主机之后以故障时间点为中心先做一次定向搜索grep -i error /var/log/vmkernel.log | grep 02:14 grep -i panic\|mce\|nmi /var/log/vmkernel.log | tail -n 50 tail -n 300 /var/log/vmkernel.logmce是 Machine Check Exception也就是硬件机器检查。nmi是非屏蔽中断。如果日志里出现了这两类关键字说明宿主机可能因为硬件问题触发了紧急中断严重时会造成整个宿主机重启或虚拟机被异常终止。那次排查中宿主机的 vmkernel.log 里并没有出现硬件相关的异常条目只看到一些常规的网络拓扑更新记录。这说明虚拟化内核层面没有主动干预这台虚拟机。日志搜索范围随后转向虚拟机自身的日志。3.2 从 vmware.log 看虚拟机的“临终遗言”每个虚拟机目录下都有一个vmware.log这是虚拟机的“黑匣子”。里面记录了虚拟机从启动到停止的完整生命周期包括虚拟硬件状态、Guest OS 的 ACPI 事件、虚拟机的电源操作等。查看方法vim-cmd vmsvc/getallvms # 拿到虚拟机在主机上的 ID 和 VMX 路径 cat /vmfs/volumes/数据存储路径/虚拟机目录/vmware.log | tail -n 100vmware.log的最后几十行非常关键。我那次排查时看到了类似这样的记录2025-...T02:14: ... VMware Tools: Guest has requested shutdown 2025-...T02:14: ... VM has been powered off这就很说明问题。Guest has requested shutdown意味着虚拟机内部的操作系统主动向虚拟硬件发出了 ACPI 关机信号而不是 ESXi 强制给它断电。换句话说虚拟机关机的“按钮”是 Guest OS 自己按下去的。如果看到的是2025-...T02:14: ... VM has been abruptly powered off 2025-...T02:14: ... Instead of normal shutdown, VM was powered off那就说明虚拟机是被外部强制断电的通常和 ESXi 层操作、宿主机故障或存储故障有关。还有一种情况是虚拟机日志里出现大量磁盘 IO 超时比如SCSI command timeout。这往往意味着存储链路出了问题虚拟机因为长时间无法访问磁盘而“假死”最终被虚拟化层判为无响应。遇到这类日志排查重点要转向存储网络和存储设备。3.3 存储链路排查别让“假关机”骗了你存储是虚拟化环境里最容易引发连锁故障的环节。ESXi 的存储栈非常敏感iSCSI 或 NFS 路径一旦抖动虚拟机的磁盘 IO 就会阻塞。一开始可能只是业务卡顿时间一长虚拟化层就有可能把虚拟机标记为无响应甚至触发 HA 重启。要排查存储链路我会按顺序做几件事登录 vCenter看存储和主机之间的路径健康状态从 ESXi 上用esxcli storage nmp path list查看多路径状态用esxcli storage core device list确认设备是否在线检查存储交换机或网络的端口信息和丢包情况。顺便说一下如果你维护的是 iSCSI 环境主机和存储之间的网络 VLAN 如果有调整很容易出现路径中断。ESXi 的默认存储超时时间比较保守但虚拟机会变成只读或 IO 阻塞。那次故障的日志里没有存储超时记录存储因素暂时排除。3.4 别忘了 Guest OS 内部日志很多 ESXi 排障的人容易陷入一个误区只在宿主机找原因不看虚拟机内部。实际上虚拟机内部日志能提供最直接的“死因”。这台虚拟机是 Linux 系统。我把它恢复开机之前先挂载了它的虚拟磁盘或者直接利用快照启动到救援模式把/var/log/messages、/var/log/syslog拷出来。如果虚拟机是 Windows就查系统事件日志重点看事件 ID 41意外关机以及 Kernel-Power 日志。结果发现虚拟机内在故障时间点附近有一条明显的 OOMOut of Memory记录紧接着内核触发 panic随后系统执行了 shutdown。这样整个链条就串起来了内存耗尽导致内核 panicGuest OS 主动关机ESXi 层的vmware.log记录了正常的关机流程。这个例子说明单看 ESXi 日志只会看到“虚拟机被正常关机”容易误判成“谁手动关机了”。只有深入到 Guest OS 内部才能找到真正触发关机的元凶。4. 主机层面故障的快速响应恢复方案4.1 第一步永远是保留现场证据如果确认不是虚拟机内部问题而是宿主机故障那处理方式完全不同。宿主机一旦出现整个节点宕机、所有虚拟机同时掉线的情况很多人的第一反应是赶紧重启主机。这个动作我会特别谨慎。主机如果真的发生了 vmkernel panic现场会在屏幕上留下紫色诊断界面。如果是物理机断电带外管理界面会留下电源告警。这些信息一旦在重启后就会丢失所以强制重启之前必须尽可能多地保留现场信息对物理主机屏幕或诊断界面拍照记录带外管理界面的 SEL 传感器日志在 vCenter 里截图所有虚拟机状态和主机告警把/var/log下关键日志文件复制到额外目录或远程存储。不要觉得这些是在浪费时间。我之前遇到过一台主机反复 PSOD第一次因为急着恢复业务什么都没留结果重启后硬件日志被覆盖排查只能靠猜。后来学聪明了每次强制重启前必留现场好几次都是靠这些现场记录直接定位到内存或 CPU 问题。4.2 单主机与 HA 集群的恢复顺序如果是 HA 集群宿主机故障后vSphere HA 会自动把虚拟机在集群内其他主机上重启。这时候要注意的并不是“如何开机”而是“如何看待自动重启后出现的新问题”。HA 自动重启可能遇到两种情况。一种是其他主机资源充足虚拟机顺利启动业务恢复得很快。另一种是虚拟机启动后报“磁盘锁”错误原因是原主机并没有彻底下线它的虚拟化进程残影还占着磁盘锁导致 HA 启动的新实例无法获取锁。这种情况下需要先在 vCenter 里确认原主机的代理是否真的失联必要时把原主机从集群中置为不可用再手动重启虚拟机。单主机环境没有这一层保护。恢复顺序我通常是这样确认硬件状态和 RAID 阵列状态启动主机进入 ESXi 管理界面先确认能否看到所有数据存储按业务优先级逐台手动开机虚拟机而不是一键全选开机每开一台虚拟机等系统起来再确认网络心跳和业务端口。第 3 步非常重要。如果一次性把几十台虚拟机同时开机刚恢复的主机可能因为瞬间的 CPU 内存峰值再次宕机那就变成二次事故了。按优先级分批次启动虽然慢但最稳。4.3 避免二次故障的注意点主机恢复后我一般还会额外观察一段时间避免只看到表面恢复就收工。首先看宿主机负载重点观察 CPU、内存、磁盘 IO 是否在合理范围。很多故障关机并不是凭空出现而是资源紧张积累的结果。虚拟机重启后如果宿主机内存和 CPU 再次被打满故障很可能会重复发生。其次看虚拟机的日志时间与宿主机日志时间是否对齐。ESXi 和 Guest OS 如果时间偏差太大排障时定位会非常痛苦因为事件时间线全对不上。我处理过一台机器Guest OS 时间比宿主机慢了十几分钟排查时差点把关联关系弄错。所以事后校时也是必做项。5. 根因定位与后续加固5.1 把根因链条完整串一遍回到那次故障本身最终的根因链条是这样的业务虚拟机上的应用内存在凌晨出现峰值Linux 触发 OOM Killer但内存压力仍然没有被释放内核在 02:14 左右触发 panicGuest OS 执行了 shutdown。ESXi 只是忠实记录了一次正常的虚拟机电源关闭事件虚拟机本身并没有遇到虚拟化层的问题。这类“Guest 自己关机”的故障严格来说不算 ESXi 故障关机但对外表现完全一样虚拟机不可用、业务中断。如果只看 vCenter 事件很容易被误导为“虚拟机被异常关闭”然后去查宿主机硬件查了一圈什么都查不到。所以把根因链条完整串一遍至少覆盖几个环节应用层有没有大查询、批量任务、内存泄漏操作系统层有没有 OOM、panic、关键服务异常虚拟化层虚拟机的配置、资源限制、工具状态硬件层内存错误、CPU 温度、电源、固件版本。只要这几个环节都过了一遍才算真正定位而不是“看起来恢复了”。5.2 把“故障关机”变成可监控、可预警的事件处理完问题之后接下来最重要的事情就是让同类问题不再静默发生。我在这个环境里做了几项加固供大家参考vCenter 告警里开启“虚拟机电源状态更改”告警一旦虚拟机意外关机监控平台能立即收到通知给 ESXi 配置远程 syslog把/var/log/vmkernel.log、vmware.log转发到日志服务器避免主机磁盘故障导致日志丢失为虚拟机的 Guest OS 部署 agent 或监控探针增加进程级心跳而不是只靠网络 ping对内存配置过小的虚拟机根据业务峰值重新评估内存和预留策略避免再次触发 OOM。监控不是越复杂越好。对资源有限的环境优先做两层一层是 vCenter 层的虚拟机电源状态告警另一层是业务端口或进程探活。这两层覆盖了绝大多数“故障关机”场景。5.3 准备一份故障关机处理 Runbook吃过一次亏之后我把处理流程整理成了固定文档每次排障都按它走。Runbook 不用写得多高端但要把命令和步骤写清楚至少包含影响范围确认清单日志查看的固定命令序列虚拟机关机后恢复的标准顺序需要走的升级流程和时间节点。下面这段命令序列是我在 Runbook 里最常用的一部分# 查看虚拟机列表和 ID vim-cmd vmsvc/getallvms # 查看虚拟机当前状态 vim-cmd vmsvc/get.summary vmId # 查看宿主机运行时长 uptime # 查看 vmkernel 日志中近期的 error/panic 记录 grep -i error\|panic\|mce\|nmi /var/log/vmkernel.log | tail -n 100 # 查看虚拟机的 vmware.log 最后 100 行 cat /vmfs/volumes/数据存储/虚拟机目录/vmware.log | tail -n 100 # 查看存储多路径和磁盘状态 esxcli storage nmp path list esxcli storage core device listRunbook 的价值不在于它有多全而在于它在半夜出事时能让你手不慌、心不乱。我之前在转文档时把很多“经验”写进去后来再看发现大部分故障都是按固定套路解决的。6. 最后想补充的几点经验故障关机这类问题处理多了之后会有一个感受最坑的不是故障本身而是“看起来恢复了”造成的麻痹。虚拟机重新开机业务恢复大家都会松了一口气。但如果没搞清楚原因下一次故障大概率还会来而且可能更严重。那次排查之后我没马上收工坚持把日志和监控补了一轮后来确实发现了两台内存预留不足的虚拟机提前调掉了隐患。另外一个小技巧在处理任何虚拟机故障关机时先给vmware.log和vmkernel.log做一个带时间戳的备份。这个动作不复杂但能让后面几天的分析从容很多。有些日志文件会被循环覆盖不及时备份等你想查的时候可能已经不存在了。最后想说的是虚拟化环境的排障本质上是在各种日志里拼图。vCenter 事件是一块宿主机日志是第二块虚拟机内部日志是第三块硬件日志是第四块。拼图拼得越快恢复就越快出现二次事故的概率也越低。希望这篇处理记录能帮大家少走一些弯路。