OpenStack Nova核心组件和RabbitMQ通信流程分析

Ø

前言

云计算从资源提供类型可以分为IaaS(基础设施即服务)、PaaS(平台即服务)和SaaS(软件即服务)三层。IaaS和PaaS相辅相成,目前云计算商业领域的各大公有云厂商一般都会提供IaaS和PaaS层的资源和服务,比如AWS、Azure、GCP(GoogleCloud Platform)、IBM Cloud、阿里云、腾讯云、百度云、金山云、华为云等。IaaS厂商一般提供计算、存储和网络等基础资源,PaaS厂商一般面向开发者提供中间件、容器编排、应用部署等资源服务。在开源领域,IaaS层的代表为OpenStack和CloudStack,PaaS层的代表为Kubernetes、OpenShift和Cloud Foundry。下面以IaaS 层开源框架OpenStack计算模块Nova为例分析各组件的通信流程。

Ø

OpenStack Nova架构

OpenStack Nova是计算模块,负责管理虚拟机的生命周期。Nova主要由nova-api、nova-cell、nova-conductor、nova-scheduler和nova-compute等组件组成。通常生产环境会把Nova划分为控制节点和计算节点两种节点来部署,控制节点上主要运行nova-api、nova-conductor、nova-scheduler服务,计算节点上主要运行nova-compute和hypervisor服务。其中,nova-api主要对外提供restful API服务;nova-cell主要是用来解决横向扩展集群规模带来的RabbitMq和MariaDB瓶颈问题;nova-conductor是nova的中枢神经,直接操作数据库;nova-scheduler是nova创建虚拟机的调度器,;nova-compute是创建管理虚拟机生命周期的真正组件,直接调用hypervisor;DB模块一般采用MariaDB集群,存储nova生命周期的所有持久化信息;hypervisor支持KVM、Xen、Hyper-v、LXC等虚拟化技术,是管理虚拟机的最终组件。上述Nova各组件是通过RabbitMQ消息队列通信的,RabbitMQ可以使各组件模块相互解耦、任务异步、并且可以起到流量削峰的作用。Nova架构如下图所示:

OpenStack Nova核心组件和RabbitMQ通信流程分析

Ø

Nova创建虚拟机的消息流程

Nova创建虚拟机流程如下图所示:

OpenStack Nova核心组件和RabbitMQ通信流程分析

创建步骤如下:

(1)nova-api接收到前端创建虚拟机的命令,把命令发送到conductor队列。

(2)nova-conductor监听到conductor队列的消息,从conductor队列获取创建虚拟机的消息。然后nova-conductor在数据库中插入要创建虚拟机的初始信息,最后发送创建虚拟机的消息到scheduler队列。该消息带有msg_id和reply_….队列,其中,msg_id表示消息的唯一标识,reply_…..队列表示下一个接收到该消息的守护进程处理完该消息后需要返回处理结果到reply_…..队列。(3)nova-scheduler监听到scheduler队列的消息,从scheduler队列获取创建虚拟机的消息。然后nova-scheduler通过filter和weight选出创建虚拟机的目标主机,然后把目标主机作为返回结果信息返回到reply_afb1…..aa77队列。最后nova-conductor根据msg_id从reply_afb1…..aa77队列中获取目标主机结果。

(4)nova-conductor发送带有目标主机的创建虚拟机的命令到compute队列。该消息带有msg_id和reply_….队列,其中,msg_id表示消息的唯一标识,reply_…..队列表示下一个接收到该消息的守护进程处理完该消息后需要返回处理结果到reply_…..队列。

(5)nova-compute监听到compute队列的消息,从compute队列获取创建虚拟机的消息。然后调用底层虚拟化接口创建好虚拟机,然后把创建好的虚拟机的详细信息作为返回结果返回到reply_2148…..89c8队列。最后nova-conductor根据msg_id从reply_2148…..89c8队列获取到创建好的虚拟机的信息,并更新数据库的虚拟机信息。

Ø 计算节点nova-compute上报心跳的消息流程

在OpenStack集群中,如何判断计算节点是否存活?需要依赖nova-compute 向nova-conductor定时上报计算节点的心跳状态,默认report_interval=10表示nova-compute服务每隔10S向conductor队列上报一次计算节点的状态信息;

service_down_time=60表示nova-conductor服务距离上次核对计算节点状态时间间隔大于60S后,还没有接受到计算机点的下一条上报信息,nova-conductor服务会自动把该计算节点在数据库的状态设置为down。如下图所示:

OpenStack Nova核心组件和RabbitMQ通信流程分析

详细步骤如下:

nova-compute每间隔10S上报一次计算节点的状态信息到conductor队列,nova-conductor服务从conductor队列获取计算机点的状态msg。

(1)如果距离上次核对的间隔时间大于60s后,还没有获取到计算机点的状态msg,nova-conductor服务会自动把该计算节点在数据库的状态设置为down,然后把处理后的返回信息发送到reply_a7281595277a443cbb7f427e55ee4515队列。nova-compute服务从返回队列reply_a7281595277a443cbb7f427e55ee4515里获取返回的信息。

(2)如果获取到计算机点的状态msg距离上次核对的间隔时间小于60s,nova-conductor服务会把该msg中的计算节点的up状态信息更新到数据库,然后把处理后的返回信息发送到reply_a7281595277a443cbb7f427e55ee4515队列。nova-compute服务从返回队列reply_a7281595277a443cbb7f427e55ee4515里获取返回的信息。

Ø

总结

任何事物都具有两面性,OpenStack的每个模块的内部组件交互全部依赖RabbitMQ。

一方面引入RabbitMQ可以起到使各模块解耦、耗时任务异步化和流量削峰的作用。但是RabbitMQ也有可能会成为整个OpenStack平台的瓶颈,如果没有合理规划RabbitMQ集群且无较强的技术能力驾驭,当OpenStack集群规模扩大后,会产生很多莫名其妙的异常情况。

但也不是没有可能解决上述问题,一般可以从两方面入手来规避上述弊端:

(1)在OpenStack大集群内划分若干个小范围的RabbitMQ集群,减轻单个消息队列负载并分摊风险;

(2)熟悉OpenStack各组件调用RabbitMQ的流程,找出瓶颈(大概率都是timeout原因)优化OpenStack和RabbitMQ的配置文件;

默认的OpenStack支持百来台小规模节点的私有云集群是不成任何问题,但是想要支持几千台甚至上万台的超大集群规模,除了上述RabbitMQ瓶颈的两点优化外,还需要从网络和存储层面对OpenStack的架构做手术。国内只有为数不多的以OpenStack为基础进行二次开发并对外提供公有云服务的大厂,才有财力、能力和魄力来对OpenStack“大动干戈”。

作者:杨武 新钛云服研发总监

十年云研发和架构经验,中国科学技术大学软件工程全日制硕士研究生学历。曾在IBM、土豆网、微烛云先后担任云计算研发工程师、架构师,技术总监等职务,参与并主导过产品设计、研发、测试和运维(DevOps)等完整产品生命周期流程,有上万台物理服务器规模的OpenStack集群架构实战经验,对云平台的瓶颈和性能优化有丰富经验。精通OpenStack、CloudForms、Kubernetes、Ceph、KVM、Docker、Solaris(SmartOS)等云平台及虚拟化技术。

标签: