简介针对中型企业私有云或虚拟化基础设施交付场景的OpenStack高可用集群实施案例源自一次面向公网提供虚拟化资源的真实项目适合负责多节点部署、网络与存储规划、控制节点高可用设计的运维及集成工程师参考。文档按规划与部署、网络分区、Ceph/Glusterfs存储选型、Pacemaker与Corosync控制节点HA、SDN与OpenDayLight集成等主线展开给出PXE LiveCD、定制安装盘、安装包与脚本三类安装方式及适用条件并结合VMware FT、KVM、超融合等实际场景说明硬件兼容性与避坑思路。资源包含1个docx文件大小约460KB内容以方法论和部署经验沉淀为主便于直接改写成内部实施方案或项目汇报素材。已有157人学习下载适合正在规划OpenStack高可用集群、希望提升部署成功率与整体稳定性的工程技术人员。1. OpenStack高可用集群案例先分清“业务不中断”和“节点不宕机”是两回事凌晨两点数据库主节点悄无声息地宕了OpenStack控制台从第二天早上开始就一直转圈。节点没坏数据也没丢但因为控制节点上的服务全依赖那一个IP所有人只能对着登录页面发愁。这是很多OpenStack高可用集群实施案例里最典型的开场——不是机器不够稳而是“高可用”在设计时只做到了一半。这篇文章要讲的是OpenStack高可用集群里控制节点怎么做才真正可用哪些组件必须堆HA、按什么顺序搭、用什么方式验证、以及哪些配置会让集群变成“假高可用”。适合正在规划私有云架构的运维以及准备走OpenStack云平台搭建这条路线的开发团队。2. 高可用架构选型三控制节点里到底哪些组件需要堆HA做高可用集群先要回答一个问题OpenStack里哪些服务挂了会要命。在经典的三控制节点案例里答案是数据库、消息队列、还有对外API入口。计算节点和存储节点相对独立但控制节点是所有单点的聚集地。这个案例按最主流的方案来拆控制节点从1个变3个再用VIP把流量打到活着的那个节点上。所以开篇的架构图里只有三层接入层用keepalived加haproxy做VIP漂移和流量分发数据层用Galera三节点同步复制保证数据库不丢事务消息层用RabbitMQ镜像队列让任务调度不因为单点队列卡死。存储部分不在本文讨论范围内但在案例里也会顺带说明边界。2.1 控制节点HA三件套keepalived、haproxy与VIP的分工用户访问OpenStack API时URL里的IP必须固定。这就是VIP存在的意义三个控制节点共享一个虚拟IP谁活着VIP就漂到谁身上。这个漂移动作由keepalived完成它通过VRRP协议在三个节点间选举主节点。但keepalived只负责“IP有人在接”不负责“收到的请求能处理”。真正负责任务分发的是haproxy。三个控制节点都装了API服务haproxy在每台节点上监听VIP对应的端口把请求按负载策略转发到三台节点上。如果某个后端节点挂了haproxy的健康检查会自动把它从转发列表里摘掉即使keepalived还没来得及切VIP转发层面已经把坏节点隔离了。这两个组件必须配套使用少一个都会出问题。只配keepalived不做haproxyVIP漂移后所有请求还是打到同一台节点上等于高可用只做了IP层面只配haproxy没有keepalived客户端就没法用一个固定地址访问集群。另外要注意keepalived的优先级差要拉开。我一般把主节点优先级设为110备节点设为100和90避免网络抖动时两台节点同时认为自己是主节点出现“双主”都持有VIP的情况。2.2 数据层Galera三节点强同步与异步复制的取舍OpenStack控制节点的数据库是最不能出错的一层——nova、cinder、neutron的元数据全在这里。传统主从异步复制在这个场景下很尴尬主库先写、从库后追主库瞬间宕机时没追上来的那部分事务直接丢失云主机元数据就不一致了。所以主流实施案例会用Galera它做的是同步复制三节点上任一写事务都要在集群内达成一致才算提交成功任何一台节点宕机都不会丢已确认的事务。但同步复制不是没有代价。整个集群的写性能会受最慢的那个节点拖累三个节点间的网络延迟一波动写请求就明显变慢。我的实践经验是三节点放在同一个机柜或至少同一个机房跨机房延迟超过10毫秒就不要再迷信Galera应该回到异步主从加半同步复制的组合。控制节点数量做成三个而不是两个加一个仲裁节点。两个数据节点加garbd仲裁节点在脑裂时非常难处理——仲裁节点本身也可能因为网络分区和两边同时失联最后无法形成多数派。三节点时多数派选举天然成立是省心且稳妥的配置。2.3 消息队列与状态层RabbitMQ镜像队列与memcached的边界控制节点上的nova-api、neutron-server都通过消息队列调度计算任务。RabbitMQ单节点挂掉整个集群的异步操作全部卡住API能通但所有任务都不执行。常规做法是三个控制节点各跑一个RabbitMQ节点再把业务队列做成镜像队列让每个队列在三台节点上都有副本。镜像队列的配置要点是策略。我在案例里用ha-all模式简单可靠。注意RabbitMQ的镜像策略只对新建队列生效对已存在的队列不生效所以要么在部署服务前先配好策略要么在策略建好后重启服务让队列按新策略重建。memcached是另一个容易被忽略的状态层组件。OpenStack的token、session缓存默认放这里如果memcached只配了主控制节点一个IPVIP漂移后所有token认证全部失效用户会被强制重新登录一次。三控制节点的memcached要配成集群配置里的server列表写三个IP缺一个都不行。3. 按“数据库优先”的顺序搭集群Galera、RabbitMQ与haproxy的落地配置部署顺序在OpenStack高可用集群里比想象中重要。常见做法是从下往上操作系统、数据库、消息队列、其他控制面服务、对接计算和存储。数据库没就绪就把nova、neutron服务全部拉起它们启动时连接数据库失败就会进入异常状态后面即使数据库恢复了也要手工重启服务才能拉回来。所以这个案例严格按“数据库优先”的顺序走。3.1 环境规划三控制节点的角色、IP与资源配比案例沿用三控制节点加计算节点的标准拓扑。控制节点只跑控制面服务计算节点只跑nova-compute和neutron-agent存储走独立节点避免控制面被业务IO拖垮。节点名角色管理网IP业务网IP参考配置ctrl-01控制节点主192.168.10.11172.16.10.118C / 16G / 200G SSDctrl-02控制节点备192.168.10.12172.16.10.128C / 16G / 200G SSDctrl-03控制节点备192.168.10.13172.16.10.138C / 16G / 200G SSDVIP虚拟IP192.168.10.10--网络分区建议三段分离管理网承载API和内部通信业务网承载实例流量存储网独立出来对接cinder或ceph。存储网如果复用管理网大流量IO会直接打爆控制节点的管理链路表现为API间歇性超时排查起来非常困惑。3.2 先搭数据库Galera三节点的启动顺序与关键参数三个节点都装好MariaDB加Galera插件后配置是第一个门槛。先看ctrl-01上的关键配置段[mysqld] server-id1 binlog_formatROW default-storage-engineinnodb wsrep_provider/usr/lib/galera/libgalera_smm.so wsrep_cluster_addressgcomm://192.168.10.11,192.168.10.12,192.168.10.13 wsrep_node_address192.168.10.11 wsrep_sst_methodrsync wsrep_cluster_nameopenstack_cluster这段配置里有几个参数决定集群能不能正常建立。wsrep_cluster_address是集群所有成员的地址列表三台节点必须写一致wsrep_node_address是本机地址不能误写成VIP否则节点之间互相通信时找不到真实的网卡地址wsrep_sst_method是节点加入时同步全量数据的方式rsync最直观适合首次搭建时排查问题生产环境有条件换成mariabackup不用锁表。启动顺序是第一个节点先起来第二个和第三个节点随后加入。新版MariaDB 10.4以上直接执行systemctl start mariadb即可旧版本需要在第一个节点上加--wsrep-new-cluster参数启动。三个节点的server-id必须不同否则binlog复制会冲突。启动后执行show status like wsrep_cluster%看到wsrep_cluster_status为Primary且节点数等于3才算建集群成功。3.3 再搭消息队列RabbitMQ镜像策略与haproxy接入RabbitMQ三节点组成集群后第一步是设置镜像队列策略rabbitmqctl set_policy ha-all ^(?!amq\.).* \ {ha-mode:all,ha-sync-mode:automatic} \ --priority 10策略名称是ha-all后面是队列名称正则^(?!amq\.).*用于避开RabbitMQ内部以amq开头的系统队列。ha-modeall表示每个业务队列在集群所有节点上都有镜像副本ha-sync-modeautomatic让新加入的节点自动同步队列内容不用手工触发同步。镜像策略只影响之后创建的队列。已经存在的旧队列不会自动获得镜像属性所以这个策略要在启动nova或neutron服务前设置好。如果发现队列没有镜像最直接的办法是删除旧队列并让服务重建。API入口的接入用haproxy完成配置片段如下listen openstack_api bind 192.168.10.10:5000 mode tcp balance roundrobin option httpchk GET /v3/ server ctrl-01 192.168.10.11:5000 check inter 5s fall 3 rise 2 server ctrl-02 192.168.10.12:5000 check inter 5s fall 3 rise 2 server ctrl-03 192.168.10.13:5000 check inter 5s fall 3 rise 2这里bind绑定的就是VIP加端口。mode tcp是四层转发因为keystone的v3接口走HTTPS直接透传TCP避免在haproxy上做证书卸载少一个证书管理上的故障点。option httpchk GET /v3/用HTTP请求做健康检查比tcp-check更准确返回非200即摘除后端。inter 5s fall 3 rise 2每5秒探测一次连续3次失败标记下线连续2次成功恢复上线——这个参数直接决定切换时长最坏情况下15秒才会发现后端节点不可用。3.4 packstack安装OpenStack的适用边界体验可以生产高可用不行如果你只是想快速跑通OpenStack云平台搭建packstack一条命令装个all-in-one环境确实最快。但packstack的设计目标就是单控制节点数据库和RabbitMQ天然是单点。网上有些“基于packstack安装OpenStack然后做高可用”的教程本质是给单控制节点套了一个keepalived的VIP数据库还是单点消息队列还是单点。主节点一挂VIP虽然漂走了但nova-api起来后连不上本地的MariaDB整个平台依然是瘫痪状态这种方案属于典型的“伪高可用”。在这个实施案例里packstack只建议拿来做安装自动化测试或功能验证基线生产级集群必须走组件化部署因为只有自己部署才能控制数据库、消息队列、缓存这些底层环节的拓扑。packstack的价值在于能快速生成一份“可运行的最小配置”作为参考而不是直接用于生产高可用集群。4. 故障注入验证拔网线、杀进程、断电三种场景与切换时长量化高可用集群搭完不算数真正的验证靠故障注入。不做故障切换的HA集群和普通多节点部署没有本质区别甚至因为多了VIP和负载均衡组件反而更容易出问题。4.1 故障注入前要收集的基线指标验证之前先把“正常状态”量化下来否则切换完根本不知道是变好了还是变差了。我一般收集三组数据API可用性、数据库集群状态、消息队列状态。API可用性用curl持续探测VIP上的keystone接口记录状态码和响应时间for i in $(seq 1 30); do code$(curl -sk -o /dev/null -w %{http_code} %{time_total} \ https://192.168.10.10:5000/v3/ --connect-timeout 3) echo $(date %H:%M:%S) $code sleep 2 done参数说明-k忽略自签证书-w输出HTTP状态码和总耗时--connect-timeout 3让连接卡住时不会拖死脚本。正常情况下输出是稳定的“200 0.2xx”格式。如果基线里就出现大量超时或5xx先把集群调正常再来做故障注入否则后面所有数据都无法区分是故障造成的还是原本就有的问题。4.2 三类故障注入实验与观察点故障注入从轻到重分三档覆盖进程级、网络级、物理级三种场景。故障等级操作方式核心观察点进程级ctrl-01上kill -9 keepalivedVIP是否在30秒内完成漂移API是否持续可访问网络级ctrl-01上ip link set eth0 downVRRP通告周期内VIP切换是否完成API恢复时间物理级直接关闭ctrl-01电源集群彻底失去主节点后新建云主机是否成功进程级故障是最温和的验证kill掉keepalived后VIP应该在几秒内漂移到优先级最高的存活节点haproxy的健康检查也会把后端摘除。网络级故障比较接近真实场景注意VIP所在接口的地址也会随网卡down掉消失下游交换机需要等待免费ARP刷新ARP表项这个响应时间会比进程级长。物理级故障最狠验证完还要检查原主节点恢复后能否自动重新加入Galera集群——如果一直卡在joining状态大概率是gcache太小触发全量SSTSST期间节点还不能对外提供服务。4.3 切换判定标准与恢复检查顺序切换验证不是看“API能通”就结束要按固定顺序检查数据库、消息队列、控制面API、计算节点状态、存储连接。原因很直接nova-api起来后要去连数据库和RabbitMQ这两层中任何一个连不上它可能显示进程活着但实际无法处理请求。先查数据库的wsrep_cluster_status是否为Primary再查RabbitMQ的镜像队列是否完整然后才看API路径。恢复操作比故障本身更容易翻车。ctrl-01恢复后不要急着把VIP手动切回去先观察30分钟确认当前主节点稳定。如果keepalived的优先级设计合理原主节点恢复后会按preempt模式自动抢回VIP这个过程对业务是透明的如果不希望它抢回来把原主节点的优先级配得比当前主节点低即可。我一般会让原主节点恢复后先当普通成员运行一天没有异常才允许它参与下次主动切换。5. 高可用集群实施避坑五个让集群变成“假高可用”的真实案例这一节是踩坑记录每条都是真实实施中遇到过的问题。高可用集群翻车通常不在架构设计上而在细节配置的连锁反应里。5.1 现象VIP漂移了但云主机控制台一直连不上集群切换完成后API和数据库都正常唯独OpenStack控制台页面打开后一直转圈加载无法进入实例的VNC或SPICE画面。原因是计算节点上nova-compute和nova-console相关的配置里memcached的地址还指向已经宕机的旧控制节点IP。VIP虽然漂移了但token缓存和console会话还是从旧地址读验不过自然进不去。解决方法是把计算节点上所有指向控制节点IP的配置改成VIPmemcached的server列表改成三个控制节点的真实IP保证任意节点持有VIP时都能读到同一份缓存。检查时用grep -r 192.168.10.11 /etc/nova /etc/neutron这类命令全局搜一遍旧IP别漏掉。5.2 现象Galera节点被逐出集群后反复回跳某个控制节点一旦重启就反复经历“加入集群—被逐出—再加入”的循环日志里大量SST请求但每次都执行到一半失败。原因是gcache.size设得太小默认值只有128M左右。节点离线期间产生的增量事务超过了gcache保留范围节点回来后无法做增量同步被迫转向全量SST而SST期间该节点又处于不可用状态被集群逐出形成一个死循环。解决方法是把wsrep_provider_options里的gcache.size调到1G以上并检查三个控制节点间的网络延迟是否稳定。注意修改gcache.size不能在运行中动态改需要先停库、改配置、再启动。5.3 现象RabbitMQ队列堆积但日志一切正常业务开始出现大规模延迟创建云主机和删除云主机的任务排不上但RabbitMQ的日志和系统日志都找不到明显报错。原因是镜像队列策略的匹配范围不对。如果策略里写的队列名是精确匹配某个固定名称而服务实际创建的队列名带了随机后缀比如reply_加一段随机字符串策略就覆盖不到这些队列仍然是单副本节点队列。主节点一挂队列内容跟着消失虽然日志没有报错但所有依赖该队列的任务全部卡死。排查时用rabbitmqctl list_policies核对策略再用rabbitmqctl list_queues name slave_nodes查看每个队列的镜像数量。slave_nodes为空的队列就是漏网之鱼解决方法是把策略正则改宽并重启服务让队列重建。5.4 现象nova-compute不定时失联控制节点日志里全是超时某台计算节点每隔几小时就被控制节点标记为失联但登录计算节点查看的时候nova-compute进程又活着负载也不高。原因是RabbitMQ的心跳超时配置太短。控制节点只要出现一次GC暂停或网络微抖动计算节点的心跳就断了控制节点马上把计算节点标记为下线正在执行的任务全部失败。解决方法是把RabbitMQ的心跳超时heartbeat参数放宽到60秒以上同时检查计算节点上的消息队列地址配置——如果写的是某个控制节点的真实IP而不是VIP那这个控制节点宕机时计算节点就会直接失联需要改成VIP地址。5.5 现象升级或重启顺序不对导致脑裂对集群做例行重启后三个控制节点互相不认Galera集群分裂成两个独立的Primary分区两边同时接收写请求数据直接分叉。原因是三个控制节点同时重启时Galera要求第一个启动的节点先建立集群另外两个节点随后加入如果三台几乎同时起来节点之间会各自认为自己是新的集群起点。解决方法是固化恢复顺序先启动第一台确认wsrep_cluster_status为Primary后再启动第二台和第三台全部进入Synced状态后才拉起控制面的其他服务。这条顺序我直接写进了维护手册并贴在控制节点所在机柜的柜门上。6. 切换演练脚本与巡检清单上线前的最后一道工序案例做到这里最后一步是让“高可用”成为团队的条件反射而不是某个人脑子里的经验。我每个季度做一次切换演练并且练完不切回让新主节点自然接管两天没问题再切回原主节点。下面这个脚本模拟主节点宕机并验证VIP和API路径的恢复时长。#!/bin/bash # 高可用切换演练模拟主控制节点故障并验证VIP有效性 PRIMARY_IP192.168.10.11 VIP192.168.10.10 ssh ${PRIMARY_IP} systemctl stop keepalived for i in $(seq 1 20); do code$(curl -sk -o /dev/null -w %{http_code} \ https://${VIP}:5000/v3/ --connect-timeout 2) echo $(date %H:%M:%S) HTTP $code [ $code 404 ] break sleep 3 done脚本逻辑很简单远程停掉主节点的keepalived模拟故障然后持续探测VIP。HTTP返回401说明keystone正常要求认证200或403说明接口可访问404说明路径通了但服务还没注册完连续无响应则说明VIP还没飘到备用节点。用这个脚本可以大致测出切换窗口的时间长度。每次切换演练后的巡检清单固定如下检查项命令或位置通过标准VIP归属ip addr showVIP只出现在一个控制节点上数据库集群mysql -e show status like wsrep_cluster_%wsrep_cluster_status为Primary消息队列镜像rabbitmqctl list_queues name slave_nodes业务队列slave_nodes数量为3API路径curl -k https://VIP:5000/v3/返回值非5xx计算节点状态openstack compute service list所有nova-compute状态为enabled且up我第一次做切换演练挑在周五下午结果切换后nova-compute集体失联整个周末都在机房擦屁股。后来我把演练固定到周二凌晨留足两小时善后窗口这个习惯一直保留到现在。高可用集群能不能信不取决于架构图画得有多完整而是你有没有亲手按过那个电源键。希望帮到你。本文还有配套的精品资源点击获取