分享

Compute Agent功能

pig2 发表于 2014-11-24 17:39:06 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 17288

问题导读

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文件
  1. console_scripts =
  2.     ceilometer-agent-central = ceilometer.central.manager:agent_central
  3.     ceilometer-agent-compute = ceilometer.compute.manager:agent_compute
  4.     ceilometer-dbsync = ceilometer.storage:dbsync
  5.     ceilometer-collector = ceilometer.collector.service:collector
  6.     ceilometer-collector-udp = ceilometer.collector.service:udp_collector
复制代码


这里表明ceilometer-agent-compute从ceilometer.compute.manager:agent_compute运行
入口函数
入口函数很简单,基本就把compute的功能写清楚了,我这个版本在ceilometer/ceilometer/compute/manager.py中
  1. def agent_compute():
  2.     eventlet.monkey_patch()
  3.     gettextutils.install('ceilometer')
  4.     service.prepare_service(sys.argv)
  5.     os_service.launch(rpc_service.Service(cfg.CONF.host,
  6.                                           'ceilometer.agent.compute',
  7.                                           AgentManager())).wait()
复制代码


前4行都是准备步骤,包括参数获取等功能,真正实现功能的是最后一行
  1. os_service.launch(rpc_service.Service(cfg.CONF.host,'ceilometer.agent.compute',AgentManager())).wait()
复制代码


我再把它展开
  1. ceilometer.openstack.common.service.launch(
  2.     ceilometer.openstack.common.rpc.service.Service(
  3.         cfg.CONF.host,'ceilometer.agent.compute',AgentManager()
  4.         )
  5.     ).wait()
复制代码


两个Service函数的作用都是OpenStack服务的基本作用————启动一个服务(关于服务我有时间再详细写一个分析服务的博客),然后启动服务后,执行AgentManager()(它继承自ceilometer.agent.AgentManager)中的initialize_service_hook()函数
agent.py
这个模块中包含了非常重要的两个类AgentManager和PollingTask,Compute Agent和Central Agent的Manager都继承自AgentManger
在AgentManager的构造函数中,有这么一句
  1. self.pollster_manager = extension_manager
复制代码


它是一种动态加载模块的机制(见学习Python动态扩展包stevedore),它将载入所有它可以用来获取虚拟机状态的模块。在Compute Agent的构造函数中说明了是namespace='ceilometer.poll.compute',即setup.cfg中的:
  1. ceilometer.poll.compute =
  2.     diskio = ceilometer.compute.pollsters:DiskIOPollster
  3.     cpu = ceilometer.compute.pollsters:CPUPollster
  4.     net = ceilometer.compute.pollsters:NetPollster
  5.     instance = ceilometer.compute.pollsters:InstancePollster
复制代码


这样就让Agent明白了它要调用哪些Pollster来获取虚拟机信息
构造函数中还有一个很重要的东西
  1. self._inspector = virt_inspector.get_hypervisor_inspector()
复制代码


inspector的作用是获取虚拟机信息的,它现在只有一种实现方式—Libvirt
接着是启动服务时运行的那个函数initialize_service_hook()了
  1. def initialize_service_hook(self, service):
  2.     self.service = service
  3.     for interval, task in self.setup_polling_tasks().iteritems():
  4.         self.service.tg.add_timer(interval,
  5.                                   self.interval_task,
  6.                                   task=task)
复制代码


大概看一下这个函数,它利用setup_polling_tasks()返回的迭代器(interval是间隔时长,task是执行的任务),将interval_task(task)以interval的间隔执行
  1. def interval_task(self, task):
  2.     task.poll_and_publish()
复制代码


那么task是什么呢?这个就是前面提到的PollingTask类了,Compute Agent的PollingTask在manager.py文件中
  1. class PollingTask(agent.PollingTask):
  2.     def poll_and_publish_instances(self, instances):
  3.         with self.publish_context as publisher:
  4.             for instance in instances:
  5.                 if getattr(instance, 'OS-EXT-STS:vm_state', None) != 'error':
  6.                     for pollster in self.pollsters:
  7.                         publisher(list(pollster.obj.get_counters(self.manager,instance)))
  8.     def poll_and_publish(self):
  9.         self.poll_and_publish_instances(
  10.             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为例说明
  1. class CPUPollster(plugin.ComputePollster):
  2.     def get_counters(self, manager, instance):
  3.         instance_name = _instance_name(instance)
  4.         cpu_info = manager.inspector.inspect_cpus(instance_name)
  5.         yield make_counter_from_instance(instance,
  6.                                          name='cpu',
  7.                                          type=counter.TYPE_CUMULATIVE,
  8.                                          unit='ns',
  9.                                          volume=cpu_info.time,
  10.                                          )
复制代码


这里省略了大部分代码,只是给出一个Pollster的写法,它需要一个get_counters的函数,用来返回货取到的虚拟机数据。执行获取的代码来自于inspector,也就是ceilometer/ceilometer/compute/virt/inspector.py中的功能了
inspector.py
inspector要做的就是去获得虚拟机数据了,它可以有多重方式,暂时ceilometer只写了基于libvirt获得的。暂时inspector可以做的内容主要有一下几个:
  1. def inspect_instances(self):
  2. def inspect_cpus(self, instance_name):
  3. def inspect_vnics(self, instance_name):
  4. def inspect_disks(self, instance_name):
复制代码


通过Libvirt获得虚拟机信息方法应该在之前讲kanyun worker原理的时候说到了,再这里就不赘述了

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条