问题导读
Ceilometer通过哪个模块去polling虚拟机或者OpenStack中需要的信息?
Compute Agent的功能是什么?
agent.py包含了那两个类?
不知道代码干了什么就盲目去读的话,基本是事倍功半的结果。 Ceilometer通过Agent模块去polling虚拟机或者OpenStack中需要的信息,然后将它传送至Ceilometer Event Bus中去。对于虚拟机的具体信息(CPU,Memory,Disk I/O,Network I/O)需要去虚拟机所运行的节点上获取(其实使用libvirt可以直接tcp到哪个节点上),所以需要将Agent模块丢到计算机点上,然后通过Libvirt获取虚拟机状态,这就是Compute Agent的功能。 入口文件Compute Agent以OpenStack Service(OpenStack服务分为Service和WSGI Service)的形式运行在计算节点上,它由一个可执行文件开启,这个可执行文件安装时生成(目前最新版本,比Grizzly新比Havana旧……)。如果是Grizzly版本,可以去ceilometer/bin下找ceilometer-agent-compute文件,如果是和我用的一样,选最新版本,就直接看ceilometer/setup.cfg文件
- console_scripts =
- ceilometer-agent-central = ceilometer.central.manager:agent_central
- ceilometer-agent-compute = ceilometer.compute.manager:agent_compute
- ceilometer-dbsync = ceilometer.storage:dbsync
- ceilometer-collector = ceilometer.collector.service:collector
- ceilometer-collector-udp = ceilometer.collector.service:udp_collector
复制代码
这里表明ceilometer-agent-compute从ceilometer.compute.manager:agent_compute运行 入口函数入口函数很简单,基本就把compute的功能写清楚了,我这个版本在ceilometer/ceilometer/compute/manager.py中 - def agent_compute():
- eventlet.monkey_patch()
- gettextutils.install('ceilometer')
- service.prepare_service(sys.argv)
- os_service.launch(rpc_service.Service(cfg.CONF.host,
- 'ceilometer.agent.compute',
- AgentManager())).wait()
复制代码
前4行都是准备步骤,包括参数获取等功能,真正实现功能的是最后一行 - os_service.launch(rpc_service.Service(cfg.CONF.host,'ceilometer.agent.compute',AgentManager())).wait()
复制代码
我再把它展开 - ceilometer.openstack.common.service.launch(
- ceilometer.openstack.common.rpc.service.Service(
- cfg.CONF.host,'ceilometer.agent.compute',AgentManager()
- )
- ).wait()
复制代码
两个Service函数的作用都是OpenStack服务的基本作用————启动一个服务(关于服务我有时间再详细写一个分析服务的博客),然后启动服务后,执行AgentManager()(它继承自ceilometer.agent.AgentManager)中的initialize_service_hook()函数 agent.py这个模块中包含了非常重要的两个类AgentManager和PollingTask,Compute Agent和Central Agent的Manager都继承自AgentManger 在AgentManager的构造函数中,有这么一句 - self.pollster_manager = extension_manager
复制代码
它是一种动态加载模块的机制(见 学习Python动态扩展包stevedore),它将载入所有它可以用来获取虚拟机状态的模块。在Compute Agent的构造函数中说明了是namespace='ceilometer.poll.compute',即setup.cfg中的: - ceilometer.poll.compute =
- diskio = ceilometer.compute.pollsters:DiskIOPollster
- cpu = ceilometer.compute.pollsters:CPUPollster
- net = ceilometer.compute.pollsters:NetPollster
- instance = ceilometer.compute.pollsters:InstancePollster
复制代码
这样就让Agent明白了它要调用哪些Pollster来获取虚拟机信息 构造函数中还有一个很重要的东西 - self._inspector = virt_inspector.get_hypervisor_inspector()
复制代码
inspector的作用是获取虚拟机信息的,它现在只有一种实现方式—Libvirt 接着是启动服务时运行的那个函数initialize_service_hook()了 - def initialize_service_hook(self, service):
- self.service = service
- for interval, task in self.setup_polling_tasks().iteritems():
- self.service.tg.add_timer(interval,
- self.interval_task,
- task=task)
复制代码
大概看一下这个函数,它利用setup_polling_tasks()返回的迭代器(interval是间隔时长,task是执行的任务),将interval_task(task)以interval的间隔执行 - def interval_task(self, task):
- task.poll_and_publish()
复制代码
那么task是什么呢?这个就是前面提到的PollingTask类了,Compute Agent的PollingTask在manager.py文件中 - class PollingTask(agent.PollingTask):
- def poll_and_publish_instances(self, instances):
- with self.publish_context as publisher:
- for instance in instances:
- if getattr(instance, 'OS-EXT-STS:vm_state', None) != 'error':
- for pollster in self.pollsters:
- publisher(list(pollster.obj.get_counters(self.manager,instance)))
-
- def poll_and_publish(self):
- self.poll_and_publish_instances(
- self.manager.nv.instance_get_all_by_host(cfg.CONF.host))
复制代码
我只写了摘了必要部分,poll_and_publish通过nova_client获得现有的所有虚拟机,然后调用poll_and_pusblish_instances 通过pollster.get_counters获得虚拟机的数据,然后通过pipeline将数据转换和传送给publisher,由publisher发送到MQ中去。这里涉及到的pipeline和publisher单独拿出来研究,之后再写。 pollsters.py这个文件位于ceilometer/ceilometer/compute下,它是轮询虚拟机信息的主要代码所在 以cpu为例说明 - class CPUPollster(plugin.ComputePollster):
- def get_counters(self, manager, instance):
- instance_name = _instance_name(instance)
- cpu_info = manager.inspector.inspect_cpus(instance_name)
- yield make_counter_from_instance(instance,
- name='cpu',
- type=counter.TYPE_CUMULATIVE,
- unit='ns',
- volume=cpu_info.time,
- )
复制代码
这里省略了大部分代码,只是给出一个Pollster的写法,它需要一个get_counters的函数,用来返回货取到的虚拟机数据。执行获取的代码来自于inspector,也就是ceilometer/ceilometer/compute/virt/inspector.py中的功能了 inspector.pyinspector要做的就是去获得虚拟机数据了,它可以有多重方式,暂时ceilometer只写了基于libvirt获得的。暂时inspector可以做的内容主要有一下几个: - def inspect_instances(self):
- def inspect_cpus(self, instance_name):
- def inspect_vnics(self, instance_name):
- def inspect_disks(self, instance_name):
复制代码
|