openstack nova 创建虚拟机流程 liberty版本

先粗略了解一下nova创建虚拟机的四个核心模块

  • api服务:负责处理客户端发送的http请求,路由到具体调用函数(包括一些中间件处理,如鉴权)
  • conductor服务:主要用于数据库的访问,为数据库访问提供安全保障,同时使compute服务与数据库解耦,目前compute服务所有的访问数据库的操作都要交给conductor完成,conductor服务和compute服务也最好要分开部署在不同服务器上,以保证数据库的安全性。同时也抽离出原本compute服务中的TaskAPI任务(主要包含比较耗时的任务),比如创建虚拟机,迁移虚拟机等操作。
  • scheduler服务:挑选合适的虚拟机。可以有多种调度器,但是只能选择一种调度器,需要在/etc/nova/nova.conf中通过 scheduler_driver指定,默认使用FilterScheduler(包含filters和weighting两个步骤,filters依据指定条件过滤不合格主机,再通过weighting对筛选后的主机列表进行权重排序找出最优主机)
  • compute服务:管理虚拟机的生命周期。

源代码(liberty版本):


def build_instances(self, context, instances, image, filter_properties,
            admin_password, injected_files, requested_networks,
            security_groups, block_device_mapping=None, legacy_bdm=True):
        # TODO(ndipanov): Remove block_device_mapping and legacy_bdm in version
        #                 2.0 of the RPC API.
        request_spec = scheduler_utils.build_request_spec(context, image,
                                                          instances)
        # TODO(danms): Remove this in version 2.0 of the RPC API
        if (requested_networks and 
                not isinstance(requested_networks,
                objects.NetworkRequestList)):
            requested_networks = objects.NetworkRequestList(
                objects=[objects.NetworkRequest.from_tuple(t)
                for t in requested_networks])
        # TODO(melwitt): Remove this in version 2.0 of the RPC API
        flavor = filter_properties.get('instance_type')
        if flavor and not isinstance(flavor, objects.Flavor):
            # Code downstream may expect extra_specs to be populated since it
            # is receiving an object, so lookup the flavor to ensure this.
            flavor = objects.Flavor.get_by_id(context, flavor['id'])
            filter_properties = dict(filter_properties, instance_type=flavor)
        try:
            scheduler_utils.setup_instance_group(context, request_spec,
                                                 filter_properties)
            # check retry policy. Rather ugly use of instances[0]...
            # but if we've exceeded max retries... then we really only
            # have a single instance.
            scheduler_utils.populate_retry(filter_properties,
                instances[0].uuid)
            hosts = self.scheduler_client.select_destinations(context,
                request_spec, filter_properties)
        except Exception as exc:
            updates = {'vm_state': vm_states.ERROR, 'task_state': None}
            for instance in instances:
                self._set_vm_state_and_notify(
                    context, instance.uuid, 'build_instances', updates,
                    exc, request_spec)
            return

        for (instance, host) in itertools.izip(instances, hosts):
            try:
                instance.refresh()
            except (exception.InstanceNotFound,
                    exception.InstanceInfoCacheNotFound):
                LOG.debug('Instance deleted during build', instance=instance)
                continue
            local_filter_props = copy.deepcopy(filter_properties)
            scheduler_utils.populate_filter_properties(local_filter_props,
                host)
            # The block_device_mapping passed from the api doesn't contain
            # instance specific information
            bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
context, instance.uuid)

            self.compute_rpcapi.build_and_run_instance(context,
                instance=instance, host=host['host'], image=image,
                request_spec=request_spec,
                filter_properties=local_filter_props,
                admin_password=admin_password,
                injected_files=injected_files,
                requested_networks=requested_networks,
                security_groups=security_groups,
                block_device_mapping=bdms, node=host['nodename'],
                limits=host['limits'])

创建流程:

1,nova-api接到客户端的创建请求

2,nova-api通过RPC cast方式调用conductor的build_instances方法

3,conductor的build_instances通过RPC call调用scheduler的select_destinations方法选择合适的目标主机

4,通过scheduler返回的主机信息,通过RPC cast调用compute的build_and_run_instance方法,完成虚拟机的创建

附:

1,[rpc client调用方式]rpc server会在服务启动时注册 ,cast和call是rpcclient的两种调用方法,区别在于cast相当于一种异步形式,call同步,所以耗时长的一般采用cast方法(实现于oslo_messaging中)

调用方式:

cctxt = self.client.prepare(server=_compute_host(None, instance),             
    version=version)
    return cctxt.call(ctxt, 'get_serial_console',
         instance=instance, console_type=console_type)

call的第二个参数为rpc调用函数名,后面的为该调用函数的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值