☰
OpenStack Nova深度拆解:架构、调度与故障排查实战
2026/10/10 10:39:45 网站建设 项目流程

做OpenStack运维的,不管你是从哪个版本入手的,肯定绕不过Nova这个组件。我之前跟人聊架构的时候经常发现一个现象:很多人用一行命令装完一套环境,能建虚机能删虚机,但真到了排查“虚机一直BUILD”、“迁移失败”、“调度选不到宿主机”这类问题的时候,就不知道去哪里看日志、看队列、看数据库状态了。这一篇是《每天5分钟玩转 OpenStack》系列的第26篇,专门把Nova从头到尾拆一遍,从架构分工、子服务职责,到实例创建流程、状态机、资源管理、高发故障排查,再到生产配置调优,尽量用大白话讲明白。

这篇内容偏运维+虚拟化方向,但也适合刚接触OpenStack的入门者。我的建议是,读的时候带上一个自己的环境随手验证,光看文字记不住。文中涉及的配置和排查思路,以你现网实际版本为准,毕竟Nova在不同版本里的行为和代码路径还是有差异的,这里讲的都是通用原理和踩坑经验。

1. 先从架构视角理解Nova在OpenStack里的角色

1.1 Nova到底管什么

Nova的全称是OpenStack Compute,也就是计算服务。它管的是虚拟机实例的整个生命周期:创建、启动、关闭、重启、挂起、恢复、迁移、快照、重建、删除,以及规格调整(resize)。你可以把它理解成“虚拟化资源的管理大脑”。

但有一点容易被新手搞混:Nova本身不是虚拟化软件。它不是一个KVM,也不是QEMU,更不是VMware,它做的事情是把上层用户的请求翻译成底层虚拟化平台能懂的操作。底层可以是KVM、QEMU、VMware ESXi、Hyper-V,甚至在某些场景下是容器驱动。Nova通过不同的compute driver,也就是驱动层,去对接这些不同的虚拟化实现。

打个比方,Nova更像是一个项目的总包工头。用户说“我要一间两室一厅”,总包工头不会自己砌墙,而是根据需求决定让哪个施工队进场(调度到宿主机),然后去调用配套的资源:板材(镜像)、水电(网络)、家具(存储)都从Neutron、Cinder、Glance这些供应商那里协调过来,最后看着工人把房子盖好(虚拟机启动),之后还要负责后续的修缮和拆除。

所以在OpenStack整个生态里,Nova不是万能的。网络配置归Neutron管,块存储卷归Cinder管,镜像归Glance管,身份认证归Keystone管,计量与监控由Ceilometer这些组件负责。Nova更像一个中枢,它负责发起请求、做出决策、驱动别人干活,然后把结果汇总返回给用户。

1.2 Nova为什么要拆这么多服务

一个新接触OpenStack的人最容易犯的错,就是在控制节点上看到一大堆nova开头的进程,然后犯迷糊:为什么一个“计算服务”需要这么多服务?这其实是OpenStack从早期的单体架构演进过来的结果。

最开始的时候,Nova的功能集中在一个服务里,但随着规模变大,人们发现单体服务不好扩展、不好维护。于是Nova被拆成了多个子服务,服务之间通过消息队列(通常是RabbitMQ)进行通信,数据库也独立出来。这样的好处很明显:不同的服务可以独立部署、独立扩容,一个服务挂了不至于让整个控制面全瘫。

但坏处也很明显:一次请求的链路变长了,排查问题的时候必须理解消息队列。比如一个用户创建虚机的请求,不是“按一下按钮”就完事,而是经过nova-api接收、nova-conductor加工、nova-scheduler选主机、nova-compute落地执行,这中间每一步都可能成为瓶颈,也都可能单独出问题。

所以我的经验是,学Nova不需要死记命令,先把下面这张“服务分工图”刻在脑子里:

进程主要部署位置核心职责
nova-api控制节点对外提供API,接收并校验用户请求
nova-scheduler控制节点决定实例创建在哪台计算节点
nova-conductor控制节点数据库操作的代理层,以及跨cell的协调
nova-compute计算节点真正调用libvirt/QEMU管理虚拟机生命周期
nova-novncproxy控制节点提供VNC远程控制台的WebSocket代理
nova-consoleauth控制节点控制台访问票据的认证校验
nova-cells(cell v2概念)控制节点/计算节点单元化部署与数据库路由
placement-api控制节点资源管理和分配查询,为调度提供数据

这张表不用背,后面每一行我都会展开讲。你只需要先建立一个概念:Nova家族的进程很多,但每一个都有明确分工,而且彼此之间靠消息队列串联起来。

2. Nova核心组件逐一拆解

2.1 nova-api:所有请求的最后一公里入口

nova-api是所有外部请求的必经门户。用户用OpenStack命令行工具、Horizon仪表盘、或者调SDK接口,本质上都是往nova-api发HTTP请求。它负责监听计算服务的API端口,通常由Keystone完成身份认证和权限校验,然后对请求做参数校验和配额检查。

这里的“最后一公里入口”并不是夸张。nova-api本身不应该包含太多业务逻辑,它更像一个闸口:进来一个请求,先看你是不是合法用户,再看你要做的事情是否合理,然后把任务写成一条消息丢进RabbitMQ,后续的事就交给其他Nova服务去处理。

有一个运维细节需要注意:nova-api是无状态服务,这意味着你可以开多个实例,前面挂一个负载均衡器,把请求分散到不同nova-api进程上。它不直接操作数据库,所以水平扩容非常方便。我之前见过有人把控制节点上的nova-api单副本当成理所当然,结果高并发创建时期经常超时。其实把这个服务扩到3份是成本最低的优化之一。

nova-api常见的故障点通常不是自身代码,而是依赖环境:Keystone认证超时会导致所有API请求缓慢,数据库连接池打满会导致API直接报错。遇到这类问题时,先看日志里的具体报错,别急着重启服务。

2.2 nova-scheduler:把虚机发给谁,由它说了算

nova-scheduler是Nova里最容易出“玄学故障”的组件。它的职责用一句话说就是:当用户要创建一台虚机,需要决定这台虚机到底跑在哪个物理节点上。它用的是FilterScheduler机制,也就是“过滤加权重”两步走。

第一步是过滤。所有的计算节点先按条件筛一遍,比如可用区是否符合要求、宿主机是否被禁用、CPU和内存是否足够、磁盘是否充足、机型规格是否匹配。过滤之后剩下的才是候选主机。如果过滤完一台都不剩,用户就会看到著名的“NoValidHost”错误。

第二步是打分。候选主机之间还要按权重排序,比如剩余内存多的权重高一点,CPU空闲多的权重高一点,最终选择分数最高的那台。这样做的目的是尽量把负载打散,避免新虚机总是被塞到同一台上,造成资源碎片更严重。

需要注意,scheduler在做判断时并不是实时去每台物理机上探测资源,而是基于数据库中的上报数据和Placement服务里的资源记录来决策。也就是说,它拿到的是一份“快照”,不是实时值。计算节点上的nova-compute需要周期性地把自己可用的资源量上报给Placement,如果上报延迟或者上报数据错误,调度就会做出错误判断。

这也是为什么生产环境里,当你发现“明明这台机器还有30G内存,但调度器就是不选它”的时候,不要急着去怀疑filter逻辑,先去看它的资源上报记录。很多时候,要么是上报脚本异常,要么就是上一批虚机占了资源但没释放干净。

2.3 nova-conductor:数据库前的“隔离层”

nova-conductor可能是很多入门者最陌生的一个组件,因为它的存在感低,但架构上非常关键。它的核心使命是:避免计算节点直接访问数据库,并且承担一部分跨节点的协调逻辑。

在早期的OpenStack版本中,nova-compute是可以直接读写数据库的。后来社区发现,计算节点直接连数据库有两大风险:第一,计算节点数量多,每个节点都直连数据库,数据库连接数很容易被打满;第二,计算节点是暴露给底层虚拟化环境的,一旦计算节点被攻破,数据库就跟着沦陷。于是设计了nova-conductor来当“隔离层”,所有计算节点要读数据,都得通过消息队列向conductor请求,再由conductor去访问数据库。

在新版本里,conductor还有了一层“Cell Conductor”的概念。简单理解就是,为了规模化部署,OpenStack把环境拆成多个cell单元,每个cell有自己的数据库,cell里的nova-compute不直接连cell数据库,而是通过cell里的conductor来访问。这样一来,整个资源模型变得非常安全且容易扩展。

conductor挂了会怎样?答案是灾难性的,虽然计算节点上的虚机不会立刻断电,但一切需要数据库参与的操作都会卡住,比如创建虚机、挂载卷、迁移等等。排查的时候,如果发现所有实例都卡在BUILD状态,消息队列里一堆conductor的RPC超时,大概率是conductor服务失去响应。这个时候最快的方法是看conductor日志和消息队列健康状态,而不是把计算节点挨个重启。

2.4 nova-compute:计算节点上的真正执行者

nova-compute是Nova里唯一一个需要部署在每个计算节点上的服务,也是真正和底层虚拟化打交道的“车间工人”。它的工作内容非常具体:根据上游下发的实例定义,和宿主机上的libvirt协同工作,生成虚拟机XML描述文件,调用QEMU/KVM把虚拟机拉起来,然后持续管理这台虚拟机的生命周期。

这里必须强调一点:nova-compute本身不直接调用QEMU命令,它通常通过libvirt这个统一接口来干活。libvirt就像是一个“翻译官”,把nova-compute的指令翻译成不同虚拟化平台能理解的操作。所以如果你在计算节点上看到libvirtd服务异常,不管nova-compute怎么折腾都没用,虚机照样起不来。

nova-compute的日志是排障时的宝藏。它会把每次操作的详细过程写下来,包括从glance下载镜像、创建镜像缓存、设置网络、生成XML、启动虚拟机、上报状态等。绝大多数创建失败的真实原因,最后都能在nova-compute日志里找到线索。我每次排障都是第一时间搜日志里的“Error”和“Exception”,往往比在Horizon上瞎翻快得多。

需要注意的是,nova-compute的状态和实际虚拟机状态之间不是永远一致的。比如计算节点负载过高导致nova-compute进程假死,底层虚机可能还在运行,但控制面已经认为它失联了。这种“脑裂”状态特别危险,操作前一定要采集证据,分清虚机到底还在不在宿主机上,再决定是否强制疏散或重置状态。

2.5 控制台与辅助组件:novncproxy、consoleauth等

用户通过OpenStack网页访问虚拟机的VNC控制台,背后也依赖Nova的几个辅助组件。这里简单说两个:

第一个是nova-novncproxy,它充当了浏览器和宿主机VNC服务之间的WebSocket代理。用户在前端点“控制台”,请求打到nova-api后,系统会分配一个token,然后浏览器和计算节点上的VNC端口建立起一个WebSocket通道,数据流经过novncproxy中转。它必须部署在用户和计算节点都能访问到的地方,否则控制台页面打开就是白屏。

第二个是nova-consoleauth,它负责校验控制台访问token。早期版本中,每个VNC控制台连接都需要拿到一个合法的console token,consoleauth就是验证这个token是否有效的地方。如果你遇到“点击控制台一直加载不出来”的问题,除了看网络通不通,还要看token是不是过期、consoleauth服务是否正常。

这类辅助组件容易被人忽视,但它们一旦出问题,用户的直观感受就是“控制台打不开”。实际运维中,我把它们纳入控制节点的健康检查范围,端口和进程状态都盯起来,别等用户反馈了才发现。

2.6 别忽视的数据库与消息队列

Nova流转的核心数据都存在数据库中。不同版本的库结构有差异,但大体上,管理面上有nova库和nova_api库,cell分布式部署时还有cell0和各cell自己的数据库。这里面存了虚拟机的规格、镜像信息、实例记录、主机聚合、配额、keypair、安全组历史等。

数据库出问题的表现五花八门:创建实例超时、列表接口卡顿、状态更新异常、配额计算错误。如果是数据库表结构锁死或者死锁多,经常会看到nova-*服务的日志里出现database is locked或者锁等待超时。遇到这类情况,先查慢查询和当前锁等待,再决定是否要做表结构优化,不要动不动就去重启数据库。

消息队列也一样关键。nova服务之间几乎全靠RabbitMQ传递RPC消息。消息队列一旦积压,就会出现大量请求排队,虚机创建卡住,集群表现就像“中风”。日常巡检一定要看队列积压情况,长期堆积的消息要及时清理。真实生产环境里,我见过一晚上积压了几十万条消息的RabbitMQ,整个控制面直接瘫痪,而表面看起来所有Nova服务进程都活着,非常迷惑。

3. 一个实例从无到有的完整旅程

3.1 从API请求到宿主机启动的分段流程

理解了各个子服务之后,你可以把创建虚拟机这件事看成一条生产流水线。用户输入openstack server create命令,到虚拟机真正启动,大概经历以下几个阶段:

第一阶段,请求接收与校验。用户命令先经过Keystone认证,拿到token,然后打进nova-api。nova-api通过中间件验证token,检查项目配额、镜像是否存在、flavor规格是否存在、网络是否可用。校验通过后,nova-api把创建请求封装成一条消息发到RabbitMQ,交给conductor处理。

第二阶段,调度决策。nova-conductor拿到请求后,先处理一些元数据的准备工作,比如生成实例UUID、初始化实例记录,然后把调度的活委托给nova-scheduler。nova-scheduler从Placement服务获取各计算节点的资源情况,再经过过滤和权重,选择一台合适的宿主机,返回给conductor。

第三阶段,消息下发。conductor拿到选定的宿主机后,通过消息队列向目标计算节点上的nova-compute发送创建指令。这一步是异步的,也就是说,API请求不会等虚拟机启动完成后才返回,而是先回复用户“任务已接收”,然后后台继续跑。

第四阶段,实际执行。nova-compute收到指令后开始干活:向Glance确认镜像位置,必要时下载镜像并做本地缓存;向Neutron请求创建或绑定端口;如果是卷启动的虚拟机,还要让Cinder把块设备挂载到宿主机;然后调用libvirt生成虚拟机XML,并让它启动。

第五阶段,状态上报。虚拟机启动成功后,nova-compute会向conductor汇报状态变化,conductor更新数据库,最终API查询时看到的状态变成ACTIVE。

整个流程里的每一步都可能出问题,但排查思路是一致的:顺着这条链路一段一段查,先看API有没有收到,再看队列有没有消息,最后看计算节点上的实际日志。任何一步断了,虚机都起不来。

3.2 状态机速查:见到这些状态别慌

用OpenStack的人每天都要面对一堆虚拟机状态。有些状态看起来吓人,但其实只是生命周期里正常的一环。我整理了一张速查表,建议收藏:

状态含义常见场景
BUILD实例正在创建中正常创建时的中间状态
ACTIVE实例运行中正常运行的稳态
ERROR实例创建或操作失败资源不足、镜像异常、脚本失败等
SHUTOFF实例已停止执行stop/关机后
SUSPENDED实例被挂起管理员挂起或断电保护
SHELVED实例被归档停用shelve操作后,释放内存资源
PAUSEDCPU暂停使用pause操作,类似于内存挂起但不释放
RESIZE实例正调整规格resize操作中的中间状态
REBUILD实例正重建rebuild操作中,保留原ID但更换底层
MIGRATING实例正迁移冷/热迁移过程中

我在实际工作中看到过不少新手,一看到ERROR状态就立刻执行强行删除,结果把还没释放的资源卡在数据库里,后患无穷。正确的做法是先点开实例详情,看“实例操作”(instance action)里记录的操作日志,再看计算节点上的nova-compute日志,分析失败原因。

另外,有一种状态是“跑飞”:虚机底层其实已经死了,但数据库里还显示ACTIVE。这种一般发生在计算节点宕机之后,没有及时做故障转移。处理的时候不要盲目重置,先确认虚机是否真的没了,再决定是重新放到新节点还是直接删除。

3.3 Placement为什么能从Nova里独立出来

老版本的OpenStack里,资源调度依赖的信息基本都存在nova数据库。后来社区渐渐发现这个设计对规模化和多组件协作不够友好。比如,用户可能还需要在GPU、FPGA这类特殊资源上做精细调度,而nova自带的资源统计模型比较死板。再加上其他项目也需要统一的资源视图,于是Placement服务应运而生。

Placement的角色可以理解成一个“房源总台账”。每个计算节点是一个resource provider,也就是资源提供者,会上报自己的库存(inventory),比如CPU核数、内存大小、磁盘容量、GPU数量等。当nova-scheduler做调度时,它先去Placement查一下有哪些provider还有空位,再结合过滤和权重选出最终目标。

我见过不少运维人员搞不清nova-scheduler和Placement的关系,以为只要nova-scheduler起来了就没问题。实际上,Placement一旦挂掉,nova的调度功能是瘫痪的,因为scheduler拿不到任何资源数据。所以生产环境里,Placement的进程健康检查、数据库连接、日志监控都应该排在最高优先级。

从架构演进的角度看,Placement从Nova里独立出来,是OpenStack走向更细粒度资源管理的一个标志。运维人员不要只把它当成“另一个数据库和API”,要理解它背后“资源抽象统一”的意图,这样才能在排查调度类问题时快速对症。

4. Nova高发故障排查与实战经验

4.1 故障现象速查表

几年的OpenStack运维做下来,Nova相关的故障其实高度集中。我把最常遇到的现象和初步排查方向整理成了一张表,每次遇到问题先对照一下,能省很多时间。

故障现象可能原因优先排查方向
创建虚机一直BUILDconductor或compute处理卡住、队列积压、资源不足看instance action、消息队列、nova-compute日志
NoValidHost无可用宿主机看Placement资源上报、主机是否禁用、filter配置
虚机创建后立即ERROR镜像异常、卷异常、脚本失败看创建时的操作日志和系统日志
迁移一直MIGRATING节点间存储或网络不一致、共享存储挂载异常检查两块计算节点的网络/存储一致性
nova-compute服务异常libvirtd异常、磁盘满、CPU跑满检查libvirtd状态、系统磁盘inode
控制台打不开novncproxy或consoleauth异常、端口不通检查WebSocket代理和token有效性
数据库连接数打满连接池配置不合适、慢查询堆积调整数据库连接池、定位慢SQL
Placement请求失败placement服务宕机、数据库异常直接访问/v1/resource_providers接口验证

这张表不是万能药,但可以帮你建立条件反射:看到什么现象,先去摸哪一块。很多新手排障效率低,就是因为到处瞎看,而不是沿着消息链路和资源链路去找。

4.2 虚机一直BUILD的排查思路

如果说Nova排障有一个最经典的问题,那非“虚机一直卡BUILD”莫属。这个问题我在群里被问过不下十次,其实排查套路非常固定。

第一步,用命令看当前状态和操作记录。openstack server show可以看状态,openstack server event list或instance action一类的命令能看到操作事件。重点确认操作卡在哪一步,比如是“scheduling”还是“spawning”,这直接决定了下一步去哪找日志。

第二步,看消息队列积压。因为创建流程严重依赖RabbitMQ,如果某一环消息没消费掉,后面的任务都会排队。这时上消息队列管理界面或命令行查队列里的unacked消息数量,如果很高,问题多半在消费端。

第三步,看相关服务的日志。如果是conductor阶段卡住,去控制节点看nova-conductor日志;如果是spawning阶段卡住,去对应计算节点看nova-compute日志。日志里通常会有明确的错误原因,比如“timed out”、磁盘空间不足、libvirt无法连接、镜像格式不对等。

第四步,检查数据库里的实例记录。看实例状态是否被卡住,如果有残留的锁定状态或任务状态,有时候需要清理任务状态。这一步要非常谨慎,建议先备份相关记录,再决定是否人工修正。

这个流程看起来简单,但每一步都有很多细节。我的建议是,每次排查都把日志和事件截图下来,事后归档,慢慢你就有自己的故障知识库了。

4.3 资源上报异常与调度失败

调度失败的原因很多,其中最隐蔽的一类是资源上报异常。你从计算节点上看,内存明明还剩很多,CPU也不忙,但调度器就是死活不把新虚机放到这台机器上。

这种情况十有八九是Placement里的资源记录和实际机器状态不一致。原因是nova-compute在上报资源时有一定的缓存和周期,如果计算节点出现过异常重启,或者增删了CPU、内存,而上报没有及时更新,Placement就会保存一份过期的数据。

排查方法很简单,直接用curl访问Placement API,查询这台计算节点的resource provider信息,看它的inventory和allocations。如果发现上报数据不对,检查nova-compute日志里有没有资源上报失败的记录,再看看计算节点是否需要手动触发一次资源同步。很多版本里,重启nova-compute服务就能触发重新上报,但这只能解决一部分问题,长期还是要靠监控和定期的容量校准脚本。

另外,配比(allocation ratio)也会导致类似的“假性失败”。比如你给内存配了超卖比例2.0,系统以为有足够内存,但物理机其实已经快满了,新的虚机依旧可能被调度上去,最后OOM。所以资源上报异常和超卖配置过激进是两兄弟,排查的时候要一起考虑。

4.4 升级维护中容易踩的坑

Nova的版本升级是运维里风险最高的操作之一,因为数据库结构会变,消息协议会变,服务之间的兼容性也需要小心处理。我见过最典型的问题是:升完级之后,某些节点上的老服务还在跑,结果新老版本之间通过RPC通信时出现协议不兼容,虚机创建和迁移全部异常。

升级前不要想当然地认为“先停服务、升包、启动”就完事。一定要先看官方文档的升级路径,搞清楚是N到N+1的跳跃还是逐版本升。数据库结构迁移通常要执行nova-manage db sync之类的命令,而且新版一般还有cell v2的映射操作。忘记执行这些步骤,就会出现数据库表缺列或者cell映射缺失的诡异故障。

另一个高频坑是升级后没有检查工作流。我建议升级完成后,不要只看控制台是否正常,要实际去创建一台最小的虚机,做一个“冒烟测试”。这个测试要覆盖镜像启动、网络接入、控制台访问、迁移这四条链路,全部通过才算升级成功。

还有一点,升级过程中的备份必须做全。OpenStack不像传统MySQL单库那么简单,nova相关的多个数据库和配置文件都要备份。哪怕只是一个字段错误,恢复起来也可能非常痛苦。我的习惯是升级前把数据库、配置文件、消息队列元数据全部快照,升级失败能快速回滚,而不是现场分析个半天。

5. 配置调优与容量规划的一些心得

5.1 nova.conf里值得重点关注的参数

Nova的配置非常分散,但核心的调优参数并不算多。我按实际生产经验挑几个重点说一下。

第一个是三个配比参数:cpu_allocation_ratio、ram_allocation_ratio、disk_allocation_ratio。它们决定Nova认为物理资源可以被超卖多少倍。比如ram_allocation_ratio=1.5,表示物理机有100G内存时,调度器认为可以卖出150G。超卖能提高资源利用率,但风险也很明显:峰值负载一来,宿主机可能直接内存不足。

第二个是reserved_host_memory_mb和reserved_host_cpus。这两个参数用来给宿主机系统自身预留资源,避免虚拟机和宿主机的系统进程抢内存和CPU。如果你发现宿主机总是内存告急,检查一下有没有预留足够的系统资源。

第三个是max_concurrent_live_migrations。热迁移是重负载操作,如果同时跑太多迁移任务,网络和磁盘IO都会被拖垮。给这个参数设置一个合理的并发上限,比把迁移请求全部放进去要稳得多。

第四个是allow_resize_same_host。这个参数控制resize时是否允许在同一宿主机上进行。开发测试环境可以开着,生产环境建议关掉,避免同一宿主机上规格调整引发资源竞争。

还有[libvirt]段里的cpu_mode,生产环境常用host-passthrough而不是host-model,因为host-passthrough让虚机直接使用宿主机的CPU指令集,性能和兼容性通常更好。不同硬件平台之间迁移时,要对CPU基线做额外规划,否则迁移过去虚机起不来,这个问题我踩过多次。

5.2 超卖、配比与资源碎片

聊Nova一定绕不开超卖。超卖是个双刃剑,设置合理能显著提高资源利用率,设置不合理就是事故温床。

CPU超卖相对宽容一些,因为虚机通常不会一直占满CPU核,场景合适的话配比可以设到2甚至更高。但内存超卖要非常谨慎。内存不像CPU那样可以分时复用,一旦虚机实际申请的内存超过物理可用内存,系统会触发OOM,严重时整台宿主机的虚机都会遭殃。

我的建议是,内存超卖比例宁低勿高,默认1.0到1.2之间比较稳妥。如果业务上有明确的内存超卖需求,应该通过主机聚合或者flavor约束,把超卖范围限制在特定资源池里,而不是全局放开。

资源碎片也是一个容易忽略的问题。假设一台宿主机剩余内存总共还有100G,但被拆成很多个4G、8G的小块,而用户要创建一台64G大规格的虚机,调度器算了半天发现没有连续资源可以满足,NoValidHost。这种情况光看总剩余量没用,要看内存碎片。运维上可以做两件事:一是对超大规格的flavor设置独立可用区,二是定期把碎片严重节点上的少量虚机迁移走,释放大块空间。

5.3 生产环境的部署形态建议

最后聊一聊生产环境里Nova比较推荐的部署形态。控制节点一般至少部署三副本,前面用负载均衡把流量分发给nova-api等一系列无状态服务。nova-conductor、nova-scheduler、Placement这些服务虽然是控制面,也可以多副本部署,但要注意它们有部分依赖数据库锁和消息队列,副本数不是越多越好,要根据并发量来定。

计算节点只跑nova-compute和配套的libvirtd,尽量不要和控制节点混布。原因很简单,计算节点更贴近业务负载,一旦被海量虚机打满CPU或磁盘IO,会拖垮控制面服务,导致整个集群几乎不可用。

存储架构上,如果规划了冷迁移和热迁移,建议使用共享存储。共享存储能让迁移过程只搬运内存状态和CPU状态,不用搬磁盘数据,速度和安全都更有保障。如果用的是本地存储,迁移就得同步磁盘数据,对网络和磁盘IO要求极高,生产环境压力大。

单元化扩展方面,Nova的cell v2机制值得重点了解。当一个集群的计算节点规模超过几百台,或者有地理上分离的资源池时,可以把计算节点划分到不同cell,每个cell有自己的数据库,控制面通过路由来连接不同cell。这种设计的初衷就是避免一个超大数据库成为性能瓶颈。

5.4 从小环境到生产,实践比命令更重要

如果你还在学习阶段,我强烈建议不要只用别人的一键部署脚本。自己在小环境里手动装一遍Nova,哪怕装得很痛苦,收获也很大。因为只有手动装过,你才会知道nova-api依赖哪些配置段、nova-compute为什么要连数据库、消息队列的exchange和queue是怎么被创建的。

学习排障的正确姿势,是主动制造故障。比如手动停掉nova-compute,看看创建虚机时会发生什么;手动把消息队列服务停掉,看看API会不会超时;手动改错Placement的库存数据,看看调度器会不会选错宿主机。这种“故意破坏”的练习,比看十篇排障文章都有用,能帮你真正建立对组件依赖关系的直觉。

最后再说一个运维习惯:写故障记录。每次排完一个Nova问题,把现象、排查路径、根因、解决方案写下来。几个月之后,你就拥有了一份专属于自己的实战手册,远比网上零散的帖子有价值。

以上是我对Nova组件的一些粗浅经验和踩坑总结,希望能给正在学习和运维OpenStack的朋友带来一点帮助。如果你也在生产环境里遇到过本文没提到的奇葩故障,不妨顺着消息队列和资源上报两条链路再挖一挖,很多时候答案就藏在你以为最不可能的那一步里。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询