OpenStack虚拟机HA的核心答案是:通过控制节点上的服务健康检查与计算节点上的资源调度联动,在物理机宕机或虚拟机操作系统崩溃时,自动将实例在数分钟内迁移到健康节点并完成网络与存储的重新挂载。这套机制不依赖人工干预,但配置门槛集中在实例的启动策略、存储后端和网络拓扑三个层面,下面直接拆解实现过程。
虚拟机HA的底层工作逻辑
OpenStack的HA不是单指一个组件,而是由Nova、Neutron、Cinder和Pacemaker等模块协同完成的故障闭环。
物理机宕机时Nova怎么发现
Nova计算节点(nova-compute)会周期性向控制节点发送心跳报告,在默认配置下,这个间隔是10秒,控制节点上的nova-conductor如果连续3个周期没有收到心跳,就会把该计算节点标记为“故障”,但注意,标记为故障不等于自动迁移,真正触发迁移动作的是实例的SHELVE_OFFLOADED状态与reschedule逻辑。
关键点在于:
- 虚拟机启动时指定了
--availability-zone和高可用策略(如os-availability-zone),Nova才会考虑迁移。 - 底层使用共享存储(如Ceph、NFS),虚拟机的磁盘文件不在本地,迁移才有意义。
- 计算节点通过
nova-compute服务发现异常后,会调用nova-scheduler在其它健康节点上重新调度。
虚拟机内部故障怎么感知
物理机宕机的场景相对容易处理,但虚拟机操作系统卡死、内核崩溃这类内部故障,OpenStack原生机制不够灵敏,此时需要引入宿主机的watchdog或客户机内的qemu-guest-agent。
实操中常见的做法:
- 在裸金属节点上启用
hardware watchdog,通过/dev/watchdog检测虚拟机响应。 - 给虚拟机配置
hw_watchdog_action为reset,当客户机超过设定时间(如120秒)无响应,Hypervisor直接强制重启该虚拟机。 - 结合Ceilometer或Prometheus监控,检测到实例网络流量长时间为零后,通过API触发
nova evacuate。
行业共识认为,纯靠OpenStack内核实现虚拟机应用层故障感知并不现实,HA主要保障的是“宿主层”和“实例层”的可用性,应用本身的高可用需要结合负载均衡或集群软件。
控制节点自身的HA不给虚拟机拖后腿
如果控制节点挂掉,计算节点虽然还能维持现有虚拟机运行,但无法执行漂移操作,因此完整的HA方案必须包含控制节点集群。
Pacemaker+Corosync做控制节点的“保险丝”
Pacemaker管理VIP和核心服务(如keystone、nova-api、neutron-server)的启停,Corosync负责节点间通信与投票,理想状态下控制节点至少部署3个,形成奇数节点避免脑裂。
配置时有几个细节容易踩坑:
- 各控制节点的
/etc/hosts解析必须一致,否则集群通信失败。 - 资源定义中要区分
clone资源(所有节点同时运行)和资源(同一时刻只在一个节点运行)。primitive
- VIP漂移依赖
ocf:heartbeat:IPaddr2资源,接口名和网段要提前规划好。
数据库和消息队列的HA是隐藏前提
如果Galera数据库或RabbitMQ集群不可用,一切调度都是空谈,Galera集群推荐至少3个节点,写入性能会因同步复制有所下降,但换来了数据一致性,RabbitMQ镜像队列要设置ha-mode: exactly和ha-params: 3,确保消息不丢。
OpenStack虚拟机HA配置的核心步骤
下面前置条件均已满足(共享存储、控制节点集群、网络节点有冗余),给出可直接落地的操作路径。
第一步:配置实例的调度策略
创建虚拟机时显式声明可用域并开启强制调度:
openstack server create --flavor high-availability --image ubuntu-22.04 --nic net-id=prod-net --availability-zone nova:compute-node-02 --property resilience=True --os-availability-zone-host capability:dedicated=1 ha-test-vm
如果不希望每次创建都加参数,可以在/etc/nova/nova.conf中修改:
[filter_scheduler]
enabled_filters = AvailabilityZoneFilter,ComputeCapabilitiesFilter,NUMATopologyFilter
ignore_hosts = compute-node-01
这里的核心是让调度器筛选出的目标节点必须健康且存储可见。
第二步:开启强制疏散和自动重启
修改计算节点上的nova-compute.conf:
[DEFAULT]
resume_guests_state_on_host_boot = True
evacuate_on_failure = True
force_evacuate = True
同时控制节点的nova-api.conf中需要配置:
[api]
osapi_compute_force_evacuate = True
行业共识指出,force_evacuate必须谨慎开启,它会在源计算节点仍然存活的情况下强制疏散,可能导致虚拟机在两端同时运行(双跑),生产环境建议对该参数做严格的审计。
第三步:结合编排服务自动拉起
如果使用Heat或Tacker,可以在模板中定义OS::Nova::Server的metadata字段,通过heat-auto-heal定期检查实例状态,但对于绝大多数生产环境,直接使用nova evacuate命令或编写脚本调用OpenStack API更直观。
一个手工验证故障切换的命令段:
# 模拟计算节点宕机 systemctl stop nova-compute # 查看节点状态 openstack compute service list # 强制疏散指定实例 openstack server evacuate <server-id> --password <admin-pass>
执行后实例会进入MIGRATING状态,随后在目标节点变为ACTIVE,整个过程中实例的IP和端口保持不变,因为网络配置(VIP或Floating IP)跟随端口而不是宿主。
故障切换期间的性能和网络影响
HA不是无代价的,切换过程会发生一些可感知的变化。
切换时间大致分布
| 阶段 | 耗时估算 | 决定因素 |
|---|---|---|
| 心跳超时发现 | 30秒~60秒 | nova-conductor轮询周期 |
| 调度器选点 | 2秒~5秒 | 节点数量和过滤规则 |
| 虚拟机冷迁移(疏散) | 1分钟~5分钟 | 内存大小,磁盘镜像大小 |
| 网络端口重新绑定 | 5秒~15秒 | Neutron插件类型(OVS/OVN) |
| 存储卷重新挂载 | 3秒~10秒 | Ceph或NFS的并发性能 |
总体上,一个4核8GB内存的虚拟机做完疏散切换大约需要2~3分钟,这段时间里TCP连接会完全中断,对依赖长连接的业务(如WebSocket、数据库连接池)影响显著。
数据一致性如何保障
如果使用Ceph作为后端,虚拟机系统盘和Cinder卷都位于RBD上,疏散时新节点直接从Ceph挂载镜像,不会出现数据丢失,但若是本地磁盘存储(比如LVM驱动),那么疏散出来的虚拟机实际上是一个损坏的磁盘副本,无法正常启动。
所以一个不得不说的话:想在OpenStack上实现靠谱的HA,共享存储是硬性门槛,Ceph或NFS二选一,NFS要保证网络延迟低于2ms,Ceph则要保证集群至少3个OSD节点。
OpenStack高可用架构的扩展思路
除了基本的主机和虚拟机级别HA,某些业务场景还要求跨可用域(AZ)容灾。
跨可用域的HA怎么做
在Nova中,AZ是通过availability_zone划定的,每个AZ默认对应单独的共享存储池和网络段,跨AZ的虚拟机HA调度需要满足:
- 存储层打通(比如两个AZ共用同一个Ceph集群)。
- Neutron使用BGP或大二层网络打通子网。
这种情况下,故障切换的判定条件要更加严格,不建议在网络不稳定或跨地域的机房之间做自动切换,否则容易引发脑裂双写。
与Kubernetes共存时的HA策略参考
很多企业现在是OpenStack承载传统虚拟机,K8s承载容器应用,虚拟机HA的角色是兜底,例如承载K8s节点的主机宕机时,OpenStack负责把虚拟K8s节点重新疏散起来,K8s的控制平面则通过自身的高可用机制在容器层面完成角色转移,本质上,OpenStack HA是基础设施层的最后一根保险丝,没必要让虚拟机内部的应用感知到切换过程。
常见故障场景与排查路径
计算节点宕机后实例卡在ERROR状态
这种情况多半是因为:
- 目标节点无法访问Ceph,检查Ceph认证和存储配置。
nova evacuation没有指定目标主机,调度器找不到符合条件的主机。- 实例带有快照或者绑定卷的类型不受支持。
排查时执行:
openstack server show <server-id> openstack server list --host <故障节点> --all-projects grep -i "evacuat" /var/log/nova/nova-conductor.log
虚拟机在另一节点启动后网络不通
网络问题的成因较为集中:
- OVS agent状态异常,新节点上的安全组规则未生效。
- 使用VLAN模式时,需要提前在交换机上放行新节点所属的VLAN。
- 端口绑定类型是
binding:vif_type为binding_failed,手动删除端口后重建。
在Neutron中强制迁移端口:
openstack port set --host <新节点> --binding-profile vnic_type=normal <port-id> openstack server migrate --confirm <server-id>
怎么验证HA是否真的生效
这是一个进行压力测试的问题,可以模拟不同层级故障:
- 第一层:杀虚拟机进程(
virsh destroy),测试watchdog重启。 - 第二层:停止nova-compute服务,测试疏散机制。
- 第三层:拔掉物理机网线或断电,测试心跳超时和冷迁移。
每一层测试都会暴露不同的问题,在真正上线前把这个三层测试做完,算是对自己的架构有了底。
关于自动故障切换的决策建议
实现OpenStack虚拟机HA的完整链路包含存储共享、控制节点集群、Nova调度策略、客户机心跳监控四个环节,多数情况下,如果只是部署了Pacemaker和Ceph,却没有设置虚拟机的evacuate策略,故障时并不能做到自动切换,OpenStack没有一键开启所有高可用的魔术开关,每个环节的配置都直接决定最终效果。
如果是生产环境,建议先从小规模节点验证开始,确认切换时间窗口和恢复能力符合运维指标后,再逐步扩大范围,这套配置本身并不复杂,但它所依赖的大规模分布式组件联动,才是真正值得耗费时间和精力的部分。
OpenStack虚拟机HA常见问题
OpenStack虚拟机在节点宕机后一定会自动迁移吗?
不一定,默认情况下,如果虚拟机没有显式配置可用域或指定主机,且存储使用的是本地磁盘,那么节点宕机后虚拟机只会进入ERROR状态,不会自动迁移,只有在共享存储、Nova服务组策略和相关调度过滤规则同时满足时,才会触发自动疏散。
evacuate和live-migration在故障切换上有什么区别?
evacuate是针对故障节点的强制疏散,虚拟机会被冷启动到新节点,期间业务中断;live-migration是虚拟机在运行状态下在线迁移,业务不中断,但要求源和目标节点都必须健康,故障场景下只能使用evacuate,正常情况下做硬件维护则用live-migration。
监控脚本检测到虚拟机内部无响应,如何触发OpenStack层面的自动切换?
脚本可以通过调用Nova API来驱逐实例(evacuate),但需要先确保该实例绑定的卷在共享存储上,而且目标节点有足够资源,需要设置Nova的service_down_time参数不要太大(通常60秒~180秒),否则API调用可能因为目标节点心跳尚未超时而被拒绝,如果注重业务级健康检查,建议在虚拟机内部部署Agent上报状态到监控平台,由平台决策是否调用API驱逐实例。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/621848.html





