pig2 发表于 2014-11-24 17:39:06

Compute Agent功能


问题导读

Ceilometer通过哪个模块去polling虚拟机或者OpenStack中需要的信息?
Compute Agent的功能是什么?
agent.py包含了那两个类?

static/image/hrline/4.gif














不知道代码干了什么就盲目去读的话,基本是事倍功半的结果。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):

通过Libvirt获得虚拟机信息方法应该在之前讲kanyun worker原理的时候说到了,再这里就不赘述了
页: [1]
查看完整版本: Compute Agent功能