• OpenStack 虚拟机启动流程 UML 分析(内含 UML 源码)


    目录

    前言

    在这里插入图片描述
    上图可见 虚拟机启动流程 之于 OpenStack 的含义,本文秉承一图抵前言的原则,通过 UML 图展现虚拟机启动的详细流程,并不断扩充,这是一篇持续更新的文章。

    API 请求

    一切缘起于一个请求:POST /servers
    https://developer.openstack.org/api-ref/compute/#create-server

    Creates a server.
    The progress of this operation depends on the location of the requested image, network I/O, host load, selected flavor, and other factors.
    To check the progress of the request, make a GET /servers/{id} request. This call returns a progress attribute, which is a percentage value from 0 to 100.
    The Location header returns the full URL to the newly created server and is available as a self and bookmark link in the server representation.
    When you create a server, the response shows only the server ID, its links, and the admin password. You can get additional attributes through subsequent GET requests on the server.
    Include the block_device_mapping_v2 parameter in the create request body to boot a server from a volume.
    Include the key_name parameter in the create request body to add a keypair to the server when you create it. To create a keypair, make a create keypair request.

    Nova API 阶段

    在这里插入图片描述

    @startuml
    actor User
    
    entity "api/openstack/compute/server.py"
    entity "compute/api.py"
    entity "conductor/api.py"
    entity "conductor/rpcapi.py"
    entity "conductor/manager.py"
    
    autonumber
    
    User -> "api/openstack/compute/server.py": POST /servers
    
    activate "api/openstack/compute/server.py"
    "api/openstack/compute/server.py" -> "api/openstack/compute/server.py": ServersController.create
    note left: 组装用于创建虚拟机的参数 create_kwargs
    
    
    "api/openstack/compute/server.py" -> "compute/api.py": API.create
    activate "compute/api.py"
    "compute/api.py" -> "compute/api.py": scheduler_utils.build_filter_properties
    note left: 组装用于调度的数据结构 filter_properties
    
    "compute/api.py" -> "compute/api.py": _create_instance
    note left: 验证输入的参数,并转换为标准数据结构对象
    
    activate "compute/api.py"
    "compute/api.py" -> "compute/api.py": _validate_and_build_base_options
    "compute/api.py" -> "compute/api.py": _check_and_transform_bdm
    note left: 组装 block_device_mapping 数据结构
    "compute/api.py" -> "compute/api.py": _provision_instances
    activate "compute/api.py"
    "compute/api.py" -> "compute/api.py": objects.RequestSpec.from_components
    note left: 实例化 objects.RequestSpec 对象,包含了调度时所考虑的调度因子
    "compute/api.py" -> "compute/api.py": objects.Instance
    note left: 实例化 objects.Instance 对象
    "compute/api.py" -> "compute/api.py": objects.InstanceMapping
    note left: 实例化 objects.InstanceMapping 对象
    "compute/api.py" -> "compute/api.py": objects.BuildRequest
    note left: 实例化 objects.BuildRequest 对象
    deactivate "compute/api.py"
    
    "compute/api.py" -> "conductor/api.py": self.compute_task_api.schedule_and_build_instances
    note left:
    
    deactivate "compute/api.py"
    
    "conductor/api.py" -> "conductor/rpcapi.py": schedule_and_build_instances
    "conductor/rpcapi.py" -> "conductor/manager.py": CAST schedule_and_build_instances
    "conductor/rpcapi.py" -> "conductor/api.py": return None
    "conductor/api.py" -> "compute/api.py": return None
    "compute/api.py" -> "api/openstack/compute/server.py": return instances, reservation_id
    "api/openstack/compute/server.py" -> User: RESP HTTP 202
    note left: instances, reservation_id
    deactivate "api/openstack/compute/server.py"
    @enduml

    Nova Conductor 阶段

    在这里插入图片描述

    @startuml
    entity "conductor/rpcapi.py"
    entity "conductor/manager.py"
    entity "scheduler/rpcapi.py"
    entity "scheduler/manager.py"
    entity "compute/rpcapi.py"
    entity "compute/manager.py"
    autonumber
    
    "conductor/rpcapi.py" -> "conductor/manager.py": CAST schedule_and_build_instances
    activate "conductor/manager.py"
    "conductor/manager.py" -> "conductor/manager.py": _schedule_instances
    activate "conductor/manager.py"
    "conductor/manager.py" -> "scheduler/rpcapi.py": self.scheduler_client.select_destinations
    "scheduler/rpcapi.py" -> "scheduler/manager.py": CALL select_destinations
    note left: 调度创建虚拟机的计算节点
    "scheduler/manager.py" -> "scheduler/rpcapi.py": return
    "scheduler/rpcapi.py" -> "conductor/manager.py": return host_lists
    "conductor/manager.py" -> "conductor/manager.py": 获取主机调度的 cell
    note left: Convert host from the scheduler into a cell record
    "conductor/manager.py" -> "conductor/manager.py": 创建 Instance 数据库记录
    "conductor/manager.py" -> "conductor/manager.py": 创建 BlockDeviceMapping 数据库记录
    "conductor/manager.py" -> "conductor/manager.py": 创建 Tag 数据库记录
    "conductor/manager.py" -> "compute/rpcapi.py": self.compute_rpcapi.build_and_run_instance
    "compute/rpcapi.py" -> "compute/manager.py": CAST build_and_run_instance
    "compute/rpcapi.py" -> "conductor/manager.py": return
    
    deactivate "conductor/manager.py"
    deactivate "conductor/manager.py"
    @enduml

    Nova Scheduler 阶段

    在这里插入图片描述

    @startuml
    entity "scheduler/rpcapi.py"
    entity "scheduler/manager.py"
    entity "scheduler/client/report.py"
    entity "scheduler/filter_scheduler.py"
    entity Placement
    entity "scheduler/host_manager.py"
    
    autonumber
    
    "scheduler/rpcapi.py" -> "scheduler/manager.py": CALL select_destinations
    activate "scheduler/manager.py" 
    "scheduler/manager.py" -> "scheduler/manager.py": objects.RequestSpec.from_primitives
    note left: 获取 Request Spec Object,用于调度
    "scheduler/manager.py" -> "scheduler/manager.py": self.placement_client.get_allocation_candidates
    note left: 从 Placement 获取调度候选人
    "scheduler/manager.py" -> "scheduler/client/report.py": get_allocation_candidates
    "scheduler/client/report.py" -> Placement: GET /allocation_candidates?%s
    "scheduler/client/report.py" -> "scheduler/manager.py": return allocation_candidates
    note left: alloc_reqs_by_rp_uuid, provider_summaries, allocation_request_version
    "scheduler/manager.py" -> "scheduler/filter_scheduler.py": self.driver.select_destinations
    activate "scheduler/filter_scheduler.py"
    "scheduler/filter_scheduler.py" -> "scheduler/filter_scheduler.py": _schedule
    activate "scheduler/filter_scheduler.py"
    "scheduler/filter_scheduler.py" -> "scheduler/filter_scheduler.py": _get_all_host_states
    note left: 获取调度候选人对应的计算节点
    "scheduler/filter_scheduler.py" -> "scheduler/filter_scheduler.py": _get_sorted_hosts
    activate "scheduler/filter_scheduler.py"
    "scheduler/filter_scheduler.py" -> "scheduler/host_manager.py": self.host_manager.get_filtered_hosts
    note left: 进行 Filters 过滤
    "scheduler/filter_scheduler.py" -> "scheduler/host_manager.py": self.host_manager.get_weighed_hosts
    note left: 进行 Weighed 排序
    deactivate "scheduler/filter_scheduler.py"
    "scheduler/filter_scheduler.py" -> "scheduler/client/report.py": utils.claim_resources
    note left: 扣除 Placement resources 数量
    "scheduler/filter_scheduler.py" -> "scheduler/client/report.py": _consume_selected_host
    note left: 根据 Request Spec Object 临时扣除资源
    "scheduler/filter_scheduler.py" -> "scheduler/host_manager.py": consume_from_request
    note left: 临时扣除 Nova Scheduler 维护的资源数据,存储在内存中的 HostState 实例对象
    "scheduler/filter_scheduler.py" -> "scheduler/client/report.py": return selections_to_return
    "scheduler/client/report.py" -> "scheduler/manager.py": return
    deactivate "scheduler/filter_scheduler.py"
    deactivate "scheduler/filter_scheduler.py"
    "scheduler/manager.py" -> "scheduler/rpcapi.py": return selections
    deactivate "scheduler/manager.py"
    @enduml

    Nova Compute 阶段(计算节点资源分配部分)

    在这里插入图片描述

    @startuml
    entity "compute/rpcapi.py"
    entity "compute/manager.py"
    entity "compute/resource_tracker.py"
    entity "compute/claims.py"
    autonumber
    
    
    "compute/rpcapi.py" -> "compute/manager.py": CAST build_and_run_instance
    
    activate "compute/manager.py"
    "compute/manager.py" -> "compute/manager.py": build_and_run_instance
    activate "compute/manager.py"
    "compute/manager.py" -> "compute/manager.py": _do_build_and_run_instance
    activate "compute/manager.py"
    "compute/manager.py" -> "compute/manager.py": _build_and_run_instance
    activate "compute/manager.py"
    "compute/manager.py" -> "compute/resource_tracker.py": instance_claim
    activate "compute/resource_tracker.py"
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": 获取虚拟机所需要的开销
    note left
     1. RAM
     2. CPU
     3. Disk
    end note
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": 获取 ComputeNode Object
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": 获取虚拟机所需要的 PCI 设备
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": claims.Claim 宣告创建虚拟机所需要的资源
    "compute/resource_tracker.py" -> "compute/claims.py": claims.Claim
    activate "compute/claims.py"
    "compute/claims.py" -> "compute/claims.py": _claim_test
    note left
    尝试在目的节点上声明虚拟机所需要的资源,判断是否能够满足
    NOTE:这里只是宣告资源需求,并非直接使用资源
    end note
    
    activate "compute/claims.py"
    "compute/claims.py" -> "compute/claims.py": _test_memory
    "compute/claims.py" -> "compute/claims.py": _test_disk
    "compute/claims.py" -> "compute/claims.py": _test_vcpus
    "compute/claims.py" -> "compute/claims.py": _test_numa_topology(展开)
    note left: 为具有 NUMA 亲和、CPU 绑定需求的虚拟机构建 GuestOS NUMA Topo 并分配 NUMA、CPU 资源
    "compute/claims.py" -> "compute/claims.py": _test_pci
    "compute/claims.py" -> "compute/resource_tracker.py": return claims.MoveClaim 实例对象
    deactivate "compute/claims.py"
    deactivate "compute/claims.py"
    
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": pci_tracker.claim_instance (展开)
    note left: 为具有 PCI 需求的虚拟机在 PCI Device Pool 中选取具体的 PCI 设备
    
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": _update_usage_from_instance
    note left
    Mark resources in-use and update stats
    Update usage for a single instance.
    end note
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": _update
    note left: 将上述宣告的资源刷新到数据库记录
    activate "compute/resource_tracker.py"
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": compute_node.save()
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": _update_to_placement
    note left: Send resource and inventory changes to placement.
    "compute/resource_tracker.py" -> "compute/resource_tracker.py": self.pci_tracker.save()
    deactivate "compute/resource_tracker.py"
    "compute/resource_tracker.py" -> "compute/manager.py": Claim 实例化对象
    deactivate "compute/resource_tracker.py"
    deactivate "compute/manager.py"
    deactivate "compute/manager.py"
    deactivate "compute/manager.py"
    "compute/manager.py" -> "compute/manager.py": _build_resources(后续)
    deactivate "compute/manager.py"
    @enduml

    Nova Compute 阶段(NUMA、CPU 资源分配部分)

    在这里插入图片描述

    @startuml
    entity "compute/claims.py"
    entity "virt/hardware.py"
    autonumber
    
    activate "compute/claims.py"
    "compute/claims.py" -> "compute/claims.py": _test_numa_topology
    note left
    为具有 NUMA 亲和、CPU 绑定需求的虚拟机
    构建 GuestOS NUMA Topo 并分配 NUMA、CPU 资源
    end note
    activate "compute/claims.py"
    "compute/claims.py" -> "compute/claims.py": 获取 instance requested_topology
    "compute/claims.py" -> "compute/claims.py": 获取 host_topology
    "compute/claims.py" -> "compute/claims.py": 获取 instance pci_requests
    "compute/claims.py" -> "virt/hardware.py": numa_fit_instance_to_host
    note left
    Fit the instance topology onto the host topology.
    将 GuestOS NUMA Topo 根据既定算法嵌入到 Host NUMA Topo
    end note
    activate "virt/hardware.py"
    "virt/hardware.py" -> "virt/hardware.py": 首先准备 NUMA Node 调度因子
    note left
    以下因子都会被考虑到 NUMA 节点的分配调度上:
      1. emulator_threads_policy: QEMU 模拟器线程策略
      2. network_metadata: 符合网络 NUMA 要求
      3. pci_requests: 与 SR-IOV 网卡同 NUMA
    end note
    
    "virt/hardware.py" -> "virt/hardware.py": itertools.permutations(host_cells, len(instance_topology))
    note left: * 根据 GuestOS NUMA Node 的数量对 Host NUMA Node 进行全排列组合
    
    "virt/hardware.py" -> "virt/hardware.py": _numa_fit_instance_cell
    note left
    * Ensure an instance cell can fit onto a host cell
    轮询 Host NUMA Node 全排列,
    将 GuestOS NUMA Node 分别尝试放置,
    直到 GuestOS NUMA Topo 被合理的放置到 Host NUMA Topo 中,
    并满足上述 NUMA 调度因子。
    end note
    
    activate "virt/hardware.py"
    "virt/hardware.py" -> "virt/hardware.py": Fit pagesize
    "virt/hardware.py" -> "virt/hardware.py": Fit memory
    "virt/hardware.py" -> "virt/hardware.py": Fit CPU amount
    "virt/hardware.py" -> "virt/hardware.py": _numa_fit_instance_cell_with_pinning
    note left: Fit CPU Pin 
    activate "virt/hardware.py"
    "virt/hardware.py" -> "virt/hardware.py": _pack_instance_onto_cores
    note left
    Try to pack the instance cell onto cores
    Pack an instance onto a set of siblings.
    end note
    deactivate "virt/hardware.py"
    
    "virt/hardware.py" -> "virt/hardware.py": instance_cell.id = host_cell.id
    note left: 将 Host NUMA 映射到 GuestOS NUMA
    deactivate "virt/hardware.py"
    "virt/hardware.py" -> "compute/claims.py": return objects.InstanceNUMATopology
    note left: 返回 GuestOS NUMA Topo 资源实例对象
    deactivate "compute/claims.py"
    "compute/claims.py" -> "compute/claims.py": Claimed GuestOS NUMA Topo
    note left: 声明要使用的 GuestOS NUMA Topo 资源,在整个虚拟机启动流程中有效
    deactivate "compute/claims.py"
    @enduml

    Nova Compute 阶段(虚拟机资源构建部分)

    在这里插入图片描述

    @startuml
    entity "compute/manager.py"
    entity "virt/libvirt/driver.py"
    autonumber
    
    "compute/manager.py" -> "compute/manager.py": _build_and_run_instance
    activate "compute/manager.py"
    "compute/manager.py" -> "compute/manager.py": 计算节点资源分配部分
    "compute/manager.py" -> "compute/manager.py": _build_resources
    activate "compute/manager.py"
    "compute/manager.py" -> "compute/manager.py": _build_networks_for_instance
    note left: 异步构建网络资源
    "compute/manager.py" -> "compute/manager.py": _default_block_device_names
    note left: 保证所有虚拟机磁盘都设置了名称,e.g. sda/sdb
    "compute/manager.py" -> "compute/manager.py": _prep_block_device
    note left: 将块设备挂载到计算节点
    deactivate "compute/manager.py"
    
    "compute/manager.py" -> "virt/libvirt/driver.py": self.driver.spawn
    note left: 孵化一个虚拟机创建任何,并在合适的时机执行它
    activate "virt/libvirt/driver.py"
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _create_image
    note left
     1. Created local Root disk file from glance image file
     2. Created Swap disk file
     3. Created Ephemeral disk file
    end note
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _ensure_console_log_for_instance
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_xml
    note left: 生成 Libvirt 虚拟机 XML 文件
    activate "virt/libvirt/driver.py"
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_config
    note left
     1. guest.virt_type
     2. guest.name
     3. guest.uuid
     4. guest.memory
     5. guest.vcpus
     6. guest.cpuset
     7. guest.cputune
     8. guest.numatune
     9. guest.membacking
     10. ...
    end note
    activate "virt/libvirt/driver.py"
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_numa_config
    note left: Returns the config objects for the guest NUMA specs.
    activate "virt/libvirt/driver.py"
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_host_numa_topology
    note left: 获取 Host NUMA Topo
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_cpu_numa_config_from_instance
    note left: 获取 Guest NUMA Topo from Instance Object
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": Init GuestOS CPUTune configuration
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": Init GuestOS NUMATune configuration
    
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": Set realtime scheduler for CPUTune
    note left
    1. _get_cell_pairs: 根据 Claims 的 GuestOS NUMA Topo 和 Host NUMA Topo 再次进行匹配
    2. set NUMATune for the cell
    3. set CPUTune for the cell
    end note
    deactivate "virt/libvirt/driver.py"
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_memory_backing_config
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_config_meta
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_idmaps
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_cpu_config
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_os_type
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_storage_config
    note left: 配置存储
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": self.vif_driver.get_config
    note left: 配置网络
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _create_consoles
    note left: 配置 Console
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _get_guest_pointer_model
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_spice_channel
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_video_device
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _set_qemu_guest_agent
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_pcie_root_ports
    note left: 配置 PCIe 设备
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_pci_devices
    note left: 配置 PCI 设备
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_watchdog_action
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_memory_balloon
    "virt/libvirt/driver.py" -> "virt/libvirt/driver.py": _guest_add_mdevs
    note left: 配置 GPU 设备
    "virt/libvirt/driver.py" -> "compute/manager.py": return GuestOS XML
    deactivate "virt/libvirt/driver.py"
    "compute/manager.py" -> "compute/manager.py": _create_domain_and_network
    note left
    1. 执行一些 firewall 相关的配置
    2. 创建 Libvirt Guest Domain 实例
    end note
    
    deactivate "virt/libvirt/driver.py"
    deactivate "virt/libvirt/driver.py"
    
    
    
    deactivate "compute/manager.py"
    @enduml

    相关阅读:

  • 相关阅读:
    No Hibernate Session bound to thread, and configuration does not allow
    谈谈数据库中MyISAM与InnoDB区别
    hibernate实体的几种状态:
    解决Eclipse导出javadoc乱码问题
    freemarker截取字符串
    many-to-one和one-to-many的配置比较
    one-to-many many-to-one配置解释
    extends:类似于java中的继承特征,extends="struts-default"
    eclipse 中创建maven web项目
    java.lang.ClassNotFoundException: javax.persistence.EntityListeners
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309701.html
Copyright © 2020-2023  润新知