searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

nova源代码阅读-nova组件概述

2023-05-23 04:28:40
172
0
       Nova是Openstack中的核心组件之一,主要负责与计算相关的服务,如对虚拟机的声明周期管理,因此,是针对虚拟机相关操作的一个组件。Nova可以管理虚拟机的计算、网络、存储等,只是对于不同的内容会调用相关组件进行管理,如虚拟机网络的管理,Nova实际上是调用了Neutron组件的相关接口进行网络的创建与关联。Nova本身并不会提供任何虚拟化的功能,它与Hypervisor交互都是通过第三方接口,如Libvirt API等,通过第三方接口,Nova可以实现支持多种虚拟化方式。

Nova基本组件

       Nova是由多个提供不同功能的独立组件组成,对外通过RESTful API进行通信,对内通过RPC进行通信,使用一个中心DB来存储数据。每个组件都可以部署一个或多个以实现横向扩展。Nova的基本架构如图所示,目前的Nova主要由API、Conductor、Scheduler、Compute四个核心组件组成,它们之间通过RPC进行通信。
       Nova-api:Nova对外提供的RESTful API服务,提供两种API服务,即nova-api-metadata及nova-api-os-compute,根据配置enable_apis选项来启动这两种服务。是Nova服务的入口,任何第三方组件发送来的请求,首先会到达API,然后由API转发给Nova内部的相应组件。API接收到请求后,依据请求是长时任务还是短时任务,将请求发送给Conductor或Compute。长时任务请求会被发送到Conductor,由Conductor负责对其全程跟踪和调度。短时任务,API通过消息队列告诉nova-compute执行相应的任务操作。
       Nova-Conductor:nova-conductor主要提供两个重要服务,首先,出于安全性和可扩展性的考虑,nova-compute不会直接访问数据库,而由nova-conductor为nova-compute提供数据库的代理访问机制,不仅是对数据库访问的一层安全保障,还在数据库升级过程中为旧的nova-compute节点提供了向下的兼容性;其次,nova-conductor连接了nova-api、nova-scheduler和nova-compute服务,Nova将所有耗时长、跨节点、易错但相对固定的处理流程抽象为任务,nova-conductor作为任务的组织者,不仅能对同时进行多个任务的状态进行跟踪,还能完成错误处理、恢复等一些列功能,例如,对于新建虚拟机或迁移类需要调度的请求,nova-conductor会向nova-scheduler请求一台符合要求的计算节点,随后,nova-conductor会把请求最终发送到合适的计算节点上。
       Nova-Scheduler:提供对计算资源的调度,提供了多种算法来应对不同场景下Nova对资源的调度,提供的算法与Scheduler都是松耦合,用户可以根据需要,定义自己的过滤算法。nova-scheduler在进行调度决策前需要从数据库中得到各个主机的资源数据,这些数据的收集与存储都由nova-compute负责。nova-compute对数据的更新会实时更新到数据库中,并有周期性任务保证资源数据的准确性。
       Nova-Compute:提供计算服务,是Nova中对虚拟机管理的核心服务,可以通过调用不同Hypervisor的API来完成对虚拟机生命周期的管理。nova-compute通过调用相应Hypervisor的接口,实现对虚拟机的创建、删除、挂起、迁移等操作。
       以创建虚拟机为例,首先用户执行Nova Client提供的用于创建虚拟机的命令,API服务监听到Nova Client发送的HTTP请求并将它转换成AMQP消息,然后通过消息队列(Queue)调用Conductor服务。在Conductor服务通过消息队列接收到任务之后,会进行一些准备工作(如汇总虚拟机参数等),再通过消息队列告诉Scheduler选择一个满足虚拟机创建要求的主机。Conductor在获知Scheduler提供的目标主机之后,会通过消息队列要求Compute服务创建虚拟机。Compute根据用户准备的各种参数,调用Hypervisor提供的API接口实现虚拟机的创建。

Nova代码结构

       接下来了解一下nova的代码结构,展示部分组要的目录结构,
.
├── etc   - Nova配置文件
├── nova
│   ├── api  - Nova API服务
│   │   ├── ec2
│   │   ├── metadata  - Metadata API
│   │   ├── openstack   - OpenStack API
│   │   └── validation   - 部分API的viewbuilder
│   ├── CA
│   ├── cmd    - 各个Nova服务的入口程序
│   ├── compute   - Nova Compute服务
│   ├── conductor  - Nova Conductor服务
│   ├── conf  - 所有的配置选项
│   ├── console   - nova-console服务
│   ├── consoleauth - nova-consoleauth服务
│   ├── db   - 数据库操作
│   ├── hacking  - 编码规范检查
│   ├── image  - Glance接口抽象
│   ├── ipv6   - IPv6工具函数
│   ├── keymgr
│   ├── locale  - 国际化相关文件
│   ├── network  - nova-network服务
│   ├── notifications
│   ├── objects   - Objects Module
│   ├── pci  - PCI/SR-IOV 支持
│   ├── policies  - 所有Policy的默认规则
│   ├── scheduler  - Nova Scheduler服务
│   ├── servicegroup
│   ├── tests  - 单元测试
│   ├── virt  - Hypervisor Driver
│   ├── volume - Cinder结构抽象
│   ├── wsgi
├── setup.cfg
├── setup.py
.....
└── tox.ini
       在阅读OpenStack代码时,首先查看文件名为setup.cfg的文件,作为OpenStack中的源码地址,setup.cfg文件是浏览OpenStack代码时最为依赖的文件,可以引导我们认识一个新的项目,并了解其代码的结构。entry_points作为setup.cfg文件中非常重要的一个section,通过对它的分析,可以相对容易找到所要研究代码的突破口。在每个setup.cfg文件的entry_points中,都会有一个相对比较特殊的组,或者说是命名空间console_scripts,其中的每一项都表示一个可执行的脚本,作为组件的入口:
console_scripts =
    nova-api = nova.cmd.api:main
    nova-api-metadata = nova.cmd.api_metadata:main
    nova-api-os-compute = nova.cmd.api_os_compute:main
    nova-compute = nova.cmd.compute:main
    nova-conductor = nova.cmd.conductor:main
    nova-console = nova.cmd.console:main
    nova-dhcpbridge = nova.cmd.dhcpbridge:main
    nova-manage = nova.cmd.manage:main
    nova-network = nova.cmd.network:main
    nova-novncproxy = nova.cmd.novncproxy:main
    nova-policy = nova.cmd.policy:main
    nova-rootwrap = oslo_rootwrap.cmd:main
    nova-rootwrap-daemon = oslo_rootwrap.cmd:daemon
    nova-scheduler = nova.cmd.scheduler:main
    nova-serialproxy = nova.cmd.serialproxy:main
    nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main
    nova-status = nova.cmd.status:main
    nova-xvpvncproxy = nova.cmd.xvpvncproxy:main
wsgi_scripts =
    nova-api-wsgi = nova.api.openstack.compute.wsgi:init_application
    nova-metadata-wsgi = nova.api.metadata.wsgi:init_application
       Nova各个服务之间的通信使用了基于AMQP实现的RPC机制,其中nova-conductor、nova-scheduler、nova-compute在启动时都会注册一个RPC Server,而nova-api因为内部并没有服务调用它提供的接口,所以无须注册。代码的目录结构类似,都含有api、rpcapi、manager模块,以nova-compute为例:
.
├── api.py
├── build_results.py
├── cells_api.py
├── claims.py
├── flavors.py
├── __init__.py
├── instance_actions.py
├── ironic_compute_rpc.py
├── manager.py
├── monitors
│   ├── base.py
│   ├── cpu
│   │   ├── __init__.py
│   │   └── virt_driver.py
│   └── __init__.py
├── power_state.py
├── resource_tracker.py
├── rpcapi.py
├── snapshot_states.py
├── stats.py
├── task_states.py
├── utils.py
└── vm_states.py
以虚拟机开机为例:
# nova/compute/rpcapi.py

@profiler.trace_cls("rpc")
class ComputeAPI(object):
    
    def start_instance(self, ctxt, instance):
    version = '5.0'
    cctxt = self.router.client(ctxt).prepare(
            server=_compute_host(None, instance), version=version)
    # RPC cast主要用于异步形式,如创建虚拟机,创建过程可能需要很长时间
    # 如果使用RPC call,则显然对性能有很大影响
    # cast()的第二个参数是RPC调用的函数名,后面的参数将作为参数被传入该函数        
    cctxt.cast(ctxt, 'start_instance', instance=instance)
      类nova.compute.rpcapi.ComputeAPI中的函数即为Compute服务提供给RPC调用的接口,其他服务在调用前需要先import这个模块,例如:
# nova/compute/api.py
from nova.compute import rpcapi as compute_rpcapi

class API(base.Base):
    """API for interacting with the compute manager."""

    def __init__(self, image_api=None, network_api=None, volume_api=None,
                 security_group_api=None, **kwargs):
        .....
        self.compute_rpcapi = compute_rpcapi.ComputeAPI()

@check_instance_state(vm_state=[vm_states.STOPPED])
def start(self, context, instance):
    """Start an instance."""
    LOG.debug("Going to try to start instance", instance=instance)

    instance.task_state = task_states.POWERING_ON
    instance.save(expected_task_state=[None])

    self._record_action_start(context, instance, instance_actions.START)
    # 调用类nova.compute.rpcapi.ComputeAPI中的接口
    self.compute_rpcapi.start_instance(context, instance)
       nova.compute.rpcapi.ComputeAPI只是暴露给其他服务的RPC调用接口,Compute服务的RPC Server在接收到RPC请求后,真正完成任务的是nova.compute.manager模块。例如:
# nova/compute/manager.py

class ComputeManager(manager.Manager):
    """Manages the running instances from creation to destruction."""

    target = messaging.Target(version='5.3')
    
    def start_instance(self, context, instance):
    """Starting an instance on this host."""
    ......
       从nova.compute.rpcapi.ComputeAPI到nova.compute.manager.ComputeManger的过程就是RPC调用的过程。
       以上主要是对Nova的主要服务和代码结果进行讲解,从整体上对Nova有个清晰的把握,通过一个简单的例子说明Nova内部的通信机制,接下来将对Nova的nova-api、nova-conductor、nova-scheduler、nova-compute服务功能进行详细介绍和代码分析。
0条评论
0 / 1000
罗****兵
3文章数
1粉丝数
罗****兵
3 文章 | 1 粉丝
罗****兵
3文章数
1粉丝数
罗****兵
3 文章 | 1 粉丝
原创

nova源代码阅读-nova组件概述

2023-05-23 04:28:40
172
0
       Nova是Openstack中的核心组件之一,主要负责与计算相关的服务,如对虚拟机的声明周期管理,因此,是针对虚拟机相关操作的一个组件。Nova可以管理虚拟机的计算、网络、存储等,只是对于不同的内容会调用相关组件进行管理,如虚拟机网络的管理,Nova实际上是调用了Neutron组件的相关接口进行网络的创建与关联。Nova本身并不会提供任何虚拟化的功能,它与Hypervisor交互都是通过第三方接口,如Libvirt API等,通过第三方接口,Nova可以实现支持多种虚拟化方式。

Nova基本组件

       Nova是由多个提供不同功能的独立组件组成,对外通过RESTful API进行通信,对内通过RPC进行通信,使用一个中心DB来存储数据。每个组件都可以部署一个或多个以实现横向扩展。Nova的基本架构如图所示,目前的Nova主要由API、Conductor、Scheduler、Compute四个核心组件组成,它们之间通过RPC进行通信。
       Nova-api:Nova对外提供的RESTful API服务,提供两种API服务,即nova-api-metadata及nova-api-os-compute,根据配置enable_apis选项来启动这两种服务。是Nova服务的入口,任何第三方组件发送来的请求,首先会到达API,然后由API转发给Nova内部的相应组件。API接收到请求后,依据请求是长时任务还是短时任务,将请求发送给Conductor或Compute。长时任务请求会被发送到Conductor,由Conductor负责对其全程跟踪和调度。短时任务,API通过消息队列告诉nova-compute执行相应的任务操作。
       Nova-Conductor:nova-conductor主要提供两个重要服务,首先,出于安全性和可扩展性的考虑,nova-compute不会直接访问数据库,而由nova-conductor为nova-compute提供数据库的代理访问机制,不仅是对数据库访问的一层安全保障,还在数据库升级过程中为旧的nova-compute节点提供了向下的兼容性;其次,nova-conductor连接了nova-api、nova-scheduler和nova-compute服务,Nova将所有耗时长、跨节点、易错但相对固定的处理流程抽象为任务,nova-conductor作为任务的组织者,不仅能对同时进行多个任务的状态进行跟踪,还能完成错误处理、恢复等一些列功能,例如,对于新建虚拟机或迁移类需要调度的请求,nova-conductor会向nova-scheduler请求一台符合要求的计算节点,随后,nova-conductor会把请求最终发送到合适的计算节点上。
       Nova-Scheduler:提供对计算资源的调度,提供了多种算法来应对不同场景下Nova对资源的调度,提供的算法与Scheduler都是松耦合,用户可以根据需要,定义自己的过滤算法。nova-scheduler在进行调度决策前需要从数据库中得到各个主机的资源数据,这些数据的收集与存储都由nova-compute负责。nova-compute对数据的更新会实时更新到数据库中,并有周期性任务保证资源数据的准确性。
       Nova-Compute:提供计算服务,是Nova中对虚拟机管理的核心服务,可以通过调用不同Hypervisor的API来完成对虚拟机生命周期的管理。nova-compute通过调用相应Hypervisor的接口,实现对虚拟机的创建、删除、挂起、迁移等操作。
       以创建虚拟机为例,首先用户执行Nova Client提供的用于创建虚拟机的命令,API服务监听到Nova Client发送的HTTP请求并将它转换成AMQP消息,然后通过消息队列(Queue)调用Conductor服务。在Conductor服务通过消息队列接收到任务之后,会进行一些准备工作(如汇总虚拟机参数等),再通过消息队列告诉Scheduler选择一个满足虚拟机创建要求的主机。Conductor在获知Scheduler提供的目标主机之后,会通过消息队列要求Compute服务创建虚拟机。Compute根据用户准备的各种参数,调用Hypervisor提供的API接口实现虚拟机的创建。

Nova代码结构

       接下来了解一下nova的代码结构,展示部分组要的目录结构,
.
├── etc   - Nova配置文件
├── nova
│   ├── api  - Nova API服务
│   │   ├── ec2
│   │   ├── metadata  - Metadata API
│   │   ├── openstack   - OpenStack API
│   │   └── validation   - 部分API的viewbuilder
│   ├── CA
│   ├── cmd    - 各个Nova服务的入口程序
│   ├── compute   - Nova Compute服务
│   ├── conductor  - Nova Conductor服务
│   ├── conf  - 所有的配置选项
│   ├── console   - nova-console服务
│   ├── consoleauth - nova-consoleauth服务
│   ├── db   - 数据库操作
│   ├── hacking  - 编码规范检查
│   ├── image  - Glance接口抽象
│   ├── ipv6   - IPv6工具函数
│   ├── keymgr
│   ├── locale  - 国际化相关文件
│   ├── network  - nova-network服务
│   ├── notifications
│   ├── objects   - Objects Module
│   ├── pci  - PCI/SR-IOV 支持
│   ├── policies  - 所有Policy的默认规则
│   ├── scheduler  - Nova Scheduler服务
│   ├── servicegroup
│   ├── tests  - 单元测试
│   ├── virt  - Hypervisor Driver
│   ├── volume - Cinder结构抽象
│   ├── wsgi
├── setup.cfg
├── setup.py
.....
└── tox.ini
       在阅读OpenStack代码时,首先查看文件名为setup.cfg的文件,作为OpenStack中的源码地址,setup.cfg文件是浏览OpenStack代码时最为依赖的文件,可以引导我们认识一个新的项目,并了解其代码的结构。entry_points作为setup.cfg文件中非常重要的一个section,通过对它的分析,可以相对容易找到所要研究代码的突破口。在每个setup.cfg文件的entry_points中,都会有一个相对比较特殊的组,或者说是命名空间console_scripts,其中的每一项都表示一个可执行的脚本,作为组件的入口:
console_scripts =
    nova-api = nova.cmd.api:main
    nova-api-metadata = nova.cmd.api_metadata:main
    nova-api-os-compute = nova.cmd.api_os_compute:main
    nova-compute = nova.cmd.compute:main
    nova-conductor = nova.cmd.conductor:main
    nova-console = nova.cmd.console:main
    nova-dhcpbridge = nova.cmd.dhcpbridge:main
    nova-manage = nova.cmd.manage:main
    nova-network = nova.cmd.network:main
    nova-novncproxy = nova.cmd.novncproxy:main
    nova-policy = nova.cmd.policy:main
    nova-rootwrap = oslo_rootwrap.cmd:main
    nova-rootwrap-daemon = oslo_rootwrap.cmd:daemon
    nova-scheduler = nova.cmd.scheduler:main
    nova-serialproxy = nova.cmd.serialproxy:main
    nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main
    nova-status = nova.cmd.status:main
    nova-xvpvncproxy = nova.cmd.xvpvncproxy:main
wsgi_scripts =
    nova-api-wsgi = nova.api.openstack.compute.wsgi:init_application
    nova-metadata-wsgi = nova.api.metadata.wsgi:init_application
       Nova各个服务之间的通信使用了基于AMQP实现的RPC机制,其中nova-conductor、nova-scheduler、nova-compute在启动时都会注册一个RPC Server,而nova-api因为内部并没有服务调用它提供的接口,所以无须注册。代码的目录结构类似,都含有api、rpcapi、manager模块,以nova-compute为例:
.
├── api.py
├── build_results.py
├── cells_api.py
├── claims.py
├── flavors.py
├── __init__.py
├── instance_actions.py
├── ironic_compute_rpc.py
├── manager.py
├── monitors
│   ├── base.py
│   ├── cpu
│   │   ├── __init__.py
│   │   └── virt_driver.py
│   └── __init__.py
├── power_state.py
├── resource_tracker.py
├── rpcapi.py
├── snapshot_states.py
├── stats.py
├── task_states.py
├── utils.py
└── vm_states.py
以虚拟机开机为例:
# nova/compute/rpcapi.py

@profiler.trace_cls("rpc")
class ComputeAPI(object):
    
    def start_instance(self, ctxt, instance):
    version = '5.0'
    cctxt = self.router.client(ctxt).prepare(
            server=_compute_host(None, instance), version=version)
    # RPC cast主要用于异步形式,如创建虚拟机,创建过程可能需要很长时间
    # 如果使用RPC call,则显然对性能有很大影响
    # cast()的第二个参数是RPC调用的函数名,后面的参数将作为参数被传入该函数        
    cctxt.cast(ctxt, 'start_instance', instance=instance)
      类nova.compute.rpcapi.ComputeAPI中的函数即为Compute服务提供给RPC调用的接口,其他服务在调用前需要先import这个模块,例如:
# nova/compute/api.py
from nova.compute import rpcapi as compute_rpcapi

class API(base.Base):
    """API for interacting with the compute manager."""

    def __init__(self, image_api=None, network_api=None, volume_api=None,
                 security_group_api=None, **kwargs):
        .....
        self.compute_rpcapi = compute_rpcapi.ComputeAPI()

@check_instance_state(vm_state=[vm_states.STOPPED])
def start(self, context, instance):
    """Start an instance."""
    LOG.debug("Going to try to start instance", instance=instance)

    instance.task_state = task_states.POWERING_ON
    instance.save(expected_task_state=[None])

    self._record_action_start(context, instance, instance_actions.START)
    # 调用类nova.compute.rpcapi.ComputeAPI中的接口
    self.compute_rpcapi.start_instance(context, instance)
       nova.compute.rpcapi.ComputeAPI只是暴露给其他服务的RPC调用接口,Compute服务的RPC Server在接收到RPC请求后,真正完成任务的是nova.compute.manager模块。例如:
# nova/compute/manager.py

class ComputeManager(manager.Manager):
    """Manages the running instances from creation to destruction."""

    target = messaging.Target(version='5.3')
    
    def start_instance(self, context, instance):
    """Starting an instance on this host."""
    ......
       从nova.compute.rpcapi.ComputeAPI到nova.compute.manager.ComputeManger的过程就是RPC调用的过程。
       以上主要是对Nova的主要服务和代码结果进行讲解,从整体上对Nova有个清晰的把握,通过一个简单的例子说明Nova内部的通信机制,接下来将对Nova的nova-api、nova-conductor、nova-scheduler、nova-compute服务功能进行详细介绍和代码分析。
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0