虚拟机宕机并不可怕,真正可怕的是定位思路混乱,导致恢复时间被无限拉长,快速定位原因并恢复服务,核心是“先看宿主机,再看虚拟机系统,最后查日志”,按顺序排查可缩短故障恢复时间。
如何快速定位虚拟机宕机原因?从宿主机状态开始判断
虚拟机宕机后,第一步不是急着重启,而是确认宿主机是否还活着,业内专家指出,超过半数的虚拟机“假死”其实源于宿主机的资源争抢或内核异常,登录OpenStack控制节点,用openstack server list确认虚拟机状态,如果显示SHUTOFF或ERROR,说明是异常关闭;如果显示ACTIVE但无法连接,则可能是网络或内部进程问题。
接着查看宿主机负载,执行ssh 宿主机IP,用uptime看系统负载,用free -h看内存余量,用df -h看磁盘空间,很多情况下,磁盘写满会导致虚拟机磁盘I/O卡死,进而触发系统停机保护,如果宿主机负载正常,再通过virsh list --all查看实例是否存在,这一步能快速区分是OpenStack层面的故障还是底层虚拟化层面的故障。
宿主机资源耗尽:最常见的“隐形杀手”
宿主机CPU或内存被其他虚拟机抢占时,受害虚拟机不一定立刻宕机,而是表现为响应极慢、SSH卡顿,最终被健康检查判定为异常并强制关闭,此时用virsh dominfo 实例名查看CPU和内存分配,再对比宿主机总资源,若发现宿主机内存剩余不足500M,属于严重不足状态,建议立即迁移其他虚拟机或关闭非核心实例。
磁盘空间问题更隐蔽,OpenStack默认使用qcow2格式,虚拟磁盘会缓慢增长,当宿主机/var/lib/nova/instances所在分区使用率达到100%时,所有写入操作都会失败,虚拟机内核大概率报I/O error后自动重启或宕机,排查命令:df -h /var/lib/nova,如果确认满掉,优先删除该宿主机上的备份镜像、旧的快照或日志文件,而不是直接重启虚拟机
,否则磁盘写入依旧失败,虚拟机起不来。
网络层故障:表现为“虚拟机活着,但服务不通”
有时候虚拟机进程还在,可业务就是连不上,这种情况容易被误判为宕机,实则是网络中断,在控制节点用openstack network agent list检查DHCP和L3代理是否在线,再openstack port list确认虚拟机端口状态,如果端口显示DOWN,大概率是虚拟网卡或Linux Bridge/OVS配置出了问题。
检查宿主机上的网桥状态:ovs-vsctl show,或者ip a查看tap接口是否存在,常见故障是OpenVSwitch服务重启后网关丢失,导致云主机无法与外部通信,处理方式是重启neutron的相关服务:systemctl restart neutron-openvswitch-agent,同时注意检查安全组规则是否误删了放行端口。
虚拟机内部排查:系统层面如何确认宕机原因?
宿主机没问题,就需要进入虚拟机内部找证据,OpenStack无法直接查看虚拟机内部状态,只能通过控制台或串口,使用openstack console url show 实例名获取VNC或SPICE地址,打开浏览器远程登录,这一步能直观看到内核panic、磁盘满导致的Read-only文件系统、或者SSH服务死掉等状态。
如果是Linux系统,重点检查/var/log/messages和/var/log/syslog,寻找oom-killer、panic、failed to mount等关键字,例如出现Out of memory: Kill process,说明是内存不足触发OOM,系统自动杀掉了关键进程导致关机,常见于没有配置swap、虚拟机内存过小、或者应用存在内存泄漏。
关键日志分析:从内核日志到应用日志的层层筛查
虚拟机内部的日志按三个优先级排查,第一优先级是dmesg输出,用dmesg -T | tail -100查看最后200条内核消息,多数硬件错误和驱动崩溃会显示在这里,第二优先级是系统日志,用journalctl -xe
查看systemd记录的异常退出进程,第三优先级才是业务日志,比如Nginx的error.log或Java应用的gc.log,用于确认是否因业务自身异常导致资源耗尽。
多数情况下,内核日志能直接给出宕机原因,比如出现Call Trace伴随Killed process,就是内存溢出;出现blk_update_request: I/O error就是磁盘故障,确认原因后,再针对性修复,例如OOM问题,建议调大虚拟机内存规格,或者开启swap分区;磁盘I/O错误则需要迁移虚拟机到健康宿主机的存储上。
快速恢复服务的实用命令序列
定位到原因后,恢复服务要按优先级操作,如果磁盘满导致宕机,先用openstack server start 实例名尝试启动,启动成功后立即清理虚拟机内的临时文件,否则磁盘依旧满,几分钟后又会宕机,如果启动失败,就用openstack server rescue 实例名进入救援模式,挂载原磁盘到临时实例进行修复,修复完成后再unrescue。
如果是宿主机故障导致虚拟机崩溃,且虚拟机磁盘属于ceph共享存储,可以直接在其他健康宿主机上执行openstack server migrate或nova evacuate,evacuate操作会把虚拟机重建到另一台物理机上,数据不丢失(仅丢失内存状态),如果是本地存储,则无法直接疏散,需要手动拷贝磁盘文件到其他宿主机,再在OpenStack中重新定义实例。
加速恢复的另一个技巧是开启自动重启策略,在nova.conf中设置resume_guests_state_on_host_boot=True,宿主机重启后虚拟机会自动恢复之前的状态,但注意,这只对宿主机重启场景有效,对虚拟机内部崩溃无效。
如何通过OpenStack监控体系提前预防宕机风险?
恢复服务是事后的补救,更好的策略是让宕机“提前被发现”,OpenStack的ceilometer组件可以采集虚拟机CPU、内存、磁盘I/O指标,配合Prometheus+Grafana实现趋势分析,实践中建议设置三层阈值告警:
当CPU使用率持续5分钟超过95%触发预警,内存使用率超过90%触发预警,磁盘剩余空间低于10%触发预警,收到预警后主动扩容,远比事后抢救成本低。
健康检查方面,通过openstack server group create --policy=anti-affinity设置反亲和策略,让核心业务虚拟机分散在不同宿主机上,避免某个宿主机宕机导致所有业务同时挂掉,新增虚拟机时,也可以在创建时指定--availability-zone把实例分布到不同机架,降低单点故障风险。
虚拟机宕机后如何快速定位原因并恢复服务?常见场景问答
虚拟机状态为ERROR时,如何恢复?
ERROR状态表示OpenStack认为该实例已无法正常管理,先用openstack server show 实例名 | grep fault查看fault信息,通常会提示错误原因,手动清除错误状态并重置状态为SHUTOFF:openstack server reset state --active 或 nova reset-state,然后执行openstack server start尝试拉起,如果持续失败,查看宿主机节点上的nova-compute.log,重点搜索BuildAbortException或NoValidHost,确认是资源不足还是存储连接异常。
宿主机宕机后,虚拟机如何快速迁移到别的节点?
核心前提是预判宿主机故障可能长期无法恢复,执行openstack server list --all-projects --host 宿主机名列出该机器上的所有虚拟机,然后使用openstack server migrate --live 实例名进行热迁移,如果源宿主机已彻底失联,改用nova evacuate --password 实例名 目标宿主机名强制疏散,注意,此操作要求虚拟机使用共享存储,且nova-compute服务正常运行,如果存储是本地盘,evacuate会抛出Cannot evacuate instance with local storage,这种情况只能手动拷贝磁盘文件,恢复顺序建议先恢复无状态业务虚拟机,再恢复有状态的数据库虚拟机,数据一致性靠数据库日志自行回放修复。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/760025.html





