openstack 之 nova架构,源码剖析

一.nova架构

        nova是openstack最核心的服务,负责维护和管理云环境的计算资源。因此,云主机的整个生命周期都是由nova负责的。

1.1 nova-api

        负责接收和相应客户的API调用。

1.2 compute core

        nova-schedule

        负责决定在哪个计算节点运行虚拟机。

        nova-compute

        通过调用Hypervisor实现虚拟机生命周期的管理。一般运行在计算节点。

        hypervisor

        对虚拟机进行硬件虚拟化的管理软件,比如KVM和VMWare等。

        nova-conductor

        由于nova-compute需要不断对数据库进行更新,比如更新虚拟机状态,为了安全性和伸缩性的考虑,通过nova-conductor间接实现数据库的访问。

1.3 database

        一般使用MYSQL,安装在控制节点上,因为nova有一些数据需要存储在database中。

1.4 Message Queue

        用于nova各个子服务之间的通讯,一般使用的是RabbitMQ,从而解耦各个子服务。

二.nova创建主机源码剖析

1.nova-api进程执行过程:

a. nova:api:openstack:compute:servers.py:ServersController:create():

        通过用户发送的api数据中的req和body信息来解析需要的有关云主机的数据,比如云主机类型(inst_type),镜像id(image_uuid),主机聚合(availability_zone),强制使用的主机以及节点(forced_host,forced_node),元数据(metadata),连接的网络(requested_networks)等,然后调用nova:compute:api.py:API:create()来正式开始创建云主机,最后向用户返回响应结果。

    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
        if api_version_request.is_supported(req, min_version='2.19'):
            description = server_dict.get('description')

        # Arguments to be passed to instance create function
        create_kwargs = {}

        # TODO(alex_xu): This is for back-compatible with stevedore
        # extension interface. But the final goal is that merging
        # all of extended code into ServersController.
        self._create_by_func_list(server_dict, create_kwargs, body)

        availability_zone = server_dict.pop("availability_zone", None)

        if api_version_request.is_supported(req, min_version='2.52'):
            create_kwargs['tags'] = server_dict.get('tags')

        helpers.translate_attributes(helpers.CREATE,
                                     server_dict, create_kwargs)

        target = {
            'project_id': context.project_id,
            'user_id': context.user_id,
            'availability_zone': availability_zone}
        context.can(server_policies.SERVERS % 'create', target)

        # TODO(Shao He, Feng) move this policy check to os-availability-zone
        # extension after refactor it.
        parse_az = self.compute_api.parse_availability_zone
        try:
            availability_zone, host, node = parse_az(context,
                                                     availability_zone)
        except exception.InvalidInput as err:
            raise exc.HTTPBadRequest(explanation=six.text_type(err))
        if host or node:
            context.can(server_policies.SERVERS % 'create:forced_host', {})

        # NOTE(danms): Don't require an answer from all cells here, as
        # we assume that if a cell isn't reporting we won't schedule into
        # it anyway. A bit of a gamble, but a reasonable one.
        min_compute_version = service_obj.get_minimum_version_all_cells(
            nova_context.get_admin_context(), ['nova-compute'])
        supports_device_tagging = (min_compute_version >=
                                   DEVICE_TAGGING_MIN_COMPUTE_VERSION)

        block_device_mapping = create_kwargs.get("block_device_mapping")
        # TODO(Shao He, Feng) move this policy check to os-block-device-mapping
        # extension after refactor it.
        if block_device_mapping:
            context.can(server_policies.SERVERS % 'create:attach_volume',
                        target)
            for bdm in block_device_mapping:
                if bdm.get('tag', None) and not supports_device_tagging:
                    msg = _('Block device tags are not yet supported.')
                    raise exc.HTTPBadRequest(explanation=msg)

        image_uuid = self._image_from_req_data(server_dict, create_kwargs)

        # NOTE(cyeoh): Although upper layer can set the value of
        # return_reservation_id in order to request that a reservation
        # id be returned to the client instead of the newly created
        # instance information we do not want to pass this parameter
        # to the compute create call which always returns both. We use
        # this flag after the instance create call to determine what
        # to return to the client
        return_reservation_id = create_kwargs.pop('return_reservation_id',
                                                  False)

        req
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值