openstack虚拟机创建快照源码分析超详细(Queen版本)

这是openStack请求应答模型(源自could man)

 

 

一.nova-api接收到外部请求,并处理转发请求

代码路径 :nova-stable-queens ——> nova ——> compute——> api.py

然后 snapshot 函数开始接收请求,并进行处理(函数很长,分步解释)

1.准备处理请求

    #创建快照
    def snapshot(self, context, instance, name, extra_properties=None):
        """Snapshot the given instance.

 

2.先创建新的镜像。这个新的镜像将保留给compute manager用来上载快照或备份

image_meta = self._create_image(context, instance, name,
                                        'snapshot',
                                        extra_properties=extra_properties)

 

3.将instance.task_state的状态设置为penddging状态(这个状态码后面要用到,它标志着操作进行到什么程度,完成各个子操作状态码会变更,方便判断以及异常处理)

instance.task_state = task_states.IMAGE_SNAPSHOT_PENDING

 

4.调用 nova-stable-queens ——> nova ——> compute ——> rpcapi.py 里的snapshot_instance函数,(并且将刚才创建的那个新镜像的id,也就是 image_meta['id'] 作为参数传入)

self.compute_rpcapi.snapshot_instance(context, instance,
                                              image_meta['id'])

 

5.打开 rpcapi.py找到 snapshot_instance 函数,snapshot_instance 函数被api.py的snapshot函数调用,用于创建快照

 def snapshot_instance(self, ctxt, instance, image_id):
        version = self._ver(ctxt, '4.0')

 

6.实例化一个router用来传递消息(正如文首的模型图所示,nova-api是通过消息队列来异步发消息的),向compute发出具体需要执行的操作

        cctxt = self.router.client(ctxt).prepare(
                server=_compute_host(None, instance), version=version)

 

7.通过名为cctxt的router,调用cast,发送message

        cctxt.cast(ctxt, 'snapshot_instance',
                   instance=instance,
                   image_id=image_id)

 

8.cast函数调用proxy_rpc_to_manager函数,通知manager

    def cast(self, ctxt, method, **kwargs):
        msg = self._make_msg(method, **kwargs)
        topic = self._get_topic()
        self.cells_rpcapi.proxy_rpc_to_manager(ctxt, msg, topic)

 

9.proxy_rpc_to_manager函数

 def proxy_rpc_to_manager(self, message, host_name, rpc_message,
                             topic, timeout):
        """Proxy RPC to the given compute topic."""
        # Check that the host exists.
        objects.Service.get_by_compute_host(message.ctxt, host_name)

        topic, _sep, server = topic.partition('.')

        cctxt = rpc.get_client(messaging.Target(topic=topic,
                                                server=server or None))

补充:

           1.真正的snapshot操作是需要在nova-compute节点上执行的,所以nova-api需要向nova-compute发送message,由于OpenStack环境中会有很多个nova-compute,所以需要通过server=_compute_host(None, instance)来获取虚拟机所在的host,并向其发送message。

           2.proxy_rpc_to_manager函数会通知manager,所以之后应该去该目录下的manager.py去找。由于前面都是函数调用的关系去串联的,刚开始学习看源码的时候就在这里断掉了不明白为什么就直接到driver.py了,实际上就是这样来的。

          3.进行函数追踪的时候,点进去会有很多函数都是同名的不知道是哪一个,可以通过(1.对参数 2.看实例化它的类是那个,选择该类里面的那个方法)去辅助找

怎么通知的需要深究rpc原理,有兴趣可以单独看

 

10. 打开nova-stable-queens ——> nova ——> compute ——>manager.py 里面_snapshot_instance函数,可以看到调用dirver的代码

def _snapshot_instance(self, context, image_id, instance,
                           expected_task_state):

            ……此处省略一堆堆,下面是调用dirver的代码,将在snapshot函数中真正执行创建
    self.driver.snapshot(context, instance, image_id,update_task_state)

 

二.向compute节点执行

11.打开nova-stable-queens ——> nova——> virt ——> libvirt ——> driver.py,找到 snapshot函数,从这里才真的开始创建快照

    def snapshot(self, context, instance, image_id, update_task_state):
        """Create snapshot from a running VM instance.

 

12. 检测libvirt版本,看使用live snapshot 热快照 还是cold snapshot 冷快照(取决于最后得出的 live_snapshot 是否等于 False,社区目前认为live snapshot不稳定,libvirt版本小于1.3.0的都只能用cold snapshot )

 if (self._host.has_min_version(hv_type=host.HV_DRIVER_QEMU)
                and source_type not in ('lvm')
                and not CONF.ephemeral_storage_encryption.enabled
                and not CONF.workarounds.disable_libvirt_livesnapshot
            try:
                guest.get_block_device(disk_path).abort_job()
            except libvirt.libvirtError as ex:
                error_code = ex.get_error_code()
                if error_code == libvirt.VIR_ERR_CONFIG_UNSUPPORTED:
                    live_snapshot = False
                else:
                    pass
        else:
            live_snapshot = False

 

13.调用image_backend函数判断后端存储

        root_disk = self.image_backend.by_libvirt_path(
            instance, disk_path, image_type=source_type)

 

14.这些判断都搞完之后更新一下task状态码

update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)

update_task_state(task_state=task_states.IMAGE_UPLOADING,expected_state=task_states.IMAGE_PENDING_UPLOAD)

 

15.挂起客户机

 self._prepare_domain_for_snapshot(context, live_snapshot, state, instance)

 

16.然后执行创建快照(到底执行哪一种,取决于live_snapshot 的值)

    16.1 冷创建

 #冷创建快照
 root_disk.snapshot_extract(out_path, image_format)

    16.2 热创建

self._live_snapshot(context, instance, guest,disk_path, out_path, source_format,image_format, instance.image_meta)

 

17.创建完快照,调用_snapshot_domain函数,恢复虚拟机状态

self._snapshot_domain(context, live_snapshot, virt_dom, state, instance)

_snapshot_domain会调用_attach_pci_devices和_attach_direct_passthrough_ports

 if guest is not None:
    self._attach_pci_devices(guest, pci_manager.get_instance_pci_devs(instance))
    self._attach_direct_passthrough_ports(context, instance, guest)

_attach_pci_devices又会调用attach_device函数,最后在attach_device中将客户机连接到设备

def attach_device(self, conf, persistent=False, live=False):
        """Attaches device to the guest.

 

18.调用update函数,上传快照到glance

self._image_api.update(context,image_id,metadata,image_file)

结束

 

 

 

 

 

 

 

 

OpenStack是一个开源的云计算平台,可以用于构建和管理公共云和私有云环境。在OpenStack创建虚拟机源码解析主要涉及以下几个方面: 1. Nova组件:Nova是OpenStack的计算模块,负责管理和调度虚拟机实例。在创建虚拟机时,首先通过Nova API接口向Nova服务发送创建虚拟机的请求。源码中涉及了虚拟机规格、镜像选项、网络配置等参数的解析和处理。 2. Glance组件:Glance是OpenStack的映像服务,用于提供虚拟机镜像。在创建虚拟机时,需要从Glance中选择合适的镜像作为虚拟机的基础环境。源码中通过Glance API接口获取镜像的元数据信息,包括名称、版本、大小、格式等,然后根据需要将镜像下载或者复制到计算节点上。 3. Neutron组件:Neutron是OpenStack的网络服务,负责虚拟机的网络连接和管理。在创建虚拟机时,需要为虚拟机分配IP地址、配置路由和安全组等网络设置。源码中通过Neutron API接口获取网络的信息,并将虚拟机的网络配置与物理网络进行关联。 4. Cinder组件:Cinder是OpenStack的块存储服务,可以为虚拟机提供持久性存储。在创建虚拟机时,可以选择并挂载Cinder卷作为虚拟机的硬盘。源码中通过Cinder API接口获取存储的信息,并将卷与虚拟机进行关联和挂载。 通过以上的源码解析,可以了解到OpenStack创建虚拟机时,涉及了多个组件的协同工作,包括计算、映像、网络和存储等方面。在实际使用中,可以根据需求和实际情况进行定制和扩展,以满足个性化的虚拟机创建需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值