探索 OpenStack 之(17):計量模塊 Ceilometer 中的數據收集機制


本文將闡述 Ceilometer 中的數據收集機制。Ceilometer 使用三種機制來收集數據:

  • Notifications:Ceilometer 接收 OpenStack 其它服務發出的 notification message
  • Polling:直接從 Hypervisor 或者 使用 SNMP 從host machine,或者使用 OpenStack 其它服務的 API 來獲取數據。
  • RESTful API:別的 application 使用 Ceilometer 的 REST API 創建 samples。

1. Notifications

1.1 被 Ceilometer 處理的 notifications

所有的 OpenStack 服務都會在執行了某種操作或者狀態變化時發出 notification。一些 nofication message 會包含 metering 需要的數據,這部分消息會被ceilometer 處理並轉化為samples。下表列出了目前 Ceilometer 所處理的各服務的notification: 

(參考文檔: http://docs.openstack.org/admin-guide-cloud/content/section_telemetry-notifications.html

Table 8.1. Consumed event types from OpenStack services
OpenStack service Event types Note
OpenStack Compute

scheduler.run_instance.scheduled,scheduler.select_destinations

compute.instance.*

For a more detailed list of Compute notifications please check the System Usage Data wiki page.
Bare metal module for OpenStack hardware.ipmi.*  
OpenStack Image Service

image.update,image.upload,image.delete,image.send

The required configuration for Image service can be found in the Configure the Image Service for Telemetry section section in theOpenStack Installation Guide.
OpenStack Networking

floatingip.create.end,floatingip.update.*,floatingip.exists

network.create.end,network.update.*,network.exists

port.create.end,port.update.*,port.exists

router.create.end,router.update.*,router.exists

subnet.create.end,subnet.update.*,subnet.exists

l3.meter

 
Orchestration module

orchestration.stack.create.end,orchestration.stack.update.end

orchestration.stack.delete.end,orchestration.stack.resume.end

orchestration.stack.suspend.end

 
OpenStack Block Storage

volume.exists,volume.create.*,volume.delete.*

volume.update.*,volume.resize.*,volume.attach.*

volume.detach.*

snapshot.exists,snapshot.create.*

snapshot.delete.*,snapshot.update.*

The required configuration for Block Storage service can be found in the Add the Block Storage service agent for Telemetry sectionsection in the OpenStack Installation Guide.

1.2 Cinder Volume Notificaitons 發出過程

 Cinder 中 /cinder/volume/util.py 的 notify_about_volume_usage 函數負責調用 oslo.message 的方法來發出 volume usage 相關的 notificaiton message:

def notify_about_volume_usage(context, volume, event_suffix,
                              extra_usage_info=None, host=None):
    if not host:
        host = CONF.host
    if not extra_usage_info:
        extra_usage_info = {}
    usage_info = _usage_from_volume(context, volume, **extra_usage_info)
    rpc.get_notifier("volume", host).info(context, 'volume.%s' % event_suffix, usage_info)

下圖顯示了該函數被調用的地方。可見:

  • Controller 節點上的 cinder-api          會發出 Info 級別的 volume.update.* notificaiton
  • Controller 節點上的 cinder-scheduler 會發出 Info 級別的volume.create.* notification
  • Volume    節點上的 cinder-volume    會發出 Info 級別的別的 volume.*.* notificaiton

再看看 notification 發出的時機。以 volume.update.* 為例:

 @wsgi.serializers(xml=VolumeTemplate)
    def update(self, req, id, body):
        """Update a volume."""
       ...

        try:
            volume = self.volume_api.get(context, id, viewable_admin_meta=True)
            volume_utils.notify_about_volume_usage(context, volume, 'update.start') #開始更新前發出 volume.update.start notificaiton
            self.volume_api.update(context, volume, update_dict)
        except exception.NotFound:
            msg = _("Volume could not be found")
            raise exc.HTTPNotFound(explanation=msg)

        volume.update(update_dict)
        utils.add_visible_admin_metadata(volume)
        volume_utils.notify_about_volume_usage(context, volume, 'update.end') #更新結束后發出 volume.update.end notification
        return self._view_builder.detail(req, volume)

在來看看使用 notificaiton driver 是如何發出 notification 的:

// /oslo/messaging/notify/_impl_messaging.py,
// notificaiton driver 由 cinder.conf 配置項 notification_driver = cinder.openstack.common.notifier.rpc_notifier 指定,它實際對應的是 oslo.messaging.notify._impl_messaging:MessagingDriver (對應關系由 cinder/setup.cfg 定義)
def
notify(self, ctxt, message, priority, retry): priority = priority.lower() for topic in self.topics: target = messaging.Target(topic='%s.%s' % (topic, priority)) #topic 是 notificaitons.info,因此會被發到同名的queue。使用默認的由 cinder.conf 中配置項 control_exchange 指定的exchange,其默認值為 openstack。而 topic 中的 "notifications" 由配置項 #notification_topics=notifications 指定。 try: self.transport._send_notification(target, ctxt, message, version=self.version, retry=retry) #Send a notify message on a topic except Exception: ......

因此,為了 Cinder 能正確發出 notificaiton 被 Ceilometer 接收到,需要在 controller 節點和 cinder-volume 節點上的 cinder.conf 中做如下配置:

control_exchange = cinder #因為queue "notificaitons.info" 是 bind 到 "cinder" exchange 上的,所以 cinder 的 notificaiton message 需要被發到 “cinder” exchange。
notification_driver = cinder.openstack.common.notifier.rpc_notifier #在某些時候 /oslo/messaging/notify/_impl_messaging.py 不存在,需要手工從別的地方拷貝過來

Cinder 還有會同樣的方式發出別的資源的notification:

 81: rpc.get_notifier("volume", host).info(context, 'volume.%s' % event_suffix,  
113: rpc.get_notifier('snapshot', host).info(context, 'snapshot.%s' % event_suffix,  
129: rpc.get_notifier('replication', host).info(context, 'replication.%s' % suffix,  
145: rpc.get_notifier('replication', host).error(context, 'replication.%s' % suffix,  
174: rpc.get_notifier("consistencygroup", host).info(context,'consistencygroup.%s' % event_suffix,  
204: rpc.get_notifier("cgsnapshot", host).info( 

但是目前 Ceilometer 只處理 volume 和 snapshot notificaiton message。

1.3 Ceilometer 處理 Volume notifications 的過程

Ceilometer 從 AMQP message queue "notifications.info" 中獲取 notificaiton 消息。該 queue 的名字由 ceilometer.conf 中的配置項 notification_topics = notifications 指定。它會按照一定的方法將 notification 轉化為 ceilometer event,然后再轉化為 samples。

1.4 Cinder 到 Ceilometer 全過程

(1) cinder-* 發出 event-type 為 "volume.*.*" topic 為"<topic>.<priority>" 的消息 到 類型為 topic 名為 <service> 的exchange

(2)exchange <service> 和 queue "<topic>.<priority>" 使用 routing-key "<topic>.<priority>" 綁定

(3)notificaiton message 被 exchange 轉發到 queue "<topic>.<priority>"

(4)ceilometer-agent-notification 從 queue "<topic>.<priority>" 中獲取 message

這里對cinder 來說:

  • <service> 是 "cinder"。需要注意 cinder 默認的 control exchange 是 "openstack",所以使用 ceilometer 時需要將其修改為 "cinder"。
  • <topic> 是 "notificaitons",由 cinder.conf 中的配置項 notification_topics=notifications 指定。
  • <priority> 是 "info",由 cinder 代碼中寫死的。
  • notificaiton message 的數據內容可參考 https://wiki.openstack.org/wiki/SystemUsageData

 

2. Polling

Ceilometer 的 polling 機制使用三種類型的 agent:

  • Compute agent
  • Central agent
  • IPMI agent

在 Kilo 版本中,這些 agent 都屬於 ceilometer-polling,不同的是,每種agent使用不同的 polling plug-ins (pollsters) 

2.1 Central agent

該 agent 負責使用個 OpenStack 服務的 REST API 來獲取 openstack 資源的各種信息,以及通過 SNMP 來獲取 hardware 資源的信息。這些資源包括:

  • OpenStack Networking

  • OpenStack Object Storage

  • OpenStack Block Storage

  • Hardware resources via SNMP

  • Energy consumption metrics via Kwapi framework

該 agent 收集到的 samples 會通過 AMQP 發給 Ceilometer Collector 或者外部系統。

2.2 Compute agent

Compute agent 安裝在 compute node 上,負責收集在上面運行的虛機的使用數據。它是通過調用 hypervisor SDK 來收集數據的。到目前為止支持的hypervisor包括:

  • Kernel-based Virtual Machine (KVM)
  • Quick Emulator (QEMU)
  • Linux Containers (LXC)
  • User-mode Linux (UML)
  • Hyper-V
  • XEN
  • VMWare vSphere

除了虛機外,該 agent 還能夠收集 compute 節點 cpu 的數據。這功能需要配置 nova.conf 文件中的 compute_monitors 項為 ComputeDriverCPUMonitor。

2.3 IPMI agent

IPMI agent 負責在 compute 節點上收集 IPMI 傳感器(sensor)的數據,以及Intel Node Manager 的數據。

3. 使用 Ceilometer REST API 創建 samples

$ ceilometer sample-create -r 37128ad6-daaa-4d22-9509-b7e1c6b08697 -m memory.usage --meter-type gauge --meter-unit MB --sample-volume 48
+-------------------+--------------------------------------------+
| Property          | Value                                      |
+-------------------+--------------------------------------------+
| message_id        | 6118820c-2137-11e4-a429-08002715c7fb       |
| name              | memory.usage                               |
| project_id        | e34eaa91d52a4402b4cb8bc9bbd308c1           |
| resource_id       | 37128ad6-daaa-4d22-9509-b7e1c6b08697       |
| resource_metadata | {}                                         |
| source            | e34eaa91d52a4402b4cb8bc9bbd308c1:openstack |
| timestamp         | 2014-08-11T09:10:46.358926                 |
| type              | gauge                                      |
| unit              | MB                                         |
| user_id           | 679b0499e7a34ccb9d90b64208401f8e           |
| volume            | 48.0                                       |
+-------------------+--------------------------------------------+

4. 收集 Neutron Bandwidth samples

Havana 版本中添加該功能。與 Ceilometer 其他采集方式不同的是,bandwidth 的采集是通過 neutron-meter-agent 收集,然后 push 到 oslo-messaging,ceilometer-agent-notification通過監聽消息隊列來收取bandwidth信息。

其實現是在 L3 router 層次來收集數據,因此需要操作員配置 IP 范圍以及設置標簽(label)。比如,我們加兩個標簽,一個表示內部網絡流量,另一個表示外部網絡流量。每個標簽會計量一定IP范圍內的流量。然后,每個標簽的帶寬的測量數據會被發到 MQ,然后被 Ceilometer 收集到。

參考鏈接:

https://wiki.openstack.org/wiki/Neutron/Metering/Bandwidth

https://openstackr.wordpress.com/2014/05/23/bandwidth-monitoring-with-neutron-and-ceilometer/

5. 收集物理設備samples

5.1 使用 kwapi kwapi 收集設備能耗數據

有時候我們需要收集 OpenStack 集群中服務器的能耗數據。kwapi 是采集物理機能耗信息的項目,agent-central 組件通過kwapi暴露的api來收集物理機的能耗信息。目前 kwapi 提供兩個類型的計量數據:
  • Energy (cumulative type): 表示 kWh.
  • Power (gauge type): 表示 watts.

Ceilometer central agent 的 pollers 直接調用 kwapi 的 API 來獲取 samples。 

參考文檔:

http://kwapi.readthedocs.org/en/latest/architecture.html

http://blog.zhaw.ch/icclab/collecting-energy-consumption-data-using-kwapi-in-openstack/

http://perso.ens-lyon.fr/laurent.lefevre/greendayslux/GreenDays_Rossigneux.pdf

5.2 使用 snmp 協議收集硬件的CPU、MEM、IO等信息

在 IceHouse 中新增該功能。

參考文檔:http://www.cnblogs.com/smallcoderhujin/p/4150368.html

6. 基於 OpenDayLight  收集 SDN samples

OpenDayLight  是 SDN 解決方案的開源項目,它的規范中包括暴露 REST API 接口來提供SDN內部的一些信息,Ceilometer Central agent 正是通過這些 API 來收集網絡組件的信息。
 
基本實現:
  1. Central agent 不直接調用 OpenDayLight 的 REST API,而是實現了一個 driver 來調用。
  2. Driver 調用 REST API 收集統計數據,返回 volume、resource id 和 metadata 給 pollster。
  3. Pollster 負責產生 samples。

實現代碼在OpenStack 的 \ceilometer\network\statistics 目錄中。

 
參考鏈接:
 
總結圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM