Openstack nova-scheduler 原始碼分析 — Filters/Weighting
目錄
前言
本篇記錄了 Openstack 在建立 Instances 時,nova-scheduler 作為排程器的工作原理和程式碼實現。
Openstack 中會由多個的 Instance 共享同一個 Host,而不是獨佔。所以就需要使用排程器這種管理規則來協調和管理 Instance 之間的資源分配。
排程器
排程器:排程 Instance 在哪一個 Host 上執行的方式。
目前 Nova 中實現的排程器方式由下列幾種:
ChanceScheduler(隨機排程器):從所有正常執行 nova-compute 服務的 Host Node 中隨機選取來建立 Instance
FilterScheduler(過濾排程器):根據指定的過濾條件以及權重來挑選最佳建立 Instance 的 Host Node 。
Caching(快取排程器):是 FilterScheduler 中的一種,在其基礎上將 Host 資源資訊快取到本地的記憶體中,然後通過後臺的定時任務從資料庫中獲取最新的 Host 資源資訊。
為了便於擴充套件,Nova 將一個排程器必須要實現的介面提取出來成為 nova.scheduler.driver.Scheduler,只要繼承了該類並實現其中的介面,我們就可以自定義排程器。
注意:不同的排程器並不能共存,需要在 /etc/nova/nova.conf
vim /etc/nova/nova.conf
scheduler_driver = nova.scheduler.filter_scheduler.FilterScheduler
FilterScheduler排程器的工作流程
FilterScheduler 首先使用指定的 Filters(過濾器) 過濾符合條件的 Host,EG. 記憶體使用率小於 2% 。然後對得到的 Host 列表計算 Weighting 權重並排序,獲得最佳的 Host 。
Filters 過濾器
Filtering 就是首先根據各個 Host 當前可用的資源情況來過濾掉那些不能滿足 Instance 要求的 Host,然後再使用配置檔案指定的各種 Filters 去過濾掉不符合過濾條件的 Host。經過 Filters 過濾後,會得到一個 Host 列表。
這樣的話 nova-scheduler 就需要從資料庫中取得當前各個 Host 最新的資源使用情況,這些資源資料的收集和儲存都由 nova-compute 中定義的資料庫同步機制來完成。但是 nova-compute 對資料庫的更新是週期性的, nova-scheduler 在選擇最佳 Host 時需要最新的資源資料。所以在 nova-scheduler 中使用了 nova.scheduler.host_manager:HostState 來維護一份資料。這份資料僅儲存在當前程序的記憶體中,裡面包含了從上次資料庫更新到現在 Host 資源的變化情況,也就是最新的 Host 資源資料。nova-scheduler 為了保持自己所維護的資源資料是最新的,每建立一個 Instance ,nova-scheduler 都要將這份資源資料更新,並從 Host 可用資源中去掉虛擬機器使用的部分。
注意:nova-scheduler 所維護的資料不會同步到資料庫,它只會從資料庫同步資料到自身,所以 nova-scheduler 並沒有寫資料庫的功能。
Filters 型別
- ALLHostsFilter:不進行任何過濾
- RamFilter:根據記憶體的可用情況來進行過濾
- ComputeFilter:選取所有處於 Active 的 Host
- TrustedFilter:選取所有可信的 Host
- PciPassthroughFilter:選取提供 PCI SR-IOV 支援的 Host
所有的 Filters 實現都位於nova/scheduler/filters 目錄,每個 Filter 都要繼承自 nova.scheduler.filters.BaseHostFilter 。如果需要自定義一個 Filter,只需通過繼承此類並實現一個函式 host_passes()
,返回的結果只有 True or False 。
在配置檔案中指定 Filters:
scheduler_available_filters=
scheduler_default_filters=
Weighting 權重
Weighting 表示對所有符合過濾條件(通過 Filters)的 Host 計算權重並以此排序從而得到最佳的一個 Host。計算 Host 權重的過程需要呼叫指定的各種 Weigher Module,得到每個 Host 的權重值。
所有的 Weigher 的實現都位於 nova/scheduler/weights 目錄下。
原始碼實現
關鍵檔案及其意義
/nova/scheduler/driver.py: 檔案中最重要的就是 Scheduler 類,是所有排程器實現都要繼承的基類,包含了排程器必須要實現的所有介面。
/nova/scheduler/manager.py: 主要實現了 SchedulerManager 類,定義了 Host 的管理操作函式,如:刪除 Host 中的 Instance — delete_instance_info
/nova/scheduler/host_manager.py: 有兩個類的實現,都是描述了跟排程器相關的 Host 的操作實現,類 HostState 維護了一份最新的 Host 資源資料。類 HostManager 描述了排程器相關的操作函式, EG._choose_host_filters/get_filtered_hosts/get_weighed_hosts
/nova/scheduler/chance.py: 只有 ChanceScheduler 類(隨機排程器),繼承自 Scheduler 類,實現隨機選取 Host Node 的排程器
/nova/scheduler/client: 客戶端呼叫程式的入口
/nova/scheduler/filter_scheduler.py: 只有 FilterScheduler 類(過濾排程器),繼承自 Scheduler 類,實現了根據指定的過濾條件來選取 Host Node 的排程器
/nova/scheduler/filters 和 /nova/scheduler/weights: 這兩個目錄下的內容分別對應 過濾器 和 權重 的實現 。
階段一:nova-scheduler 接收 build_instances RPC 遠端呼叫
nova-conductor ==> RPC scheduler_client.select_destinations() ==> nova-sechduler
#nova.conductor.manager.ComputeTaskManager:build_instances()
def build_instances(self, context, instances, image, filter_properties,
admin_password, injected_files, requested_networks,
security_groups, block_device_mapping=None, legacy_bdm=True):
# TODO(ndipanov): Remove block_device_mapping and legacy_bdm in version
# 2.0 of the RPC API.
# 獲取需要建立的 Instance 的引數資訊
request_spec = scheduler_utils.build_request_spec(context, image,
instances)
# TODO(danms): Remove this in version 2.0 of the RPC API
if (requested_networks and
not isinstance(requested_networks,
objects.NetworkRequestList)):
# 請求 network 資訊
requested_networks = objects.NetworkRequestList(
objects=[objects.NetworkRequest.from_tuple(t)
for t in requested_networks])
# TODO(melwitt): Remove this in version 2.0 of the RPC API
# 獲取 flavor 資訊
flavor = filter_properties.get('instance_type')
if flavor and not isinstance(flavor, objects.Flavor):
# Code downstream may expect extra_specs to be populated since it
# is receiving an object, so lookup the flavor to ensure this.
flavor = objects.Flavor.get_by_id(context, flavor['id'])
filter_properties = dict(filter_properties, instance_type=flavor)
try:
scheduler_utils.setup_instance_group(context, request_spec,
filter_properties)
# check retry policy. Rather ugly use of instances[0]...
# but if we've exceeded max retries... then we really only
# have a single instance.
scheduler_utils.populate_retry(filter_properties,
instances[0].uuid)
# 獲取 Hosts 列表
hosts = self.scheduler_client.select_destinations(context,
request_spec, filter_properties)
except Exception as exc:
updates = {'vm_state': vm_states.ERROR, 'task_state': None}
for instance in instances:
self._set_vm_state_and_notify(
context, instance.uuid, 'build_instances', updates,
exc, request_spec)
return
for (instance, host) in itertools.izip(instances, hosts):
try:
instance.refresh()
except (exception.InstanceNotFound,
exception.InstanceInfoCacheNotFound):
LOG.debug('Instance deleted during build', instance=instance)
continue
local_filter_props = copy.deepcopy(filter_properties)
scheduler_utils.populate_filter_properties(local_filter_props,
host)
# The block_device_mapping passed from the api doesn't contain
# instance specific information
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
context, instance.uuid)
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-conductor 在呼叫 nova-scheduler 來獲取能夠建立 Instance 的 Host 的同時也獲取了:requested_networks/flavor 等資訊。
其中獲取 Hosts 列表的程式碼塊:
# 獲取 Hosts 列表
hosts = self.scheduler_client.select_destinations(context,
request_spec, filter_properties)
下面列出了一系列為了獲取 Hosts 列表的函式呼叫跳轉:
# nova.scheduler.client.query.SchedulerQueryClient:select_destinations()
from nova.scheduler import rpcapi as scheduler_rpcapi
class SchedulerQueryClient(object):
"""Client class for querying to the scheduler."""
def __init__(self):
self.scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI()
def select_destinations(self, context, request_spec, filter_properties):
"""Returns destinations(s) best suited for this request_spec and
filter_properties.
The result should be a list of dicts with 'host', 'nodename' and
'limits' as keys.
"""
#
return self.scheduler_rpcapi.select_destinations(
context, request_spec, filter_properties)
# nova.scheduler.rpcapi.SchedulerAPI:select_destinations()
def select_destinations(self, ctxt, request_spec, filter_properties):
cctxt = self.client.prepare(version='4.0')
return cctxt.call(ctxt, 'select_destinations',
request_spec=request_spec, filter_properties=filter_properties)
階段二:從 scheduler.rpcapi.SchedulerAPI 到 scheduler.manager.SchedulerManager
rpcapi.py 中的介面函式會在 manager.py 中實現實際操作函式。
所以跳轉到 nova.scheduler.manager.SchedulerManager:select_destinations()
# nova.scheduler.manager.SchedulerManager:select_destinations()
class SchedulerManager(manager.Manager):
"""Chooses a host to run instances on."""
target = messaging.Target(version='4.2')
def __init__(self, scheduler_driver=None, *args, **kwargs):
if not scheduler_driver:
scheduler_driver = CONF.scheduler_driver
# 可以看出這裡的 driver 是通過配置檔案中的選項值指定的類來返回的物件 EG.nova.scheduler.filter_scheduler.FilterScheduler
self.driver = importutils.import_object(scheduler_driver)
super(SchedulerManager, self).__init__(service_name='scheduler',
*args, **kwargs)
def select_destinations(self, context, request_spec, filter_properties):
"""Returns destinations(s) best suited for this request_spec and
filter_properties.
The result should be a list of dicts with 'host', 'nodename' and
'limits' as keys.
"""
dests = self.driver.select_destinations(context, request_spec,
filter_properties)
return jsonutils.to_primitive(dests)
階段三:從 scheduler.manager.SchedulerManager 到排程器 FilterScheduler
vim /etc/nova/nova.conf
scheduler_driver = nova.scheduler.filter_scheduler.FilterScheduler
從配置檔案選項 scheduler_driver
的值可以知道,nova.scheduler.manager.SchedulerManager:driver
是 nova.scheduler.filter_scheduler.FilterScheduler
的例項化物件。
所以跳轉到 nova.scheduler.filter_scheduler.FilterScheduler:select_destinations() 。
# nova.scheduler.filter_scheduler.FilterScheduler:select_destinations()
class FilterScheduler(driver.Scheduler):
"""Scheduler that can be used for filtering and weighing."""
def __init__(self, *args, **kwargs):
super(FilterScheduler, self).__init__(*args, **kwargs)
self.options = scheduler_options.SchedulerOptions()
self.notifier = rpc.get_notifier('scheduler')
def select_destinations(self, context, request_spec, filter_properties):
"""Selects a filtered set of hosts and nodes."""
self.notifier.info(context, 'scheduler.select_destinations.start',
dict(request_spec=request_spec))
# 需要建立的 Instances 的數量
num_instances = request_spec['num_instances']
# 獲取滿足笫一次過濾條件的主機列表 List (詳見上述的排程器過濾原理)
# nova.scheduler.filter_scheduler.FilterScheduler:_schedule() ==> return selected_hosts
selected_hosts = self._schedule(context, request_spec,
filter_properties)
# Couldn't fulfill the request_spec
# 當請求的 Instance 數量大於合適的主機數量時,不會建立 Instance 且輸出 'There are not enough hosts available.'
if len(selected_hosts) < num_instances:
# NOTE(Rui Chen): If multiple creates failed, set the updated time
# of selected HostState to None so that these HostStates are
# refreshed according to database in next schedule, and release
# the resource consumed by instance in the process of selecting
# host.
for host in selected_hosts:
host.obj.updated = None
# Log the details but don't put those into the reason since
# we don't want to give away too much information about our
# actual environment.
LOG.debug('There are %(hosts)d hosts available but '
'%(num_instances)d instances requested to build.',
{'hosts': len(selected_hosts),
'num_instances': num_instances})
reason = _('There are not enough hosts available.')
raise exception.NoValidHost(reason=reason)
dests = [dict(host=host.obj.host, nodename=host.obj.nodename,
limits=host.obj.limits) for host in selected_hosts]
self.notifier.info(context, 'scheduler.select_destinations.end',
dict(request_spec=request_spec))
return dests
def _schedule(self, context, request_spec, filter_properties):
# 獲取所有 Hosts 的狀態
hosts = self._get_all_host_states(elevated)
selected_hosts = []
# 獲取需要建立的 Instances 數目
num_instances = request_spec.get('num_instances', 1)
# 遍歷 num_instances,為每個 Instance 選取合適的主機
for num in range(num_instances):
# Filter local hosts based on requirements ...
# 在 for 迴圈裡,_schedule 的兩個關鍵操作,get_filtered_hosts() 和 get_weighed_hosts()
hosts = self.host_manager.get_filtered_hosts(hosts,
filter_properties, index=num)
if not hosts:
# Can't get any more locally.
break
LOG.debug("Filtered %(hosts)s", {'hosts': hosts})
weighed_hosts = self.host_manager.get_weighed_hosts(hosts,
filter_properties)
LOG.debug("Weighed %(hosts)s", {'hosts': weighed_hosts})
scheduler_host_subset_size = CONF.scheduler_host_subset_size
# 下面兩個 if,主要為了防止 random.choice 呼叫越界
if scheduler_host_subset_size > len(weighed_hosts):
scheduler_host_subset_size = len(weighed_hosts)
if scheduler_host_subset_size < 1:
scheduler_host_subset_size = 1
# 在符合要求的weigh過的host裡進行隨機選取
chosen_host = random.choice(
weighed_hosts[0:scheduler_host_subset_size])
LOG.debug("Selected host: %(host)s", {'host': chosen_host})
selected_hosts.append(chosen_host)
# Now consume the resources so the filter/weights
# will change for the next instance.
chosen_host.obj.consume_from_instance(instance_properties)
if update_group_hosts is True:
if isinstance(filter_properties['group_hosts'], list):
filter_properties['group_hosts'] = set(
filter_properties['group_hosts'])
filter_properties['group_hosts'].add(chosen_host.obj.host)
# 迴圈為每一個例項獲取合適的主機後,返回選擇的主機列表
return selected_hosts
上述的函式有三個非常關鍵的操作函式:
- _get_all_host_states: 獲取所有的 Host 狀態,並且將初步滿足條件的 Hosts 過濾出來。
- get_filtered_hosts:使用 Filters 過濾器將第一個函式返回的 hosts 進行再一次過濾。
- get_weighed_hosts:通過 Weighed 選取最優 Host。
這三個關鍵函式在後面會繼續介紹。
首先看看host_manager.get_filtered_hosts() 中,host_manager 是 nova.scheduler.driver.Scheduler 的成員變數 。如下:
# nova.scheduler.driver.Scheduler:__init__()
# nova.scheduler.filter_scheduler.FilterScheduler 繼承了 nova.scheduler.driver.Scheduler
class Scheduler(object):
"""The base class that all Scheduler classes should inherit from."""
def __init__(self):
# 從這裡知道 host_manager 會根據配置檔案動態匯入
self.host_manager = importutils.import_object(
CONF.scheduler_host_manager)
self.servicegroup_api = servicegroup.API()
還需要注意:scheduler.filter_scheduler.FilterScheduler:_schedule() 中獲取 Hosts 狀態的函式 _get_all_host_states()
實現如下:
# nova.scheduler.host_manager.HostManager:get_all_host_states()
def get_all_host_states(self, context):
service_refs = {service.host: service
for service in objects.ServiceList.get_by_binary(
context, 'nova-compute')}
# 獲取 Compute Node 資源
compute_nodes = objects.ComputeNodeList.get_all(context)
# nova.object.__init__()
# ==> nova.object.compute_node.ComputeNodeList:get_all
seen_nodes = set()
for compute in compute_nodes:
service = service_refs.get(compute.host)
if not service:
LOG.warning(_LW(
"No compute service record found for host %(host)s"),
{'host': compute.host})
continue
host = compute.host
node = compute.hypervisor_hostname
state_key = (host, node)
host_state = self.host_state_map.get(state_key)
# 更新主機資訊
if host_state:
host_state.update_from_compute_node(compute)
else:
host_state = self.host_state_cls(host, node, compute=compute)
self.host_state_map[state_key] = host_state
# We force to update the aggregates info each time a new request
# comes in, because some changes on the aggregates could have been
# happening after setting this field for the first time
host_state.aggregates = [self.aggs_by_id[agg_id] for agg_id in
self.host_aggregates_map[
host_state.host]]
host_state.update_service(dict(service))
self._add_instance_info(context, compute, host_state)
seen_nodes.add(state_key)
# remove compute nodes from host_state_map if they are not active
# * 移除 not active 的節點
dead_nodes = set(self.host_state_map.keys()) - seen_nodes
for state_key in dead_nodes:
host, node = state_key
LOG.info(_LI("Removing dead compute node %(host)s:%(node)s "
"from scheduler"), {'host': host, 'node': node})
del self.host_state_map[state_key]
return six.itervalues(self.host_state_map)
# get_all_host_states主要用來去除不活躍的節點
繼續往下看獲取 Compute Node 資源資訊函式 objects.ComputeNodeList.get_all(context)
的實現。
# nova.object.compute_node:get_all()
@base.remotable_classmethod
def get_all(cls, context):
# 調到了 nova.db.api.compute_node_get_all()
db_computes = db.compute_node_get_all(context)
return base.obj_make_list(context, cls(context), objects.ComputeNode,
db_computes)
#nova.db.api:compute_node_get_all()
def compute_node_get_all(context):
"""Get all computeNodes.
:param context: The security context
:returns: List of dictionaries each containing compute node properties
"""
return IMPL.compute_node_get_all(context)
至此,說明 liberty 版本的 nova-scheduler 還是能夠訪問資料庫的。
問題是: nova-scheduler 是怎麼更新主機資訊的,能夠直接資料庫進行寫操作嗎?
答案是:不能,nova-scheduler 不能夠對資料庫進行寫操作,但是卻可以從資料庫中讀取 Host 資源資料並快取在程序的記憶體中。如下:
# nova.scheduler.host_manager.HostState:__init__()
class HostState(object):
"""Mutable and immutable information tracked for a host.
This is an attempt to remove the ad-hoc data structures
previously used and lock down access.
"""
def __init__(self, host, node, compute=None):
self.host = host
self.nodename = node
# Mutable available resources.
# These will change as resources are virtually "consumed".
self.total_usable_ram_mb = 0
self.total_usable_disk_gb = 0
self.disk_mb_used = 0
self.free_ram_mb = 0
self.free_disk_mb = 0
self.vcpus_total = 0
self.vcpus_used = 0
self.pci_stats = None
self.numa_topology = None
# Additional host information from the compute node stats:
self.num_instances = 0
self.num_io_ops = 0
# Other information
self.host_ip = None
self.hypervisor_type = None
self.hypervisor_version = None
self.hypervisor_hostname = None
self.cpu_info = None
self.supported_instances = None
nova-scheduler 並沒有寫資料庫的操作函式,但是 nova-scheduler 會將資料庫的資料快取到程序記憶體中。這樣就可以在保證了 nova-scheduler 能使用最新的 Host 資源資訊,同時下降低了對資料庫的 I/O 請求。
階段四:從排程器 FilterScheduler 到過濾器 Filters
上面的程式碼中呼叫了 Filters 函式:get_filtered_hosts()
,實現如下:
# nova.scheduler.host_manager.HostManager:get_filtered_hosts()
def get_filtered_hosts(self, hosts, filter_properties,
filter_class_names=None, index=0):
"""Filter hosts and return only ones passing all filters."""
# 下面定義了若干區域性函式,先省略掉
def _strip_ignore_hosts(host_map, hosts_to_ignore):
ignored_hosts = []
for host in hosts_to_ignore:
。。。。
# 返回經過驗證的可用的過濾器;
filter_classes = self._choose_host_filters(filter_class_names)
。。。。
# 呼叫了get_filtered_objects
return self.filter_handler.get_filtered_objects(filters,
hosts, filter_properties, index)
# 繼續跳轉到 get_filtered_objects()
def get_filtered_objects(self, filters, objs, filter_properties, index=0):
list_objs = list(objs)
LOG.debug("Starting with %d host(s)", len(list_objs))
part_filter_results = []
full_filter_results = []
log_msg = "%(cls_name)s: (start: %(start)s, end: %(end)s)"
for filter_ in filters:
if filter_.run_filter_for_index(index):
cls_name = filter_.__class__.__name__
start_count = len(list_objs)
# 關鍵的一句話
objs = filter_.filter_all(list_objs, filter_properties)
if objs is None:
LOG.debug("Filter %s says to stop filtering", cls_name)
return
list_objs = list(objs)
end_count = len(list_objs)
part_filter_results.append(log_msg % {"cls_name": cls_name,
"start": start_count, "end": end_count})
if list_objs:
remaining = [(getattr(obj, "host", obj),
getattr(obj, "nodename", ""))
for obj in list_objs]
full_filter_results.append((cls_name, remaining))
return list_objs
# objs 的 return 又呼叫了 filter_.filter_all(list_objs, filter_properties)
def filter_all(self, filter_obj_list, filter_properties):
for obj in filter_obj_list:
if self._filter_one(obj, filter_properties):
# 符合規則 生產一個obj
yield obj
# 繼續呼叫 _filter_one()
def _filter_one(self, obj, filter_properties):
# 如果符合 Filter 過濾器,就返回 TRUE,否則返回 FALSE
return self.host_passes(obj, filter_properties)
經過一連串的呼叫跳轉,Filter 的過濾工作就完成了。
階段五:Filters 到權重計算與排序
# nova.scheduler.host_manager.HostManager:get_weighed_hosts()
def get_weighed_hosts(self, hosts, weight_properties):
"""Weigh the hosts."""
return self.weight_handler.get_weighed_objects(self.weighers,
hosts, weight_properties)
# nova.weights.BaseWeightHandler:get_weighed_objects()
class BaseWeightHandler(loadables.BaseLoader):
object_class = WeighedObject
def get_weighed_objects(self, weighers, obj_list, weighing_properties):
"""Return a sorted (descending), normalized list of WeighedObjects."""
weighed_objs = [self.object_class(obj, 0.0) for obj in obj_list]
if len(weighed_objs) <= 1:
return weighed_objs
for weigher in weighers:
weights = weigher.weigh_objects(weighed_objs, weighing_properties)
# Normalize the weights
weights = normalize(weights,
minval=weigher.minval,
maxval=weigher.maxval)
for i, weight in enumerate(weights):
obj = weighed_objs[i]
obj.weight += weigher.weight_multiplier() * weight
# 進行排序
return sorted(weighed_objs, key=lambda x: x.weight, reverse=True)
相關推薦
Openstack nova-scheduler 原始碼分析 — Filters/Weighting
目錄 前言 本篇記錄了 Openstack 在建立 Instances 時,nova-scheduler 作為排程器的工作原理和程式碼實現。 Openstack 中會由多個的 Instance 共享同一個 Host,而不是獨佔。所以就需要使用排
105 - kube-scheduler原始碼分析 - predicate演算法註冊
一、predicate註冊過程 今天我們來聊聊predicate函式是怎麼被註冊進去的,也就是要執行的一堆predicate是怎麼成為“選中的孩子”。 程式碼位置:pkg/scheduler/factory/plugins.go:111
深挖Openstack Nova - Scheduler排程策略
深挖Openstack Nova - Scheduler排程策略 一. Scheduler的作用就是在建立例項(instance)時,為例項選擇出合適的主機(host)。這個過程分兩步
【kubernetes/k8s原始碼分析】kube-scheduler 原始碼分析
前言 在 kubernetes 體系中,scheduler 是唯一一個以 plugin 形式存在的模組,這種可插拔的設計方便使用者自定義所需要的排程演算法,所以原始碼路徑為 plugin 目錄下
Kubernetes Scheduler原始碼分析
本文是對Kubernetes 1.5的Scheduler原始碼層面的剖析,包括對應的原始碼目錄結構分析、kube-scheduler執行機制分析、整體程式碼流程圖、核心程式碼走讀分析等內容。閱讀本文前,請先了解kubernetes scheduler原理解析。
OpenStack之Neutron原始碼分析 Neutron-server初始化
從資料夾的命名也基本可以得出該目錄程式碼的作用,幾個重要的資料夾如下: agent: 主要是l3 agent及l3 agent ha的相關程式碼; common: 主要是各底層驅動與linux系統命令的互動層; db: 是neutron各功能與資料庫互動資
Openstack Nova 原始碼分析 — RPC 遠端呼叫過程
目錄 Nova Project Services nova-api:捕獲novaclient傳送過來的HTTP請求,並且將它轉換為AMQP訊息,通過Queue來與別的services
OpenStack之Nova分析——Nova Scheduler排程演算法
上篇文章介紹了Nova Scheduler服務的啟動流程,我們知道Nova Scheduler服務作為一個排程者,其核心便是排程演算法。這篇文章我們就來分析一下Nova Scheduler服務的排程演算法吧。 在配置檔案中,排程演算法預設的驅動類是FilterSchedul
OpenStack Nova深入學習 -- 建立instance的過程之原始碼分析
Nova的核心元件有nova API, nova Conductor,nova Scheduler和nova compute。如下圖所示: nova主要元件的作用: 1). nova API -- 主要是接收HTTP請求(通常來自nova client),將其轉換成命令
nova建立虛機流程原始碼分析 openstack
今天跟大家分享openstack中利用nova建立虛機時的原始碼流程,以便更好的理解openstack雲平臺實現,也有助於故障定位。 建立虛機方式有兩種,一種是通過dashboard雲管理平臺建立,一種是nova命令列方式建立。現在各雲端計算公
OpenStack原始碼分析之Nova-Compute服務啟動過程(icehouse)
學習OpenStack有半年多了,一直都停留在使用和trouble shooting的階段,最近有時間來好好研究了一下程式碼,因為以前是C++/Windows出生的,所以對Linux下面的Python開發不是很熟悉,本文適合一些已經使用過OpenStack並且想要初步瞭解程
nova-scheduler模組排程過程分析
openstack在建立虛擬機器或進行虛擬機器的冷遷移時根據在nova.conf檔案中scheduler_default_filters和scheduler_available_filters配置的過濾器, 對主機進行篩選,選擇合適的目的主機。 本文根據nova M版原始碼分析排程不同過濾器
openstack虛擬機器resize原始碼分析(更新至排程計算節點執行任務)
openstack虛擬機器resize原始碼分析 resize過程python-client端debug [[email protected] ~(keystone_admin)]# nova --debug resize 2001bdd5-8a2e
openstack-nova原始碼虛擬機器建立流程
nova-api接收到訊息後,呼叫nova\api\openstack\compute\servers.py 中ServersController類的create()方法, 部分程式碼: try: inst_type = flavors.get_f
Ceilometer 20、prometheus-openstack-exporter原始碼分析
1 引言 prometheus-openstack-exporter是用於提供openstack各元件服務狀態資訊給prometheus的專案。 該專案主要分為兩部分: 1) 預設每隔30秒向openstack各元件傳送請求,獲取各個元件服務的狀態並寫入到快取中。 2) 開啟一個tcp伺服器,
Centos7 Openstack nova模組安裝與分析(Queens版本)
一、Nova框架 Nova Api :提供統一Rest-api風格API介面,作為Nova元件的入口,接受使用者的請求 Nova Scheduler :負責排程,將例項分配到具體計算節點 Nova Conductor :負責Nova與資料庫進行
nova原始碼分析--API(2)
/etc/nova/api-paste.ini檔案中的定義了以下三個composite: [composite:osapi_compute] use = call:nova.api.openstack.urlmap:urlmap_factory /: oscomputeve
scheduler的原始碼分析_Kubernetes中文社群
很長時間沒有寫文章,一直在啃kubernetes文件,本來立志一定要讀完所有的文件。還有它的最佳實踐openshift的文件。但目前為止,我並沒有讀完kubernetes的文件。當前,我們有需求需要客製化kubernetes的排程函式,所以開始研究kube-scheduler的程式碼。 kub
Kubernetes23--kube-scheduler原始碼--優選過程分析
kubernetes/pkg/scheduler/core/generic_scheduler.go 優選過程分析 優選函式入口 priorityList, err := PrioritizeNodes(pod, g.cachedNodeInfoMap, metaPrioritiesIn
【原創】k8s原始碼分析-----kube-scheduler
原始碼為k8s v1.1.1穩定版本 一、主要流程 1、main入口 原始碼在k8s.io/kubernetes/plugin/cmd/kube-scheduler 這種封裝是k8s