分享

一个OpenStack访问请求在各组件之间的调用过程解析


问题导读

1.松耦合架构的好处是什么?
2.OpenStack的各个服务之间如何实现松耦合的?
3.nova-client是否可以向cinder,neutron发送请求?
4.如何调试nova-client ?







OpenStack 各个组件之间的关系
OpenStack 是一整套资源管理软件的集合,也是当前最热的开源虚拟化管理软件之一,有一个全球139个国家将近两万开发者参与的开源社区(www.openstack.org)作为支持。OpenStack项目的目的是快速建设一个稳定可靠的公有云或私有云系统。整个项目涵盖了计算,存储,网络以及前端展现等关于云管理的全部方面,包含了众多子项目,其中主要的子项目有:
  • OpenStack Compute (code-name Nova) 计算服务
  • OpenStack Networking (code-name Neutron) 网络服务
  • OpenStack Object Storage (code-name Swift) 对象存储服务
  • OpenStack Block Storage (code-name Cinder) 块设备存储服务
  • OpenStack Identity (code-name Keystone) 认证服务
  • OpenStack Image Service (code-name Glance) 镜像文件服务
  • OpenStack Dashboard (code-name Horizon) 仪表盘服务
  • OpenStack Telemetry (code-name Ceilometer) 告警服务
  • OpenStack Orchestration (code-name Heat) 流程服务
  • OpenStack Database (code-name Trove) 数据库服务

OpenStack的各个服务之间通过统一的REST风格的API调用,实现系统的松耦合。下图是OpenStack各个服务之间API调用的概览,其中实线代表client 的API调用,虚线代表各个组件之间通过rpc 调用进行通信。松耦合架构的好处是,各个组件的开发人员可以只关注各自的领域,对各自领域的修改不会影响到其他开发人员。不过从另一方面来讲,这种松耦合的架构也给整个系统的维护带来了一定的困难,运维人员要掌握更多的系统相关的知识去调试出了问题的组件。所以无论对于开发还是维护人员,搞清楚各个组件之间的相互调用关系是怎样的都是非常必要的。


1.jpg



从nova-client入手
nova-client是一个命令行的客户端应用,终端用户可以从nova-client发起一个api请求到nova-api,nova-api服务会转发该请求到相应的组件上。同时,nova-api支持对cinder、neutron的请求转发,也就是你可以在nova-client直接向cinder,neutron发送请求。

我们可以在调用nova-client 增加--debug选项打印更多的debug消息,通过这些debug信息可以了解到如果我们需要发起一个完整的业务层面上请求,都需要跟那些服务打交道。

以 boot 一个新实例为例子,以下是执行代码以及debug输出:
  1. [tagett@stack-01 devstack]$ nova --debug boot t3 --flavor m1.nano --image  
  2. 44c37b90-0ec3-460a-bdf2-bd8bb98c9fdf --nic net-id=b745b2c6-db16-40ab-8ad7-af6da0e5e699
  3. REQ: curl -i 'http://cloudcontroller:5000/v2.0/tokens'
  4. REQ: curl -i 'http://cloudcontroller:8774/v2/d7beb7f28e0b4f41901215000339361d/images/44c37b90-0ec3-460a-bdf2-bd8bb98c9fdf'
  5. REQ: curl -i 'http://cloudcontroller:8774/v2/d7beb7f28e0b4f41901215000339361d/flavors/m1.nano'
  6. REQ: curl -i 'http://cloudcontroller:8774/v2/d7beb7f28e0b4f41901215000339361d/servers' -X POST
  7. -H "Accept: application/json" -H "Content-Type: application/json" -H "User-Agent:
  8. python-novaclient" -H "X-Auth-Project-Id: admin" -H "X-Auth-Token:
  9. {SHA1}15d9e554b7456f1043732bb8df72d1521c5f6aa1" -d '{"server":
  10. {"name": "t3", "imageRef": "44c37b90-0ec3-460a-bdf2-bd8bb98c9fdf",
  11. "flavorRef": "42", "max_count": 1, "min_count":
  12. 1, "networks": [{"uuid": "b745b2c6-db16-40ab-8ad7-af6da0e5e699"}]}}'
复制代码
从以上debug输出我们可以清楚看到,执行一个boot新实例的操作需要发送如下几个api请求:
  • 向keystone发送请求,获取租户(d7beb7f28e0b4f41901215000339361d)的认证token
  • 通过拿到的token,向nova-api服务发送请求,验证image是否存在
  • 通过拿到的token,向nova-api服务发送请求,验证创建的favor是否存在
  • 请求创健一个新的instance,需要的元数据信息通过包含在请求body中
nova-client帮我们把需要的全部请求放到一起,而最重要的就是4。如果用户想自己通过rest api 直接发送http请求的话,可以直接使用4,当然,前提是先通过调用keystone服务得到认证token。
下面结合代码重点叙述一下4的请求数据流动在整个stack中的过程。


2.png


图1创建新实例时的请求在OpenStack中各组件之间的调用
上图是一个全局的流程图,图中每个服务是一个单独的进程实例,他们之间通过rpc调用(广播或者调用)另一个服务。nova-api服务是一个wsgi服务实例,创建新instance的入口代码是在nova /api/openstack/compute/servers.py,处理函数为:
  1. def create(self, req, body):
  2.     """Creates a new server for a given user."""
  3. …   
  4. (instances, resv_id) = self.compute_api.create(context,...
复制代码
做一些参数验证之后,调用compute api的create 函数(代码在nova/compute/api.py中):
  1. @hooks.add_hook("create_instance")
  2. def create(self, context, instance_type,
  3. ...
  4.         return self._create_instance(...
复制代码
创建instance对象实例,_create_instance会调用compute_task api 的build_instances 方法对刚创建的instances实例进行构建:
  1. self.compute_task_api.build_instances(context, ...
复制代码
compute_task api是一个nova-conductor 服务的rpc api请求,处理代码在nova/conductor/manager.py中:
  1. def build_instances(self, context, instances, image, filter_properties,
  2. ...
  3.        hosts = self.scheduler_rpcapi.select_destinations(context,
  4. ...
  5.        self.compute_rpcapi.build_and_run_instance(context, ...
复制代码
它做了两件事情:调用scheduler的rpc api选择在那些主机上创建新实例,并最终通过rpc请求nova-compute 服务去构建和运行新实例。
处理函数在nova/compute/manager.py中:
  1. def build_and_run_instance(self, context, instance, image, request_spec,
  2.                  filter_properties, admin_password=None,
  3.                  injected_files=None, requested_networks=None,
  4.                  security_groups=None, block_device_mapping=None,
  5.                  node=None, limits=None):
复制代码

最终调用配置文件中配置的hypervisor类型进行虚拟机的创建和运行,一个实例就这样构建好了。
以下是上面涉及到的服务的主要功能:
  • nova-api:接受http请求,并响应请求,当然还包括请求信息的验证
  • nova-conductor:与数据库交互,提高对数据库访问的安全性
  • nova-scheduler:调度服务,决定最终实例要在哪个服务上创建。迁移,重建等都需要通过这个服务
  • nova-compute:调用虚拟机管理程序,完成虚拟机的创建和运行以及控制
以上基本包含nova项目的全部服务,但一个请求有的时候并不需要经过全部的服务。继续看shelve一个实例的过程。

  1. [tagett@stack-01 devstack]$ nova --debug shelve t2
  2. REQ: curl -i 'http://cloudcontroller:5000/v2.0/tokens' …
  3. REQ: curl -i 'http://cloudcontroller:8774/v2/d7beb7f28e0b4f41901215000339361d/servers'…
  4. REQ: curl -i 'http://cloudcontroller:8774/v2/d7beb7f28e0b4f41901215000339361d/servers/r'…
  5. REQ: curl -i 'http://cloudcontroller:8774/v2/d7beb7f28e0b4f41901215000339361d/servers/
  6. 00be783d-bef5-46b1-bfdc-316618c76e92/action'
  7. -X POST -H "Accept: application/json" -H "Content-Type: application/json"
  8. -H "User-Agent: python-novaclient" -H "X-Auth-Project-Id: admin"
  9. -H "X-Auth-Token: {SHA1}0634ea0ef1c3994e1f496c5d8890d32610cf11e9"
  10. -d '{"shelve": null}'…
复制代码
  • 向keystone发送请求,获取租户(d7beb7f28e0b4f41901215000339361d)的认证token
  • 通过拿到的token,向nova-api服务发送请求,显示该租户的全部服务实例
  • 通过拿到的token,向nova-api服务发送请求,查询准备shelve的实例uuid的详细信息
  • 请求一个server操作action,执行shelve操作(request body为‘{“shelve”: null}’)
nova-api返回http 202,成功接受请求,转为后台进行异步执行。



已有(1)人评论

跳转到指定楼层
Redgo 发表于 2015-3-30 08:51:39
好复杂,看不懂~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条