标签: openstack nova 源码阅读

在openstack中,虚拟机的创建无疑是非常重要的,了解虚拟机创建流程并阅读nova模块关于创建虚拟机的源码对opensatck开发有很很大帮助,本篇文章将以openstack queens版本为基础.讲解创建虚拟机的源码.由于nova模块代码复杂,而且阅读源码所需知识较多,所以侧重于流程逻辑,源码阅读可能不够详尽指出.

nova模块结构

DB: 用于存储nova服务相关数据的SQL数据库,通常为MySQL

API:接收HTTP请求的组件,处理请求并通过oslo.messaging队列或HTTP与其他组件通信

Scheduler: 决定虚拟机在哪个主机运行

Network: 管理IP转发,桥接和vlans

Compute: 管理虚拟机和虚拟机管理器直接的通信

Conductor: 处理需要协同的请求(创建/重建),作为数据库代理,或者处理对象转换

创建虚拟机流程

为了简便,这里省略了认证过程,实际上一个请求发送过来,还要经过认证和鉴权等过程,确保该用户有权限创建虚拟机.

在openstack的wiki中给出创建一个虚拟的workflow,图有点大,但对于每个组件的工作内容写的非常详细

我们可以把创建流程分成几个部分

处理请求

用户发送一个创建虚拟机的请求,Nova-Api接收到请求后,Nova-Api负责激活扩展插件,检查虚拟机名称,接收注入文件,提取新虚拟机的网络设置,检查配置和镜像等工作.

然后Nova-Api将处理好的参数集以JSON文件通过HTTP请求发送给Nova的Compute-Api.然后向用户发送带有虚拟机预留ID的相应(这时的相应码202,提示虚拟机创建成功,但实际上虚拟机还未真正创建成功)

Compute-Api在接收到请求后将会检查创建政策,进一步检查虚拟机,网络,镜像和配额,然后正式建立虚拟机的配置.

接着在数据库中生成虚拟机的相应记录,而后通过消息队列发送请求让scheduler选择一个host来创建虚拟机.

虚拟机调度和资源准备

scheduler接收到消息后根据消息中filters对所有host进行过滤,最后选出某个host,然后跟新数据库,并通过消息队列向被选定的host发送创建虚拟机消息

被选定的host接收到队列的消息后在数据库中更新虚拟机和任务的状态,然后通过nova network-api为虚拟机创建或获取网络.

接着通过nova volume-api为虚拟机创建新的卷,决定虚拟机的块设备映射,并将卷挂载到虚拟机上

此时虚拟机的调度和资源准备都以完成.

在hypervisor上运行虚拟机

被选定的host获取镜像,建立块设备映射,最后生成libvirt.xml最后执行hypervisor的spawn()方法,至此,虚拟机已经在host上运行了.最后一步是跟新虚拟机和任务的状态.

源码阅读

下面将根据虚拟机创建时调用的模块顺序阅读代码

Nova-Api

Nova-Api将处理不同类型的请求写成了各种controler类,而处理创建虚拟机的类被称为ServerControler

# nova/api/openstack/compute/servers.py

class ServersController(wsgi.Controller):

# 为了简明,省略了很多用于检查的装饰器

@wsgi.response(202)

def create(self, req, body):

"""Creates a new server for a given user."""

context = req.environ['nova.context']

server_dict = body['server']

password = self._get_server_admin_password(server_dict)

name = common.normalize_name(server_dict['name'])

description = name

# create方法干的是些从请求中提取并检查参数的脏活

# 省略...

try:

# 依然是构建参数的代码...

# 调用compute_api创建虚拟机

(instances, resv_id) = self.compute_api.create(context,

inst_type,

image_uuid,

display_name=name,

display_description=description,

availability_zone=availability_zone,

forced_host=host, forced_node=node,

metadata=server_dict.get('metadata', {}),

admin_password=password,

requested_networks=requested_networks,

check_server_group_quota=True,

supports_multiattach=supports_multiattach,

**create_kwargs)

# 错误处理...

compute-api

# nova/compute/api.py

class API(base.Base):

def create(self, context, instance_type,

image_href, kernel_id=None, ramdisk_id=None,

min_count=None, max_count=None,

display_name=None, display_description=None,

key_name=None, key_data=None, security_groups=None,

availability_zone=None, forced_host=None, forced_node=None,

user_data=None, metadata=None, injected_files=None,

admin_password=None, block_device_mapping=None,

access_ip_v4=None, access_ip_v6=None, requested_networks=None,

config_drive=None, auto_disk_config=None, scheduler_hints=None,

legacy_bdm=True, shutdown_terminate=False,

check_server_group_quota=False, tags=None,

supports_multiattach=False):

"""准备实例创建工作,然后将实例信息发送至scheduler,

由scheduler计算host上创建和在DB创建记录。

"""

# preparation

# 为了简介,所有参数简略为args和kwargs

self_create_instance(*args, **kwargs)

def _create_instance(self, context, instance_type,

image_href, kernel_id, ramdisk_id,

min_count, max_count,

display_name, display_description,

key_name, key_data, security_groups,

availability_zone, user_data, metadata, injected_files,

admin_password, access_ip_v4, access_ip_v6,

requested_networks, config_drive,

block_device_mapping, auto_disk_config, filter_properties,

reservation_id=None, legacy_bdm=True, shutdown_terminate=False,

check_server_group_quota=False, tags=None,

supports_multiattach=False):

"""核查所有参数"""

# verifying

pass

# 获取镜像信息

if image_href:

# if image_href is provied, get image via glance api

image_id, boot_meta = self._get_image(context, image_href)

else:

# if image_href is not proved, get image metadata from bdm

image_id = None

boot_meta = self._get_bdm_image_metadata(

context, block_device_mapping, legacy_bdm)

# 继续检查参数

# 由于block device mapping有两种版本,为了兼容,需要检查并在必要时转换

block_device_mapping = self._check_and_transform_bdm(context,

base_options, instance_type, boot_meta, min_count, max_count,

block_device_mapping, legacy_bdm)

# go on checking

# 为了支持cell特性,参见cell wiki

# https://docs.openstack.org/nova/ocata/cells.html

if CONF.cells.enable:

# 创建instance模型对象

# 检查quota

# 调用rpc api将消息发送到队列

self.compute_task_api.build_instance(*args, **kwargs)

else:

compute_task_api.schedule_and_build_instances(*args, **kwargs)

return instances, reservation_id

调度和消息传递代码

nova组件之间可以通过rpc api以消息队列通信,而最后的真正执行的任务的类都在manager.py文件中定义.这里我们方便理解省略调度代码

# nova/conductor/api.py

class ComputeTaskAPI(object):

def schedule_and_build_instance(self, *args, **kwargs):

# very simple method

# call rpc api only

self.conductor_compute_rpc_api.schedule_and_build_instance(*args, **kwargs)

# nova/conductor/rpcapi.py

class ComputeTaskAPI(object):

def schedule_and_build_instance(self, *args, **kwargs):

# 构建参数和api版本检查

# 最后将其发送到消息队列

cctxt.cast(context, 'schedule_and_build_instance', **kwargs)

manager代码

# nova/compute/manager.py

class ComputeManager(object):

@wrap_exception()

@reverts_task_state

@wrap_instance_fault

def build_and_run_instance(self, *args, **kwargs):

# 给资源加锁,避免竞争

@utils.synchronized(instance.uuid)

def _locked_do_build_and_run_instance(*args, **kwargs):

with self._build_semaphore:

try:

result = self._do_build_and_run_instance(*args, **kwargs)

# handle exceptions

pass

# 由于创建虚拟机的工作可能会持续很长时间,为了避免进程阻塞

# 将这个任务分发给某个worker

utils.spawn_n(_locked_do_build_and_run_instance,

context, instance, ...)

def _do_build_and_run_instance(self, *args, **kwargs):

# 更新虚拟机和任务状态

# 解码注入文件

try:

with timeutils.StopWatch() as timer:

self._build_and_run_instance(*args)

# handle exceptions

def _build_and_run_instance(self, *args, **kwargs):

# 获取 image ref

try:

scheduler_hints = self._get_scheduler_hints(filter_properties, request_spec)

rt = self._get_resource_tracker()

with rt.instance_claime(context, instance, node, limits):

# 获取群组策略和镜像metadata

# 通过调用_build_resources创建network和volume

with self._build_resources(*args) as resources:

# handle vm and task state

# spawn instance on hypervisor

with timeuitls.StopWatch() as time:

# 通过driver创建xml,然后真正运行虚拟机

self.driver.spawn(*args, **kwargs)

# handle exceptions

openstack源码架构_openstack创建虚拟机源码阅读相关推荐

  1. nova创建虚拟机源码分析系列之六 api入口create方法

    openstack 版本:Newton 注:博文图片采用了很多大牛博客图片,仅作为总结学习,非商用. 该图全面的说明了nova创建虚机的过程,从逻辑的角度清晰的描述了前端请求创建虚拟机之后发生的一系列 ...

  2. 微信创建二维码_如何创建二维码

    微信创建二维码 QR codes aren't everyone's cup of tea but I quite like them. If I see something I want to re ...

  3. Openstack Liberty 版本原生环境创建虚拟机BDM参数组合规范

    声明: 本博客欢迎转发,但请保留原作者信息! 新浪微博:郑振宇_HW 博客地址:http://blog.csdn.net/zheng_zhenyu 内容系本人及本人团队学习.研究和总结,如有雷同,实属 ...

  4. yolov3之pytorch源码解析_springmvc源码架构解析之view

    说在前面 前期回顾 sharding-jdbc源码解析 更新完毕 spring源码解析 更新完毕 spring-mvc源码解析 更新完毕 spring-tx源码解析 更新完毕 spring-boot源 ...

  5. spring boot 源码_springboot源码架构解析listener

    说在前面 前期回顾 sharding-jdbc源码解析 更新完毕 spring源码解析 更新完毕 spring-mvc源码解析 更新完毕 spring-tx源码解析 更新完毕 spring-boot源 ...

  6. netty springmvc_springmvc源码架构解析之HandlerMapping

    说在前面 前期回顾 sharding-jdbc源码解析 更新完毕 spring源码解析 更新完毕 spring-mvc源码解析 更新完毕 spring-tx源码解析 更新完毕 spring-boot源 ...

  7. python 全栈开发,Day128(创建二维码,扫码,创建玩具的基本属性)

    python 全栈开发,Day128(创建二维码,扫码,创建玩具的基本属性) 昨日内容回顾 1.app播放音乐plus.audio.createPlayer(文件路径/URL)player.play( ...

  8. LAMP架构介绍以及Apache源码安装

    一.LAMP架构介绍以及Apache源码安装 1.1.LAMP概述 LAMP是企业基础的应用架构 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web ...

  9. 【Java 虚拟机原理】JDK 体系结构 | Java 源码运行原理 | Java 虚拟机内存

    文章目录 一.JDK 体系结构 二.Java 源码运行原理 三.Java 虚拟机内存结构 一.JDK 体系结构 JDK 体系结构 : 下图所有的内容都是 JDK 体系中的组成元素 ; Java Lan ...

  10. 易语言修改虚拟机硬盘id_易语言本地虚拟机源码

    易语言本地虚拟机源码 系统结构:显示工具路径,读入未用分区,获取分区位置,设置虚拟机分区,读入虚拟分区,操作并显示日志,处理显示错误提示,取驱动器文本列表,写配置目录,处理结果文件,格式化时间,取Do ...

最新文章

  1. 图像处理和模式识别等技术的快速发展大大地推动了机器视觉的发展
  2. python lol脚本_配台电脑,能玩LOL顶配和能够写一些python脚本能用ps不卡,预算6k到8k?...
  3. 设计模式6+1大原则
  4. 基于FPGA的FFT变换实现
  5. 再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结
  6. matlab如何建立一个空矩阵,然后往里面赋值
  7. Qt工作笔记-简单的画图工具
  8. 计算机组成原理3(集中式总线判优控制、总线通信控制)
  9. 最简单的视频编码器:编译(libx264,libx265,libvpx)
  10. linux 下的带宽、延时、吞吐率、PPS
  11. 关闭word 2010时每次都提示:所做更改会影响共用模板Normal.dotm
  12. html里用js实现随机抽奖,javascript实现随机抽奖功能
  13. 文本情感倾向分析——机器学习模型
  14. HoloLens开发学习笔记(一):HoloLens简介
  15. 电子邮箱哪个好用又安全?
  16. FFmpeg 常用命令汇总
  17. iOS22 地图定位- 苹果自带地图
  18. Spring基础-AOP-切入点详解
  19. AD_Copy Room
  20. cuDNN: efficient Primitives for Deep Learning 论文阅读笔记

热门文章

  1. 一个案例入门tableau——NBA球队数据可视化实战解析
  2. mysql数据库压缩_Mysql压缩解决方案
  3. 2018南京航天航空大学820自动控制原理参考答案
  4. 传奇私服服务器怎么增加npc,传奇添加NPC的方法以及形象代码计算
  5. word2vec模型深度解析
  6. 每日一记,养成记录的习惯
  7. php调京东联盟接口,使用京东联盟API获取自定义促销链接
  8. opencontrail学习(一)
  9. 吴翰清:云计算安全是“皇帝的新装”么?
  10. mysql3819错误,微软 Office 3819.20006 预览版发布:修复 Excel 导出 PDF 错误等问题