技术

IT这个行当之需求与时间管理 golang结构体和包中的类型或基础类型定义方法 golang中结构体的初始化方法(new方法) 项目管理总结 python函数式编程之-装饰器(Decorators) python文件批量处理 Go,互联网时代的C Python推导式演变(Comprehensions) 项目管理感悟 golang学习简单例子 了解GitHub工作流【译】 PHP Socket的使用 Apache 日志文件格式及简单处理 Python脚本--下载合并SAE日志 PHP命名空间及自动加载 基于CSS3实现尖角面包屑 部署Ceilometer到已有环境中 OpenStack Ceilometer Collector代码解读 OpenStack Ceilometer数据存储与API源码解析 OpenStack Ceilometer中的Pipeline机制 OpenStack Ceilometer Compute Agent源码解读 学习Python动态扩展包stevedore 学习Python的ABC模块 Python包管理工具setuptools详解 OpenStack Horizon 中文本地化 WSGI学习 在虚拟机单机部署OpenStack Grizzly 学习使用python打包工具distutils python包工具之间的关系 给OpenStack创建Ubuntu镜像 OpenStack Grizzly Multihost部署文档 为什么使用pip而不是easy_install HTML中meta标签viewpoint的作用 交互式编程-IPython 页面提速之——数据缓存 给OpenStack创建Win7镜像 Ceilometer的命令行使用 部署一个ceilometer-horizon项目 给OpenStack创建Windows XP镜像 几种企业的存储系统 概念模型、逻辑模型、物理模型的区别 五中常见的开源协议整理(BSD,Apache,GPL,LGPL,MIT) OpenStack监控项目Ceilometer的一些术语 VNC和远程桌面的区别 OpenStack Ceilometer项目简介 虚拟化与云计算中KVM,Xen,Qemu的区别和联系 调试和修改OpenStack中的Horizon部分 JavaScript变量作用域 kanyun worker原理 kanyun server服务 在OpenStack中部署kanyun kanyun的api-client命令 sae下的python开发部署和一个简单例子 OpenStack Nova内部机制 PHP可变变量 JS中防止浏览器屏蔽window.open PHP操作Session的原理及提升安全性时的一个问题

标签


OpenStack Ceilometer Compute Agent源码解读

2013年06月11日

Compute Agent功能

不知道代码干了什么就盲目去读的话,基本是事倍功半的结果。

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

这个模块中包含了非常重要的两个类AgentManagerPollingTask,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通过novaclient获得现有的所有虚拟机,然后调用`pollandpusblishinstances`

通过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.py

inspector要做的就是去获得虚拟机数据了,它可以有多重方式,暂时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原理的时候说到了,再这里就不赘述了

TODO

基本先写到这里,对于了解Compute Agent代码运行机制,对它进行二次开发也有很大帮助,再有内容以后再补充