ESXi主机未响应排障:心跳链路分析与pktcap-uw抓包实操 ESXi 主机在管理界面里变成灰色的“Not Responding”那种感觉做过运维的人都懂虚拟机的业务可能还在跑但你不知道它下一秒会不会真的挂掉也不敢贸然重启。这个状态既不像“Disconnected”断开那样干脆也不像“Inaccessible”无法访问那样明确它悬在中间逼着你去验证一件事——到底是主机真的出问题了还是只是“心跳”没送过去。我要聊的就是这件事ESXi 主机 not responding未响应的成因分层、排查路径以及在 ESXi 上做抓包pktcap-uw、tcpdump-uw的具体手法。内容偏向一线排障适合手里管着几台到几十台 ESXi 主机、被“未响应”反复折腾过的朋友也适合刚接触虚拟化、还没弄明白心跳链路的同行。不讲空话都是从现场记录里扒出来的东西。1. 把“未响应”拆开看三种状态背后是三种故障1.1 Not Responding 与 Disconnected、Inaccessible 的差别很多人把这三个状态当成一回事实际差别很大判断错方向会浪费几小时。Disconnected断开通常是管理端主动断开的连接比如你手动断开、证书不匹配导致握手失败、管理端服务重启后没能重建会话主机本身大概率是活的只是“这个管理端不跟它讲话了”。Not Responding未响应的含义更偏“管理端连不上但也没有明确证据说主机死了”典型触发是管理代理进程响应超时、管理网络丢包、或者主机负载高到 443 端口的 TCP 会话无法在超时时间内完成握手。Inaccessible无法访问多见于集群环境主机被判定为隔离或 HA 代理通信失败往往伴随数据存储心跳异常。这三者的处置动作完全不同Disconnected 先去查证书和版本Not Responding 优先查管理网络的连通性和 hostd 进程Inaccessible 要先确认共享存储和集群心跳。我见过有人一看到灰色就重启管理代理结果主机业务正在做批量备份重启直接把备份任务打断了——查清状态含义比任何命令都重要。1.2 一台“未响应”的主机其实可能在正常跑业务这是最容易误判的地方。管理界面显示未响应只代表管理平面的通信出了问题不代表数据平面停了。虚拟机的网络转发由虚拟交换机承担跟 hostd 进程、跟管理 vmkernel 接口没有强依赖关系。所以第一反应不该是重启而是从另一个入口确认主机还活着带外管理口就是那个独立的管理网口/IPMI 类接口看电源和风扇状态、看物理交换机对应端口的指示灯、从同网段另一台机器 ping 管理地址、或者直接登录带外控制台。我个人的习惯是先做三件事顺序固定ping 管理 IP判断链路层和网络层通不通、ping 默认网关判断是不是本机路由或上游问题、从另一台同网段主机 telnet 管理 IP 的 443 和 902 端口判断 hostd 是否还活着。这三步两分钟内能出结果。如果 ping 通、443 不通基本锁定主机侧进程或防火墙如果 ping 不通但带外控制台能进那就是网络或网卡的问题可以直接往抓包方向走。提示不要在没有带外访问手段的情况下重启一台“未响应”的主机。你无法确认它是否正在写数据一次硬重启可能带来比故障本身更大的损失。2. 心跳链路逐层拆解为什么总是管理网络出问题2.1 从管理端到 hostd 的那条会话管理端和 ESXi 之间的“心跳”本质上是几条长期存在的 TCP 会话加上周期性的状态上报。管理端通过 443 端口与主机的 hostd 通信拉取配置、性能计数器、事件虚拟机的远程控制台走 902 端口集群环境里主机之间还有一层独立的心跳走管理网络同时共享存储上还有数据存储心跳文件做兜底。理解这个结构很关键管理网络一旦出现间歇性丢包最先表现异常的就是这些长连接。长连接的脆弱点在于握手和保活。TCP 会话在中间设备防火墙、负载均衡、NAT 设备上都有会话老化时间如果空闲一段时间没有流量中间设备把会话表项清掉而两端还认为连接存在下一次发包就会石沉大海直到上层超时才报“未响应”。这类问题有个很典型的特征规律性每隔固定时长比如 5 分钟、15 分钟出现一次未响应过一会儿自己恢复。看到这种周期性症状先怀疑中间设备的老化策略而不是主机硬件。2.2 五个高频故障域从光模块一路查到 ARP 表我把实际遇到过的原因归成五层从上往下查比乱猜高效得多。层级典型现象优先验证手段物理层端口 up/down 抖动、错包计数上涨交换机端口计数器、esxcli network nic stats get -n vmnicX链路层双工/速率协商不一致、聚合配置不匹配两端协商结果对比、LACP 状态网络层跨网段不通、MTU 不一致、ARP 异常vmkping、esxcli network ip neighbor list传输层443/902 端口被拦、会话老化端口探测、抓包看 SYN 与重传应用层hostd 卡死、证书过期、时间漂移/var/log/hostd.log、时间同步状态物理层的坑最隐蔽。有一次一台主机每两天未响应一次交换机端口计数器里的 CRC 错包在缓慢增长速率不高容易被忽略。换了一根跳线后再没复现。错包计数只要在涨就不是“正常波动”别被“占比很小”说服。链路层的经典问题是聚合配置主机侧做了基于 IP 哈希的静态聚合交换机侧配了 LACP 动态聚合两边都不报错但流量分布异常某些会话直接丢。这种故障抓包看特别明显——同一个源目对的包出现大量乱序和重传。网络层的代表是 MTU。管理网络一般 1500vMotion 或存储网络可能配了 9000如果这两类流量共用一块物理网卡或者经过同一条上行链路而中间某台交换机端口没放大 MTU就会出现“小包通、大包丢”的诡异现象表现为管理端偶尔失联尤其在做大批量操作时。3. 抓包之前必须做的信息采集3.1 控制台里先跑完这几条命令抓包是最后手段不是第一步。上机后我固定跑这几条把现场状态先固定下来避免重启或改动后证据丢失。# 1. 管理接口与路由 esxcli network ip interface ipv4 get esxcli network ip route ipv4 list # 2. 物理网卡状态与错包 esxcli network nic list esxcli network nic stats get -n vmnic0 # 3. 虚拟交换机与上行 esxcli network vswitch standard list esxcli network vswitch standard uplink list # 4. 防火墙规则集确认 443/902 没被拦 esxcli network firewall ruleset list | grep -i -E vSphereClient|vmConsole # 5. 当前连接看 hostd 是否还在监听 esxcli network ip connection list | grep -E :443|:902 # 6. ARP 表看网关和邻居是否正常解析 esxcli network ip neighbor list # 7. 关键日志尾部 tail -n 200 /var/log/hostd.log tail -n 200 /var/log/vmkernel.log其中第 2 条最容易被跳过但价值最高。nic stats里的Dropped、Errors、CRC、Overruns四个数只要有一个在持续增长就说明问题在物理层或驱动层这时候抓上层协议的包意义不大。第 6 条能快速暴露 IP 冲突和网关 ARP 老化如果网关条目状态反复在 REACHABLE 和 STALE 之间跳同网段八成存在地址冲突。日志方面hostd.log里搜“Timeout”“Connection reset”“SSL”能定位应用层vmkernel.log里搜“vmnic”“link down”“NAPI”能定位驱动层。建议先把日志打包走用vm-support生成支持包这个动作不改变现场状态但会在事后救你一命。3.2 抓哪个点vmk、uplink、switchport 的取舍ESXi 的抓包位置有三个层次选错了要么抓不到包要么抓到重复包。抓 vmkernel 接口--vmk vmk0看到的是主机协议栈视角的流量适合判断“主机有没有发出包”“上层有没有收到应答”。如果这里看不到 SYN说明主机的路由或防火墙在丢弃如果看到 SYN 但看不到 SYN-ACK问题在外侧。抓物理上行--uplink vmnic0看到的是离开/进入网卡的原始帧适合判断“包到底有没有上网线”。这个位置最接近物理层能暴露 VLAN 标签、MTU 截断、上行选择错误的问题。抓虚拟端口--switchport portID适合定位某台虚拟机或某个 vmkernel 接口与虚拟交换机之间的交互端口 ID 用net-stats -l或esxcli network vm list查。选择逻辑很简单先怀疑主机内部就抓 vmk先怀疑外部网络就抓 uplink要确认虚拟交换机有没有正确转发就抓 switchport。拿不准的时候两个点同时抓通过时间戳对齐做比对这招我用了很多次几乎是判断“丢在哪一段”的最快方式。抓包前必须估算容量否则容易把本地盘写满。计算方式文件大小 ≈ 包数 × (96 字节截断 16 字节文件头 16 字节记录头) ≈ 包数 × 128 字节。管理网络平时心跳流量很低几百 pps 量级8 小时按 300 pps 算就是 864 万包约 1.1 GB本地盘能扛住。但如果遇到广播风暴pps 可能上万一小时就是 4 GB 以上。所以一定要先设截断长度和包数上限宁可少抓一点也不能把盘写满——盘满了会连带影响日志写入和虚拟机快照。注意抓包文件不要写在正被诊断的存储或管理网络上优先放在本地磁盘的独立目录或者干脆写到内存盘/tmp。/tmp容量小但速度快适合抓短时间的突发流量缺点是重启即丢。4. 实操从零完成一次管理网络抓包4.1 环境准备与前置检查假设场景是这样的某公司机房一台 ESXi 主机每天凌晨定时任务期间变成未响应十来分钟后自己恢复白天一切正常。管理网络是 192.0.2.0/24文档示例网段管理 vmkernel 是 vmk0物理上行是 vmnic0网关 192.0.2.1管理端在 192.0.2.50。动手前先确认三件事SSH 或本地控制台的 Shell 已开启、本地磁盘剩余空间足够、确认当前没有重要任务在跑。开启 SSH 这件事本身有安全成本用完立刻关掉这是纪律不是建议。# 确认本地存储挂载点与剩余空间 df -h | grep -E vmfs|tmp # 建一个专门放抓包文件的目录 mkdir -p /vmfs/volumes/datastore1/capture进入 4.2 之前先看帮助确认本机版本支持的参数这个动作能避免一半的语法错误pktcap-uw -h不同版本在参数命名上略有差异尤其是文件轮转和捕获点相关的选项以本机帮助输出为准不要照抄别人的博客。这是个很实在的经验同一套命令在 6.7 和 8.x 上不一定完全通用。4.2 命令落地三个位置同时开抓针对这个场景我一般开三个抓包任务分别对应“主机内部视角”“物理上行视角”“目标端视角”。# A. 抓管理 vmkernel 接口双向过滤 443截断 128 字节 pktcap-uw --vmk vmk0 --dir 0 --snaplen 128 \ --proto 6 --dstport 443 \ --outfile /vmfs/volumes/datastore1/capture/vmk0-443.pcap # B. 抓物理上行只看与网关的交互覆盖整个管理网段的动静 pktcap-uw --uplink vmnic0 --dir 0 --snaplen 128 \ --outfile /vmfs/volumes/datastore1/capture/vmnic0-all.pcap # C. 抓 902 端口排除控制台通道的干扰 pktcap-uw --vmk vmk0 --dir 0 --snaplen 128 \ --proto 6 --dstport 902 \ --outfile /vmfs/volumes/datastore1/capture/vmk0-902.pcap 参数解释一下。--dir 0是双向1是入向从外部进入主机2是出向--proto 6表示 TCP--snaplen 128把每个包截断到 128 字节够看 TCP 头和部分负载能显著降低文件体积。为什么是 128 而不是 96因为要完整保留 TCP 选项字段时间戳、窗口缩放排重传和 RTT 时这些字段很关键如果只关心有没有握手96 就够。这个取舍值得说清楚很多人抄了-s 0全包结果一小时写好几百 G。如果目标版本支持捕获丢弃点加一条能看到被丢弃的包及原因对定位虚拟交换机丢包特别有用# 需确认本机支持 --capture 参数 pktcap-uw --uplink vmnic0 --capture Drop --dir 1 --snaplen 128 \ --outfile /vmfs/volumes/datastore1/capture/vmnic0-drop.pcap 抓完后记得按 PID 停掉后台任务别让它们一直跑pktcap-uw --list 2/dev/null || true # 部分版本可列活动会话 ps | grep pktcap kill PID另一种工具是tcpdump-uw语法接近通用 tcpdump适合习惯这个工具链的人也支持按大小轮转tcpdump-uw -i vmk0 -s 128 -w /vmfs/volumes/datastore1/capture/gw.pcap \ -C 200 -W 5 host 192.0.2.50 and port 443-C 200表示单文件 200 MB 轮转-W 5表示最多保留 5 个文件这套组合是环缓冲跑一整天也不会撑爆盘。如果你只打算记住一个抓包命令就记这条它对长时间守株待兔最友好。4.3 把 pcap 捞出来看先看四样东西文件在 ESXi 上通过 SCP 传到分析机就行。分析时不用一上来就全量打开几百万包按这个顺序看效率最高。第一步看 TCP 重传率和 RTT 分布。统计里如果重传超过 1%管理网络的“偶尔失联”就有解释了。重传集中在某个时间窗口就把时间点记下来跟系统日志、备份任务时间表做比对。第二步看握手是否完成。过滤tcp.flags.syn 1看 SYN 有没有对应的 SYN-ACK。只见 SYN 不见 SYN-ACK说明对端没回或者被中间设备拦了同时抓到多个 SYN 但没有 ACKSYN 重传基本就是丢包或者目标端口无监听。第三步看是否有 ARP 异常。过滤arp观察是否有“同 IP 不同 MAC”的应答或者网关 ARP 请求长时间无应答。这一条能抓出地址冲突和网关老化很多“未响应”其实是主机不知道网关 MAC 了。第四步对时间线。把 pcap 的时间戳和hostd.log里第一条 Timeout 的时间对上去误差应在几秒之内。如果日志说超时的时间点抓包里那个时刻的链路是干净的没有重传、没有丢包、握手正常那问题就往上走去查 hostd 自身和存储 I/O。回到这个案例三个抓包文件对比后发现uplink 侧在凌晨有大量来自管理网段的 ARP 广播同时 443 会话出现周期性重传重传间隔与定时任务的启动时间吻合而 vmk0 侧的包发出后迟迟等不到应答。最终定位是上游一台接入交换机端口开启了某种泛洪抑制突发广播触发抑制后短暂阻断转发。交换机侧调整参数后未响应再没出现。这个结论完全靠“三个点同时抓包 时间戳比对”得出单点抓包根本看不出这个因果。5. 三个真实场景复盘别把所有锅都甩给网络5.1 案例一错包计数在涨但涨得很慢某实验室一台主机每周未响应一到两次每次持续几分钟。网络侧排查一圈无果最后是nic stats里那个不起眼的 CRC 错包数字暴露了问题——每周几十个占比极低几乎被忽略。换了光模块和跳线后清零故障随之消失。这个案例的教训是管理网络的“间歇性”故障优先看物理层计数哪怕数字很小。判断标准不是绝对值大小而是“是否持续增长”。我的做法是间隔 10 分钟连查两次两次数值相同才算稳定一次性采样没什么参考价值。5.2 案例二MTU 不一致导致大包默默消失某公司把 vMotion 和存储流量放在同一对物理网卡上MTU 配了 9000管理网络也复用了这对上行。现象是平时正常一做批量迁移管理端就失联。抓包显示小的控制包正常收发一旦有大包就断且没有 ICMP 的“需要分片”报文回来——中间设备直接静默丢弃了。验证方法很直接用不分片的 ping 逐级试探# 验证 9000 MTU8972 8 字节 ICMP 头 20 字节 IP 头 9000 vmkping -d -s 8972 -I vmk1 192.0.2.20 # 验证 1500 MTU1472 28 1500 vmkping -d -s 1472 -I vmk0 192.0.2.1-d是不分片-s是负载长度。这个加减法很多人算错记住“MTU 负载 8 20”IPv4 场景下 1500 MTU 对应 14729000 对应 8972。如果 1472 能通、1473 不通说明路径 MTU 就是 1500如果 8972 不通而 1472 通说明中间某一段没放开大帧。把管理网络和存储网络彻底分开走不同上行是根治办法。5.3 案例三时间漂移把网络问题“造”了出来一台主机反复显示未响应抓包一切正常重传率几乎为零RTT 稳定。最后在日志里发现证书校验失败的记录原因是主机 BIOS 电池失效硬件时钟跑偏时间同步又因为管理端不可达而失败形成死循环。这类问题的识别特征很明显抓包干净但应用层报错。判断方法是对比主机时间和一台可靠的时间源偏差超过 5 分钟就该警惕。修复动作是先手动校准时间、修好时间同步源再重建管理端连接。从此我上机第一件事就是date -u看一眼比什么都快。6. 常见问题速查与踩坑清单6.1 问题速查表现象最可能原因快速验证处置动作规律性失联几分钟自愈中间设备会话老化对比失联间隔是否固定调整保活或会话老化时间批量任务期间失联MTU 不一致 / 上行拥塞vmkping -d -s 8972统一 MTU拆分流量抓包无重传但应用报错证书、时间、进程卡死date -u、查 hostd 日志校准时间重启管理代理同网段 ICMP 双应答IP 地址冲突抓arp看 MAC 变化排查冲突设备443 端口探测不通但 ping 通防火墙或 hostd 停止查规则集与进程放行规则重启服务交换机端口计数器错包增长光模块、跳线、协商间隔取两次计数对比换线换模块固定速率抓包文件写不进去目标路径空间不足或只读df -h看挂载点换本地盘或/tmp6.2 十条踩坑经验第一条别在未确认主机状态前重启。带外控制台先看一眼能省掉很多麻烦。第二条抓包前先跑pktcap-uw -h。版本差异导致参数不通用照抄会浪费大量时间。第三条永远设--snaplen。全包抓取在管理网络这种流量下也没有意义128 字节足够做九成的判断。第四条长时间观察用环缓冲-C加-W的组合比单文件更安全不会把盘写满。第五条抓包文件别放在被诊断的路径上。存储链路有问题时你连文件都取不出来。第六条多点同时抓靠时间戳对齐。单点抓包只能证明“这里有没有包”证明不了“包丢在哪一段”。第七条错包计数的判断标准是趋势不是绝对值。间隔采样两次对比别信一次性快照。第八条MTU 验证用不分片 ping记住 1472 和 8972 两个数。这个小技巧能省下几小时的抓包时间。第九条先看日志再看包。日志里往往已经写明了方向抓包是验证不是探索。第十条抓完立刻关 SSH、清临时文件。临时目录和抓包文件本身就是风险面。我个人在实际操作中的体会是“未响应”这个状态最坑的地方不是技术难度而是它给你一种“必须马上做点什么”的压迫感。真正有效的动作往往是反直觉的——先不动先把现场状态固定下来先把三个抓包点开起来让证据自己说话。我手里那套排障脚本核心其实就三行查计数、查日志、开抓包剩下全是等待和比对。慢一点反而快。