中文

杂谈 os包的功能 Amaze UI中的组件 Skeleton CSS的用武之地 SVG Introduction mysql数据库迁移 How agent and message bus work in the CloudStack platform? 剖析cloudstack中虚机的创建过程 AngularJS与LoopBack LoopBack实战 Sails使用手册 在NodeJS中使用MySQL数据库 在NodeJS中使用Sqlite 实战XLRD类库 上下文中给模板中的变量赋值 使用Pecan创建restful API 服务 使用python语言操作excel文件 Magento性能调优 Celery的世界 Linux下如何快速查找文件和内容 MySQL常用资源 为PHP设置服务器(Apache/Nginx)环境变量 MySQL大量数据插入各种方法性能分析与比较 Laravel中使用Redis作为队列系统的工作流程 使用Supervisor来管理你的Laravel队列 在Laravel中使用自己的类库三种方式 用Xdebug和Sublime调试PHP代码 用Laravel+Grunt+Bower管理你的应用 PHP Socket的使用 Python脚本--下载合并SAE日志 PHP命名空间及自动加载 SVN 常用资源 Shell 常用资源 Python 常用资源 PHP 常用资源 jQuery 常用资源 JavaScript 常用资源 HTML 常用资源 Git 常用资源 Linux下多个命令连续执行方法 基于CSS3实现尖角面包屑 部署Ceilometer到已有环境中 更新前端框架到Bootstrap3 OpenStack Ceilometer数据存储与API源码解析 OpenStack Ceilometer中的Pipeline机制 OpenStack Ceilometer Compute Agent源码解读 学习Python动态扩展包stevedore 学习Python的ABC模块 Python包管理工具setuptools详解 OpenStack Horizon 中文本地化 安装MySQL和MongoDB的WEB管理界面 给Git或者APT设置goagent代理 WSGI学习 在虚拟机单机部署OpenStack Grizzly python包工具之间的关系 给OpenStack创建Ubuntu镜像 OpenStack Grizzly Multihost部署文档 HTML中meta标签viewpoint的作用 交互式编程-IPython 页面提速之——数据缓存 给OpenStack创建Win7镜像 Ceilometer的命令行使用 给OpenStack创建Windows XP镜像 概念模型、逻辑模型、物理模型的区别 Bootstrap常用资源 OpenStack监控项目Ceilometer的一些术语 服务器自动化部署及运维常见工具 Linux下开启Libvirtd的tcp监控 VNC和远程桌面的区别 调试和修改OpenStack中的Horizon部分 win7快速打开应用程序或文件 JavaScript变量作用域 git创建远程库 MySQL远程访问 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通过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.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代码运行机制,对它进行二次开发也有很大帮助,再有内容以后再补充