OpenStack创建虚拟机流程

云主机创建流程图:

dashboard发创建云主机的请求是先到novaclient,再由novaclient以http的形式发送到nova-api端,我们这里直接从nova端讲起,通过wsgi映射匹配,API映射匹配可以看我的另一篇博客:OpenStack Restful API框架介绍

创建云主机会首先调用到nova/api/openstack/compute/servers.py文件中的create()函数:

@wsgi.response(202)
@extensions.expected_errors((400, 403, 409))
@validation.schema(schema_server_create_v20, ‘2.0‘, ‘2.0‘)
@validation.schema(schema_server_create, ‘2.1‘, ‘2.18‘)
@validation.schema(schema_server_create_v219, ‘2.19‘, ‘2.31‘)
@validation.schema(schema_server_create_v232, ‘2.32‘, ‘2.36‘)
@validation.schema(schema_server_create_v237, ‘2.37‘, ‘2.41‘)
@validation.schema(schema_server_create_v242, ‘2.42‘)
def create(self, req, body):
    """Creates a new server for a given user."""
    ......
    # 前面的代码主要是做了传进参数的检查、转换和操作的权限检查,同时获取镜像
    # id和flavor对象,这些处理完后会调用:
    (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,
                                group_id=server_dict.get(‘group_id‘, None),
                                os_type=server_dict.get(‘os_type‘, None),
                                boot_type=‘legacy‘,
                                store_id=server_dict.get(‘store_id‘, None),
                                enable_ha=server_dict.get(‘enable_ha‘, None),
                                thinputer_extra=server_dict.get(‘thinputer_extra‘, None),
                                **create_kwargs)

这里是调用到了nova/compute/api.py文件中的create函数

该函数进行网络是否有不合规操作,比如多个云主机却只指定了一个ip,检查可用域,生成过滤字典,然后调用_create_instance方法

主要是初始化一些参数,检查和检验参数和配额方面的检查,生成instances、request_specs和build_requests对象,request_specs和build_requests对象用以调度选择,instances用以返回给客户端,值可看注解,接着函数调用:

self.compute_task_api.schedule_and_build_instances(
                context,
                build_requests=build_requests,
                request_spec=request_specs,
                image=boot_meta,
                admin_password=admin_password,
                injected_files=injected_files,
                requested_networks=requested_networks,
                block_device_mapping=block_device_mapping)

实现文件是在nova/conductor/api.py,该api.py其实是对同级下的rpcapi.py做了层封装,真正实现在rpcapi.py文件。

api.py中的:

def schedule_and_build_instances(self, context, build_requests,
                                     request_spec, image,
                                     admin_password, injected_files,
                                     requested_networks, block_device_mapping):
        self.conductor_compute_rpcapi.schedule_and_build_instances(
            context, build_requests, request_spec, image,
            admin_password, injected_files, requested_networks,
            block_device_mapping)

这里调用了rpcapi.py中的schedule_and_build_instances方法:

def schedule_and_build_instances(self, context, build_requests,
                                      request_specs,
                                      image, admin_password, injected_files,
                                      requested_networks,
                                      block_device_mapping):
        version = ‘1.16‘
        kw = {‘build_requests‘: build_requests,
              ‘request_specs‘: request_specs,
              ‘image‘: jsonutils.to_primitive(image),
              ‘admin_password‘: admin_password,
              ‘injected_files‘: injected_files,
              ‘requested_networks‘: requested_networks,
              ‘block_device_mapping‘: block_device_mapping}

        cctxt = self.client.prepare(version=version)
        cctxt.cast(context, ‘schedule_and_build_instances‘, **kw)

这里是远程调用到了nova/conductor/manager.py中的schedule_and_build_instances函数:

def schedule_and_build_instances(self, context, build_requests,
                                     request_specs, image,
                                     admin_password, injected_files,
                                     requested_networks, block_device_mapping):
        legacy_spec = request_specs[0].to_legacy_request_spec_dict()
        try:
            hosts = self._schedule_instances(context, legacy_spec,
                        request_specs[0].to_legacy_filter_properties_dict())
            ..........

这个函数主要前面部分主要是先通过scheduler选择合适的host,然后是将要创建的虚拟机的信息写入到数据库中,最后是调用build_and_run_instance函数,该函数实现是在nova/compute_rpcapi.py:

def build_and_run_instance(self, ctxt, instance, host, image, request_spec,
            filter_properties, admin_password=None, injected_files=None,
            requested_networks=None, security_groups=None,
            block_device_mapping=None, node=None, limits=None):

        version = ‘4.0‘
        cctxt = self.router.by_host(ctxt, host).prepare(
                server=host, version=version)
        cctxt.cast(ctxt, ‘build_and_run_instance‘, instance=instance,
                image=image, request_spec=request_spec,
                filter_properties=filter_properties,
                admin_password=admin_password,
                injected_files=injected_files,
                requested_networks=requested_networks,
                security_groups=security_groups,
                block_device_mapping=block_device_mapping, node=node,
                limits=limits)

通过host参数远程调用指定宿主机的build_and_run_instance方法,实现文件在nova/compute/manage.py:

@wrap_exception()
@reverts_task_state
@wrap_instance_fault
def build_and_run_instance(self, context, instance, image, request_spec,
                 filter_properties, admin_password=None,
                 injected_files=None, requested_networks=None,
                 security_groups=None, block_device_mapping=None,
                 node=None, limits=None):

    @utils.synchronized(instance.uuid)
    def _locked_do_build_and_run_instance(*args, **kwargs):
        # NOTE(danms): We grab the semaphore with the instance uuid
        # locked because we could wait in line to build this instance
        # for a while and we want to make sure that nothing else tries
        # to do anything with this instance while we wait.
        with self._build_semaphore:
            self._do_build_and_run_instance(*args, **kwargs)

    # NOTE(danms): We spawn here to return the RPC worker thread back to
    # the pool. Since what follows could take a really long time, we don‘t
    # want to tie up RPC workers.
    utils.spawn_n(_locked_do_build_and_run_instance,
                  context, instance, image, request_spec,
                  filter_properties, admin_password, injected_files,
                  requested_networks, security_groups,
                  block_device_mapping, node, limits)

这里的关键点是调用到了_do_build_and_run_instance函数,该函数的关键代码是调用了_build_and_run_instance函数来创建:

def _build_and_run_instance(self, context, instance, image, injected_files,
            admin_password, requested_networks, security_groups,
            block_device_mapping, node, limits, filter_properties):
    ..........

    # 这个函数的主要功能有进行事件通知、获取所需资源、创建好网络设备和磁盘设备,最
    # 后是通过配置文件的driver选定以哪种虚拟化方式实现虚拟机的生成,这里调用的函数是:
    self.driver.spawn(context, instance, image_meta,
                                              injected_files, admin_password,
                                              network_info=network_info,
                                              block_device_info=block_device_info)

对应的函数实现在nova/virt/libvirt/driver.py:

def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None):
        disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
                                            instance,
                                            image_meta,
                                            block_device_info)
        injection_info = InjectionInfo(network_info=network_info,
                                       files=injected_files,
                                       admin_pass=admin_password)
        gen_confdrive = functools.partial(self._create_configdrive,
                                          context, instance,
                                          injection_info)
        self._create_image(context, instance, disk_info[‘mapping‘],
                           injection_info=injection_info,
                           block_device_info=block_device_info)

        # Required by Quobyte CI
        self._ensure_console_log_for_instance(instance)

        # 生成libvirt所需的xml文件
        xml = self._get_guest_xml(context, instance, network_info,
                                  disk_info, image_meta,
                                  block_device_info=block_device_info)
        self._create_domain_and_network(
            context, xml, instance, network_info, disk_info,
            block_device_info=block_device_info,
            post_xml_callback=gen_confdrive,
            destroy_disks_on_failure=True,
            power_on=False)
        LOG.debug("Instance is running", instance=instance)

在该函数中主要的功能是生成镜像、生成xml信息,最后调用_create_domain_and_network函数进行挂载上磁盘、网络初始化和虚拟机域生成。

虚拟机域生成通过调用了_create_domain函数来实现

总结下,虚拟机的创建流程如下:

(1)用户首先通过Restful Api向keystone组件获取认证信息

(2)然后向nova-api进程发送一个创建虚拟机的请求,并携带获取的认证信息和创建虚拟机的参数

(3)nova-api将认证信息发送到keystone里认证是否是有效的认证信息

(4)通过认证后且nova-api检查权限通过后向数据库写入新建虚拟机的数据库记录

(5)nova-api通过发消息到消息队列让nova-conductor去创建虚拟机

(6)nova-conductor通过发消息到消息队列让nova-scheduler筛选和选择可创建虚拟机的节点

(7)nova-scheduler返回经过筛选的可用宿主机给nova-conductor

(8)nova-conductor通过发消息到消息队列请求让目标节点nova-compute服务创建虚拟机

(9)nova-compute服务发消息到消息队列让控制节点上的nova-conductor服务获取要新建的虚拟机的元数据信息,比如内存、cpu等信息

(10)nova-compute获取到新建虚拟机的元数据信息后,为虚拟机分配资源,比如cpu、内存资源

(11)请求镜像服务获取新建虚拟机的镜像信息和创建镜像文件

(12)如果有网卡和数据盘创建请求,则会分别向neutron和cinder服务请求创建对应的资源

(13)虚拟机域的生成,如果是libvirt的driver,定义好虚拟机的XML信息

(14)初始化虚拟网络设备并启动虚拟机

原文地址:https://www.cnblogs.com/luohaixian/p/12368164.html

时间: 2024-08-24 11:58:26

OpenStack创建虚拟机流程的相关文章

在Ceph中创建虚拟机流程改进之分析

作为个人学习笔记分享,有任何问题欢迎交流! 最近在Gerrit中看到一个change:https://review.openstack.org/#/c/94295/ , 它主要是对当前在Ceph中创建虚拟机的流程的改进.如果glance的backend是ceph, 则nova创建虚拟机到RBD的流程是这样的: 通过glance从ceph中下载image --> 本地 --> 复制image到rbd 这个change的目的就是:不需要下载到本地,直接在rbd中复制image,以提高虚拟机创建的速

openstack创建虚拟机思维导图整理

openstack创建虚拟机思维导图整理:

openstack创建虚拟机

使用devstack安装部署openstack之后,通常我们应该使用vmware的快照功能拍摄快照,以便以后我们可以恢复到之前的情况.创建虚拟机是openstack典型的工作流程,下面将给出创建虚拟机的详细步骤: 1.由于openstack的各种服务都需要经过授权才能够使用,而在授权过程中会使用到OS_PROJECT_NAME,OS_USERNAME和ADMIN_PASSWORD三个openstack环境变量,devstack为我们提供了设置这三个变量的openrc脚本,因此只需devstack

如何解决OpenStack创建虚拟机或删除虚拟机时一直处于deleting或者creating状态的问题。

在OpenStack使用时,有时候会遇到创建虚拟机或者删除虚拟机无法成功创建或者删除的时候,一直提示正在进行中. 这种问题是由于OpenStack的消息积压,OpenStack的Nova Computer无法消费消息说导致. 处理这两种情况的方法可以是,先重置虚拟机状态,把虚拟机设置为active状态,删除虚拟机,再重启nova computer的服务即可. 步骤如下: 1.SSH登陆OpenStack管理平台. 2.加载source源: source keystonerc 3. 把所有Open

openstack创建虚拟机的步骤

图片来自互联网. 虚拟机启动过程如下: 1.界面或命令行通过RESTful API向keystone获取认证信息.2.keystone通过用户请求认证信息,并生成auth-token返回给对应的认证请求.3.界面或命令行通过RESTful API向nova-api发送一个boot instance的请求(携带auth-token).4.nova-api接受请求后向keystone发送认证请求,查看token是否为有效用户和token.5.keystone验证token是否有效,如有效则返回有效的

Azure ARM Portal 创建虚拟机流程

Azure ARM Portal已经上线很长一段时间了,这篇文章非常基础,写这一系列文章也是因为近期在接触客户中,发现很多客户非常需要这一些最基础的帮助.因此我也花了一点时间重头整理了下Azure上的基础使用文档,首先就从创建虚拟机开始 1.登陆portal.azure.cn,国际版登录portal.azure.com,点击左侧菜单,选择资源组,然后创建一个新的资源组. 2.为资源组命名,选择地理位置. 3.完成资源组创建后,继续创建虚拟网络,如下 4.为虚拟网络选择资源组 5.完成网络创建后开

Openstack创建虚拟机进不去操作系统

如果是你按照官方搭建的Openstack并且你的base机位虚拟机且 用的kvm虚拟机等到安装完Openstack后你会看到虚拟机在qemu层可以起来不过进不去操作系统像下面图一样 我们首先看下当前qemu版本 [[email protected] ~]# qemu-img --help|grep version qemu-img version 1.5.3, Copyright (c) 2004-2008 Fabrice Bellard        conversion. If the nu

openstack之虚拟机的创建流程

这篇博文静静的呆在草稿箱大半年了,如果不是因为某些原因被问到,以及因为忽略它而导致的损失,否则我也不知道什么时候会将它完成.感谢这段时间经历的挫折,让我知道不足,希望你能给我更大的决心! 本文试图详细地描述openstack创建虚拟机的完整过程,从用户发起请求到虚拟机成功运行,包括客户端请求的发出.keystone身份验证.nova-api接收请求.nova-scheduler调度.nova-computer创建.nova-network分配网络.对于每一个模块在创建虚拟机的过程中所负责的功能和

Openstack创建云主机的流程-小小白(linuxzkq)

博主自从之前换了工作到现在,因为工作太忙的原因,已经好久没有更新博客了,深表歉意,还望大家理解...... 今天正好有点时间,整理下Openstack创建云主机的流程,大神勿喷. 一.流程图 二.虚拟机创建流程如下 客户(用户)端通过命令行CLI或Dashboard Horizon使用自己的用户名密码请求认证组件keystone进行用户的验证: keystone通过查询在keystone的数据库user表中是否存在user的相关信息,包括password加密后的hash值,并返回一个token_