Master code attach volume to VM

来源:互联网 发布:淘宝基础版全屏店招 编辑:程序博客网 时间:2024/06/05 18:42

卷挂载 业务流程

  1. 访问 keystone 组件做用户认证
  2. 认证通过,携带 token 请求 novaclient
  3. novaclient 接受请求,进行卷挂载
    • 挂载请求路由到 VolumeAttachmentController,进入 nova-api
    • nova-api RPC CALL 到 nova-compute 创建 BDM
    • nova-api 调用 cinderclient 获取 volume 信息,检证,并设定状态 attaching
    • nova-api RPC CAST 到 nova-compute 进行卷挂载
    • 根据 nova.conf 的配置项 compute_driver 获取 LibvirtDriver
    • 根据 BDM source_type 获取驱动 DriverVolumeBlockDevice
    • 调用 DriverVolumeBlockDevice 进行挂载
      • 调用 cinderclient 获取 volume 信息,检证
      • 调用 os_brick 获取 connector 信息
      • 调用 cinderclient 进行存储端挂载,并返回挂载信息(指定的格式)
      • 调用 LibvirtDriver 进行挂载
        • 根据 cinderclient 挂载返回值的 driver_volume_type 获取 LibvirtISCSIVolumeDriver
        • 调用 LibvirtISCSIVolumeDriver 进行主机挂载
        • 将挂载信息写进 VM xml 文件中
      • 调用 cinderclient 更新 cinder DB

nova attach volume 源码分析(基于 master 源码)

客户端接受请求并路由到 VolumeAttachmentController

nova client    ↓POST /v2.1/servers/c2486c45-5a8f-4028-8cd1-51c0425f677a/os-volume_attachments    ↓nova.api.openstack.compute.volumes.VolumeAttachmentController.create    self.compute_api.attach_volume        self.compute_api 可用的有两个:            1. nova.compute.cells_api.ComputeCellsAPI            2. nova.compute.api.API        根据 nova.conf 配置项决定使用哪一个,默认情况下是 nova.compute.api.API

nova-api 层处理请求

nova.compute.api.API.attach_volume    self._attach_volume        ↓nova.compute.api.API._attach_volume    step1: volume_bdm = self._create_volume_bdm            ↓    step2: self._check_attach_and_reserve_volume(context, volume_id, instance)            ↓    step3: self.compute_rpcapi.attach_volume(context, instance, volume_bdm)

step1: 创建 BDM 数据库表数据

nova.compute.api.API._create_volume_bdm    volume_bdm = self.compute_rpcapi.reserve_block_device_name        发送 RPC CALL 到 nova-compute 创建数据库数据            ↓        nova.compute.rpcapi.reserve_block_device_name PRC CALL            ↓        nova.compute.manager.reserve_block_device_name            nova DB block_device_mapping 表新建新数据

step2: 检查可用域并更新 cinder DB volume 数据

nova.compute.api.API._check_attach_and_reserve_volume    2.1 调用 cinderclient 获取需要挂载的 volume 信息        volume = self.volume_api.get(context, volume_id)        实现:cinderclient(context).volumes.get(volume_id)            ↓    2.2 通过上一步查询结果,判断 availability_zone 是否相同(和 cinder 组件无交互)        self.volume_api.check_availability_zone        实现:nova.volume.cinder.API.check_availability_zone            ↓    2.3 调用 cinderclient 更新 cinder DB -> 'status': 'attaching'(以防止其他操作进入)        self.volume_api.reserve_volume(context, volume_id)        实现:nova.volume.cinder.API.reserve_volume            cinderclient(context).volumes.reserve(volume_id)                                    ↓            调用 cinderclient reserve(os-reserve)                                    ↓            cinder.api.contrib.volume_actions.VolumeActionsController._reserve                                    ↓            cinder.volume.api.API.reserve_volume         

step3: 挂载卷

RPC CAST 到 nova-compute
self.compute_rpcapi.attach_volume            ↓nova.compute.rpcapi.attach_volume PRC CAST            ↓nova.compute.manager.ComputeManager.attach_volume
核心挂载处理流程(ComputeManager.attach_volume)
1. 根据 source_type 获取 BDM 驱动 DriverVolumeBlockDevice
driver_bdm = driver_block_device.convert_volume(bdm)                        ↓nova.virt.block_device.convert_volume                        ↓获取 BDM 驱动 nova.virt.block_device.DriverVolumeBlockDevice
2. BDM driver attach
self._attach_volume(context, instance, driver_bdm)                             ↓bdm.attach(context, instance, self.volume_api, self.driver,           do_driver_attach=True)self.volume_api = nova.volume.cinder.APIself.driver = nova.virt.libvirt.driver.LibvirtDriver                             ↓                实际上调用 BDM 驱动进行卷挂载nova.virt.block_device.DriverVolumeBlockDevice.attach                             ↓               预处理(获取卷,判断可用域)+-STEP 1---------------------|-----------------------------------+|                get volume by cinderclient                      ||                check availability_zone                         |+----------------------------|-----------------------------------+                             ↓        获取 connector,为 initialize_connection 提供入参+-STEP 2---------------------|-----------------------------------+| connector = virt_driver.get_volume_connector(instance)         ||                            ↓                                   || nova.virt.libvirt.driver.LibvirtDriver.get_volume_connector    ||                            ↓                                   || os_brick.initiator.connector.get_connector_properties          |+----------------------------|-----------------------------------+                             ↓             存储端进行挂载返回 connection_info+-STEP 3---------------------|-----------------------------------+| connection_info = volume_api.initialize_connection             ||                            ↓                                   ||    nova.volume.cinder.API.initialize_connection                ||                            ↓                                   || cinderclient initialize_connection(os-initialize_connection)   ||      (when occur Exception terminate_connection)               |+----------------------------|-----------------------------------+                             ↓        主机端根据 connection_info 挂载卷到目标主机(iSCSI 为例)+-STEP 4---------------------|-----------------------------------+|              virt_driver.attach_volume                         ||    nova.virt.libvirt.driver.LibvirtDriver.attach_volume        ||         (when occur Exception terminate_connection)            ||                            ↓                                   ||         nova.virt.libvirt.driver.LibvirtDriver.                ||                   _connect_volume                              ||                            ↓                                   ||     nova.virt.libvirt.volume.iscsi.LibvirtISCSIVolumeDriver.   ||                      connect_volume                            ||                            ↓                                   ||       self.connector.connect_volume(connection_info['data'])   ||       os_brick.initiator.connectors.iscsi.ISCSIConnector.      ||                       connect_volume                           ||                            ↓                                   ||     guest.attach_device(conf, persistent=True, live=live)      ||        (write attach info to VM XML)                           |+----------------------------|-----------------------------------+                             ↓                    更新 cinder DB 数据+-STEP 5---------------------|-----------------------------------+|                    volume_api.attach                           ||                            ↓                                   ||               nova.volume.cinder.API.attach                    ||                            ↓                                   ||              cinderclient attach(os-attach)                    |+----------------------------------------------------------------+

  • 卷挂载 业务流程
  • nova attach volume 源码分析基于 master 源码
      • 客户端接受请求并路由到 VolumeAttachmentController
      • nova-api 层处理请求
        • step1 创建 BDM 数据库表数据
        • step2 检查可用域并更新 cinder DB volume 数据
        • step3 挂载卷
          • RPC CAST 到 nova-compute
          • 核心挂载处理流程ComputeManagerattach_volume
            • 根据 source_type 获取 BDM 驱动 DriverVolumeBlockDevice
            • BDM driver attach

2 0
原创粉丝点击