本文將闡述 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)
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 收集設備能耗數據
- 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
- Central agent 不直接調用 OpenDayLight 的 REST API,而是實現了一個 driver 來調用。
- Driver 調用 REST API 收集統計數據,返回 volume、resource id 和 metadata 給 pollster。
- Pollster 負責產生 samples。
實現代碼在OpenStack 的 \ceilometer\network\statistics 目錄中。
