久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

nova怎么創建虛擬機

197次閱讀
沒有評論

共計 7624 個字符,預計需要花費 20 分鐘才能閱讀完成。

丸趣 TV 小編給大家分享一下 nova 怎么創建虛擬機,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

總體描述:

1.   創建實例接口

還是先看接口 API

REQ: 
curl \
-i  http://ubuntu80:8774/v2/0e962df9db3f4469b3d9bfbc5ffdaf7e/servers  \
-X POST -H  Accept: application/json  \
-H  Content-Type: application/json  \ 
-H  User-Agent: python-novaclient  \
-H  X-Auth-Project-Id: admin  \
-H  X-Auth-Token: {SHA1}e87219521f61238b143fbb323b962930380ce022  \
-d  {server : { name :  ubuntu_test ,  imageRef :  cde1d850-65bb-48f6-8ee9-b990c7ccf158 ,  flavorRef :  2 ,  max_count : 1,  min_count : 1,  networks : [{ uuid :  cfa25cef-96c3-46f1-8522-d9518eb5a451}]}}

這里對應的依然是 Controller

具體位置為:

nova.api.openstack.compute.servers.Controller.create

注意這個方法的裝飾器有一個 @wsgi.response(202),而根據 HTTP 協議狀態碼返回 202 表示服務器已接受請求,但尚未處理,表明這是一個異步任務。

最終此方法調用的 self.compute_api.create(…) 是由__init__(…) 中的 self.compute_api = compute.API() 獲取。

因此 compute.API() 對應到 nova.compute.api.API.create(…),其內部又調用 nova.compute.api.API._create_instance(…)。

就在 nova.compute.api.API._create_instance(…) 里面重點來了。

2. 任務狀態第一次變化為 SCHEDULING

在 nova.compute.api.API._create_instance(…) 里有一步調用:

instances = self._provision_instances(context, instance_type,
 min_count, max_count, base_options, boot_meta, security_groups,
 block_device_mapping, shutdown_terminate,
 instance_group, check_server_group_quota)

這一方法的位置是 nova.compute.api.API._provision_instances,其內部有如下調用:

instance = self.create_db_entry_for_new_instance(...)

而在 nova.compute.api.API.create_db_entry_for_new_instance 對應(self.create_db_entry_for_new_instance(…)),有如下調用:

self._populate_instance_for_create(context, instance, image, index,
 security_group, instance_type)

其對應的是 nova.compute.api.API._populate_instance_for_create,內部第一次將任務狀態置為調度:

instance.vm_state = vm_states.BUILDING
instance.task_state = task_states.SCHEDULING

那么回到_provision_instances 方法,主要是申請了配額。

3. 由 nova-api 到 nova-conductor

在 nova.compute.api.API._create_instance(…) 里有一步調用:

self.compute_task_api.build_instances(context,
 instances=instances, image=boot_meta,
 filter_properties=filter_properties,
 admin_password=admin_password,
 injected_files=injected_files,
 requested_networks=requested_networks,
 security_groups=security_groups,
 block_device_mapping=block_device_mapping,
 legacy_bdm=False)

從這一步開始離開 nova-api,nova-api 調用的是 nova-conductor,nova-scheduler 和 nova-compute 中的方法。

 @property
 def compute_task_api(self):
 if self._compute_task_api is None:
 # TODO(alaski): Remove calls into here from conductor manager so
 # that this isn t necessary. #1180540
 from nova import conductor
 self._compute_task_api = conductor.ComputeTaskAPI()
 return self._compute_task_api

4. nova-conductor 調用 nova-scheduler 和 nova-compute

這邊已經來到 conductor 部分,位置為 nova.conductor.ComputeTaskAPI:

def ComputeTaskAPI(*args, **kwargs):
 use_local = kwargs.pop(use_local , False)
 if oslo.config.cfg.CONF.conductor.use_local or use_local:
 api = conductor_api.LocalComputeTaskAPI
 else:
 api = conductor_api.ComputeTaskAPI
 return api(*args, **kwargs)

這里 use_local 是默認置為 False,這里默認調用的是

api = conductor_api.LocalComputeTaskAPI

它的位置是 nova.conductor.LocalComputeTaskAPI 在它的構造函數(__init__(…))中有 manager.ComputeTaskManager 即 nova.conductor.ComputeTaskManager

這個類的 build_instances 方法,位置(nova.conductor.ComputeTaskManager.build_instances(…)):

nova-conductor 會在 build_instances() 中生成 request_spec 字典,

request_spec = scheduler_utils.build_request_spec(...)

其中包括了詳細的虛擬機信息,nova-scheduler 依據這些信息為虛擬機選擇一個最佳的主機,

hosts = self.scheduler_client.select_destiation(... , request_spec, ...)

然后 nova-conductor 再通過 RPC 調用 nova-compute 創建虛擬機

 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])

這里調用的是 nova.compute.rpcapi.ComputeAPI.build_and_run_instance

其中可以看到,調用的是 build_and_run_instance,而 cctxt.cast(…) 是異步遠程調用(調用后不立即返回),詳細可以搜索 oslo.messaging 模塊的使用

 cctxt.cast(ctxt,  build_and_run_instance , instance=instance,
 image=image, request_spec=request_spec,
 filter_properties=filter_properties,
 admin_password=admin_password,
 injected_files=injected_files,
 requested_networks=requested_networks,
 security_groups=security_groups,
 block_device_mapping=block_device_mapping, node=node,
 limits=limits)

調用對應的是 nova.compute.manager.build_and_run_instance(…),其內部調用(注意:使用的是 spawn 方式調用)的是_do_build_and_run_instance(…)。

_do_build_and_run_instance(…) 內部主要的調用為_build_and_run_instance 函數(nova.compute.manager._build_and_run_instance(…)):

5. 建立和運行實例  

定位到 nova.compute.manager._build_and_run_instance(…) 之后,看到如下代碼:

 def _build_and_run_instance(self, context, instance, image, injected_files,
 admin_password, requested_networks, security_groups,
 block_device_mapping, node, limits, filter_properties):
 image_name = image.get(name)
 self._notify_about_instance_usage(context, instance,  create.start ,
 extra_usage_info={image_name : image_name})
 try:
 #  資源跟蹤器
 rt = self._get_resource_tracker(node)
 with rt.instance_claim(context, instance, limits) as inst_claim:
 # NOTE(russellb) It s important that this validation be done
 # *after* the resource tracker instance claim, as that is where
 # the host is set on the instance.
 self._validate_instance_group_policy(context, instance,
 filter_properties)
 #  分配資源,包括網絡和存儲,在內部
 #  任務狀態由 task_states.SPAWNING 變為 task_states.NETWORKING 再
 #  變成 task_states.BLOCK_DEVICE_MAPPING
 with self._build_resources(context, instance,
 requested_networks, security_groups, image,
 block_device_mapping) as resources:
 instance.vm_state = vm_states.BUILDING
 #  任務狀態變為孵化中
 instance.task_state = task_states.SPAWNING
 instance.numa_topology = inst_claim.claimed_numa_topology
 instance.save(expected_task_state=
 task_states.BLOCK_DEVICE_MAPPING)
 block_device_info = resources[block_device_info]
 network_info = resources[network_info]
 #  調用底層 virt api 孵化實例
 self.driver.spawn(context, instance, image,
 injected_files, admin_password,
 network_info=network_info,
 block_device_info=block_device_info)
 except ...:
 # NOTE(alaski): This is only useful during reschedules, remove it now.
 instance.system_metadata.pop(network_allocated , None)
 #  查看實例電源狀態
 instance.power_state = self._get_power_state(context, instance)
 #  開啟實例電源(開機) instance.vm_state = vm_states.ACTIVE
 #  任務狀態清空
 instance.task_state = None
 #  實例內部時間操作
 instance.launched_at = timeutils.utcnow()
 try:
 instance.save(expected_task_state=task_states.SPAWNING)
 except (exception.InstanceNotFound,
 exception.UnexpectedDeletingTaskStateError) as e:
 with excutils.save_and_reraise_exception():
 self._notify_about_instance_usage(context, instance,
  create.end , fault=e)
 #  通知創建過程結束
 self._notify_about_instance_usage(context, instance,  create.end ,
 extra_usage_info={message : _( Success)},
 network_info=network_info)

第一步就是建立一個資源跟蹤器(RT: Resource Tracker),注意,RT 分為索要跟蹤器(Claim RT)和周期跟蹤器(Periodic RT),當然我們還可以自己擴展插件叫擴展跟蹤器(Extensible RT)。

顧名思義,在_build_and_run_instance 函數中建立的 RT 是索要(claim)跟蹤器,對計算節點上的資源進行核實,如果資源分配失敗,會拋出異常。

 rt = self._get_resource_tracker(node)
 with rt.instance_claim(context, instance, limits) as inst_claim:

這里還要提到_build_resources 函數,在這個函數里 instance.task_state 狀態

由 task_states.SCHEDULING 變為 task_states.NETWORKING 再變成 task_states.BLOCK_DEVICE_MAPPING

self._build_resources(context, instance,
 requested_networks, security_groups, image,
 block_device_mapping)

待資源分配完成,任務狀態由 task_states.BLOCK_DEVICE_MAPPING 轉變為 task_states.SPAWNING

instance.task_state = task_states.SPAWNING

當一切準備完畢時,調用 self.driver.spawn 孵化實例,底層則是 Libvirt 部分,啟動孵化過程

 self.driver.spawn(context, instance, image,
 injected_files, admin_password,
 network_info=network_info,
 block_device_info=block_device_info)

之后做的就是開機,對時,通知創建過程結束,成功!

以上是“nova 怎么創建虛擬機”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注丸趣 TV 行業資訊頻道!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計7624字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 婺源县| 呼玛县| 隆子县| 南雄市| 五河县| 虞城县| 滨州市| 永仁县| 鸡泽县| 永登县| 陆河县| 德江县| 孟州市| 读书| 松原市| 黄陵县| 兴业县| 新巴尔虎右旗| 朝阳市| 乾安县| 平和县| 景谷| 临海市| 嫩江县| 富宁县| 鄄城县| 麻栗坡县| 武夷山市| 宝兴县| 堆龙德庆县| 湖州市| 淮滨县| 汤原县| 武山县| 沧源| 天等县| 偏关县| 固安县| 高邑县| 牟定县| 连云港市|