摘要:引言當我們在使用那些建設在之上的云平臺服務的時候,往往在概覽頁面都有一個明顯的位置用來展示當前集群的一些資源使用情況,如,,內(nèi)存,硬盤等資源的總量使用量剩余量。如上,就是統(tǒng)計節(jié)點硬件資源的整個邏輯過程為例。
引言
當我們在使用那些建設在OpenStack之上的云平臺服務的時候,往往在概覽頁面都有一個明顯的位置用來展示當前集群的一些資源使用情況,如,CPU,內(nèi)存,硬盤等資源的總量、使用量、剩余量。而且,每當我們拓展集群規(guī)模之后,概覽頁面上的資源總量也會自動增加,我們都熟知,OpenStack中的Nova服務負責管理這些計算資源,那么你有沒有想過,它們是如何被Nova服務獲取的嗎?
Nova如何統(tǒng)計資源我們知道,統(tǒng)計資源的操作屬于Nova服務內(nèi)部的機制,考慮到資源統(tǒng)計結(jié)果對后續(xù)操作(如創(chuàng)建虛擬機,創(chuàng)建硬盤)的重要性,我們推斷該機制的運行順序一定先于其他服務。
通過上述簡單的分析,再加上一些必要的Debug操作,我們得出:
該機制的觸發(fā)點位于nova.service.WSGIService.start方法中:
def start(self): """Start serving this service using loaded configuration. Also, retrieve updated port number in case "0" was passed in, which indicates a random port should be used. :returns: None """ if self.manager: self.manager.init_host() self.manager.pre_start_hook() if self.backdoor_port is not None: self.manager.backdoor_port = self.backdoor_port self.server.start() if self.manager: self.manager.post_start_hook()
其中,self.manager.pre_start_hook()的作用就是去獲取資源信息,它的直接調(diào)用為nova.compute.manager.pre_start_hook如下:
def pre_start_hook(self): """After the service is initialized, but before we fully bring the service up by listening on RPC queues, make sure to update our available resources (and indirectly our available nodes). """ self.update_available_resource(nova.context.get_admin_context()) ... @periodic_task.periodic_task def update_available_resource(self, context): """See driver.get_available_resource() Periodic process that keeps that the compute host"s understanding of resource availability and usage in sync with the underlying hypervisor. :param context: security context """ new_resource_tracker_dict = {} nodenames = set(self.driver.get_available_nodes()) for nodename in nodenames: rt = self._get_resource_tracker(nodename) rt.update_available_resource(context) new_resource_tracker_dict[nodename] = rt # Delete orphan compute node not reported by driver but still in db compute_nodes_in_db = self._get_compute_nodes_in_db(context, use_slave=True) for cn in compute_nodes_in_db: if cn.hypervisor_hostname not in nodenames: LOG.audit(_("Deleting orphan compute node %s") % cn.id) cn.destroy() self._resource_tracker_dict = new_resource_tracker_dict
上述代碼中的rt.update_available_resource()的直接調(diào)用實為nova.compute.resource_tracker.update_available_resource()如下:
def update_available_resource(self, context): """Override in-memory calculations of compute node resource usage based on data audited from the hypervisor layer. Add in resource claims in progress to account for operations that have declared a need for resources, but not necessarily retrieved them from the hypervisor layer yet. """ LOG.audit(_("Auditing locally available compute resources")) resources = self.driver.get_available_resource(self.nodename) if not resources: # The virt driver does not support this function LOG.audit(_("Virt driver does not support " ""get_available_resource" Compute tracking is disabled.")) self.compute_node = None return resources["host_ip"] = CONF.my_ip # TODO(berrange): remove this once all virt drivers are updated # to report topology if "numa_topology" not in resources: resources["numa_topology"] = None self._verify_resources(resources) self._report_hypervisor_resource_view(resources) return self._update_available_resource(context, resources)
上述代碼中的self._update_available_resource的作用是根據(jù)計算節(jié)點上的資源實際使用結(jié)果來同步數(shù)據(jù)庫記錄,這里我們不做展開;self.driver.get_available_resource()的作用就是獲取節(jié)點硬件資源信息,它的實際調(diào)用為:
class LibvirtDriver(driver.ComputeDriver): def get_available_resource(self, nodename): """Retrieve resource information. This method is called when nova-compute launches, and as part of a periodic task that records the results in the DB. :param nodename: will be put in PCI device :returns: dictionary containing resource info """ # Temporary: convert supported_instances into a string, while keeping # the RPC version as JSON. Can be changed when RPC broadcast is removed stats = self.get_host_stats(refresh=True) stats["supported_instances"] = jsonutils.dumps( stats["supported_instances"]) return stats def get_host_stats(self, refresh=False): """Return the current state of the host. If "refresh" is True, run update the stats first. """ return self.host_state.get_host_stats(refresh=refresh) def _get_vcpu_total(self): """Get available vcpu number of physical computer. :returns: the number of cpu core instances can be used. """ if self._vcpu_total != 0: return self._vcpu_total try: total_pcpus = self._conn.getInfo()[2] + 1 except libvirt.libvirtError: LOG.warn(_LW("Cannot get the number of cpu, because this " "function is not implemented for this platform. ")) return 0 if CONF.vcpu_pin_set is None: self._vcpu_total = total_pcpus return self._vcpu_total available_ids = hardware.get_vcpu_pin_set() if sorted(available_ids)[-1] >= total_pcpus: raise exception.Invalid(_("Invalid vcpu_pin_set config, " "out of hypervisor cpu range.")) self._vcpu_total = len(available_ids) return self._vcpu_total ..... class HostState(object): """Manages information about the compute node through libvirt.""" def __init__(self, driver): super(HostState, self).__init__() self._stats = {} self.driver = driver self.update_status() def get_host_stats(self, refresh=False): """Return the current state of the host. If "refresh" is True, run update the stats first. """ if refresh or not self._stats: self.update_status() return self._stats def update_status(self): """Retrieve status info from libvirt.""" ... data["vcpus"] = self.driver._get_vcpu_total() data["memory_mb"] = self.driver._get_memory_mb_total() data["local_gb"] = disk_info_dict["total"] data["vcpus_used"] = self.driver._get_vcpu_used() data["memory_mb_used"] = self.driver._get_memory_mb_used() data["local_gb_used"] = disk_info_dict["used"] data["hypervisor_type"] = self.driver._get_hypervisor_type() data["hypervisor_version"] = self.driver._get_hypervisor_version() data["hypervisor_hostname"] = self.driver._get_hypervisor_hostname() data["cpu_info"] = self.driver._get_cpu_info() data["disk_available_least"] = _get_disk_available_least() ...
注意get_available_resource方法的注釋信息,完全符合我們開始的推斷。我們下面單以vcpus為例繼續(xù)調(diào)查資源統(tǒng)計流程,self.driver._get_vcpu_total的實際調(diào)用為LibvirtDriver._get_vcpu_total(上述代碼中已給出),如果配置項vcpu_pin_set沒有生效,那么得到的_vcpu_total的值為self._conn.getInfo()[2](self._conn可以理解為libvirt的適配器,它代表與kvm,qemu等底層虛擬化工具的抽象連接,getInfo()就是對libvirtmod.virNodeGetInfo的一次簡單的封裝,它的返回值是一組數(shù)組,其中第三個元素就是vcpus的數(shù)量),我們看到這里基本就可以了,再往下就是libvirt的C語言代碼而不是Python的范疇了。
另一方面,如果我們配置了vcpu_pin_set配置項,那么該配置項就被hardware.get_vcpu_pin_set方法解析成一個可用CPU位置索引的集合,再通過對該集合求長后,我們也能得到最終想要的vcpus的數(shù)量。
如上,就是Nova統(tǒng)計節(jié)點硬件資源的整個邏輯過程(vcpus為例)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/38158.html
此文已由作者王盼授權(quán)網(wǎng)易云社區(qū)發(fā)布。 歡迎訪問網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運營經(jīng)驗~ 現(xiàn)狀計算節(jié)點發(fā)生磁盤損壞等數(shù)據(jù)無法恢復的異常時,節(jié)點上的云主機系統(tǒng)盤無法恢復,導致云主機只能被清理重建 計算節(jié)點宕機但磁盤數(shù)據(jù)可用時,重啟即可恢復所有云主機的運行 計算節(jié)點多次宕機(或一段時間內(nèi)頻繁宕機),則需要遷移所有云主機或者直接清理重建,云硬盤需要遷移到其他cinder-volume存儲服務節(jié)點 一般來...
摘要:一為什么要使用虛擬云桌面背景攜程呼叫中心,即服務聯(lián)絡中心,是攜程的核心部門之一,現(xiàn)有幾萬員工。他們?nèi)晷r為全球攜程用戶提供服務。為此,攜程正式引入了虛擬云桌面。攜程云桌面現(xiàn)狀攜程云桌面現(xiàn)已部署上海南通如皋合肥信陽穆棱六個呼叫中心。 編者:本文為劉科在第六期【攜程技術(shù)微分享】中的分享內(nèi)容。在攜程技術(shù)中心(微信號ctriptech)微信后臺回復【云桌面】,可加入微信交流群,和關(guān)注云桌面的...
摘要:一為什么要使用虛擬云桌面背景攜程呼叫中心,即服務聯(lián)絡中心,是攜程的核心部門之一,現(xiàn)有幾萬員工。他們?nèi)晷r為全球攜程用戶提供服務。為此,攜程正式引入了虛擬云桌面。攜程云桌面現(xiàn)狀攜程云桌面現(xiàn)已部署上海南通如皋合肥信陽穆棱六個呼叫中心。 編者:本文為劉科在第六期【攜程技術(shù)微分享】中的分享內(nèi)容。在攜程技術(shù)中心(微信號ctriptech)微信后臺回復【云桌面】,可加入微信交流群,和關(guān)注云桌面的...
摘要:下圖展示了虛擬機可以獲取到的信息神奇的這個地址來源于,亞馬遜在設計公有云的時候為了讓能夠訪問,就將這個特殊的作為服務器的地址。服務啟動了服務,負責處理虛擬機發(fā)送來的請求。服務也運行在網(wǎng)絡節(jié)點。中的路由和服務器都在各自獨立的命名空間中。前言下圖是OpenStack虛擬機在啟動過程中發(fā)出的一個請求,我們在里面可以看到cloud-init和169.254.169.254。那么它們分別是做什么用的呢...
摘要:模板中的頂級,定義實例化后將返回的數(shù)據(jù)。通過如此的解析和協(xié)作,最終完成請求的處理。服務接受請求,讀入模板信息,處理后利用請求發(fā)送給。首先,調(diào)用拿到對應的。Heat 是由AWS的EC2 Cloud Formation 演化而來,是openstack中負責Orchestration的service, 用于openstack 中資源的編排,它通過將OpenStack中的資源(resource)以模...
閱讀 2425·2021-08-18 10:21
閱讀 2534·2019-08-30 13:45
閱讀 2165·2019-08-30 13:16
閱讀 2131·2019-08-30 12:52
閱讀 1376·2019-08-30 11:20
閱讀 2635·2019-08-29 13:47
閱讀 1633·2019-08-29 11:22
閱讀 2774·2019-08-26 12:11