Rate Monasca / Ceilometer metrics with CloudKitty
This blogpost describes how to install and configure Monasca-Ceilometer and CloudKitty in order to allow CloudKitty to collect metrics through Monasca’s API.
Intended audience: OpenStack administrators, familiar with Ceilometer and CloudKitty. Having experience with Monasca is a big plus.
By Luka Peschke, Cloud Consultant and CloudKitty Developer @ Objectif Libre
Since the OpenStack Queens release, it is possible to integrate CloudKitty (OpenStack’s official rating component) with Monasca. In order to achieve this, we will install Monasca-Ceilometer. This projects allows Ceilometer to publish metrics to Monasca.
Pre-requisites
For the following steps, you will need a running OpenStack cloud with Monasca and Ceilometer (Ceilometer must be installed from source).
Step 1: Installing Monasca-Ceilometer
First, clone monasca-ceilometer:
$ git clone https://github.com/openstack/monasca-ceilometer /tmp/monasca-ceilometer
$ cd /tmp/monasca-ceilometer/ceilosca/ceilometer
Then, copy the relevant files to Ceilometer’s source directory:
$ cp monasca_client.py $CEILO_SOURCE_DIR/ceilometer/ $ cp publisher/* $CEILO_SOURCE_DIR/ceilometer/publisher/ $ cp -r ceilosca_mapping/ $CEILO_SOURCE_DIR/ceilometer/ $ cp opts.py monasca_ceilometer_opts.py $CEILO_SOURCE_DIR/ceilometer/
You will also need to copy some configuration files:
$ cp /tmp/monasca-ceilometer/etc/ceilometer/monasca_pipeline.yaml \ /tmp/monasca-ceilometer/etc/ceilometer/ceilosca_pipeline.yaml \ /tmp/monasca-ceilometer/etc/ceilometer/monasca_field_definitions.yaml \ /etc/ceilometer/
Once the files are copied, you will need to edit Ceilometer’s setup.cfg
file. Add the following line to the ceilometer.sample.publisher =
section:
monasca = ceilometer.publisher.monclient:MonascaPublisher
Event publishing isn’t supported in Monasca-Ceilometer yet, so you don’t have to edit ceilometer.event.publisher
.
Ceilometer’s configuration files need to be adapted. Edit /etc/ceilometer/pipeline.yaml
to publish metrics to Monasca. For example:
sources: - name: meter_source meters: - "*" sinks: - meter_sink [...] sinks: - name: meter_sink transformers: publishers: - monasca://http://10.0.2.15:8070/v2.0
Then, edit ceilometer.conf
:
# Add the following section: [monasca] service_auth_url = $KEYSTONE_URL service_region_name = RegionOne service_password = ******** service_username = ceilometer service_project_name = service service_domain_name = Default service_auth_type = password enable_api_pagination = True database_retry_interval = 5 database_max_retries = 5 # Add the following to the [database] section: [database] connection = monasca://http://10.0.2.15:8070/v2.0
You may also want to edit /etc/ceilometer/monasca_field_definitions.yml
to add some dimensions (attributes) to your resources.
Once the config files are correct, (re)install Ceilometer:
$ cd $CEILO_SOURCE_DIR $ pip install . $ pip install python-monascaclient
Finally, add the “monasca-user” role to Ceilometer:
$ openstack role add --user ceilometer --project service monasca-user
You may now (re)start the different Ceilometer services. As Ceilometer publishes metrics identified on the “service” tenant, you can list your metrics like this:
$ openstack project list +----------------------------------+-------------------+ | ID | Name | +----------------------------------+-------------------+ | 9a7d3fdd2eec47b1b11a9c5a265e3d87 | myproject | | e5f331d9e8d1469aba1c80e5a79cdd01 | service | | f7b7b3560b8f455bbf406bd0cc12b1c3 | admin | +----------------------------------+-------------------+ # List metrics for 'myproject' tenant $ monasca metric-list --tenant-id e5f331d9e8d1469aba1c80e5a79cdd01 \ --dimensions project_id=9a7d3fdd2eec47b1b11a9c5a265e3d87
Step 2: Installing CloudKitty
First, clone and install Cloudkitty:
$ git clone https://github.com/openstack/cloudkitty -b stable/queens /opt/cloudkitty
$ pip install ./cloudkitty
# Copy the config files
$ mkdir /etc/cloudkitty
$ cp /opt/cloudkitty/etc/cloudkitty/* /etc/cloudkitty
Then, create the ‘cloudkitty’ database:
$ mysql -uroot -padminpass << EOF
CREATE DATABASE cloudkitty;
GRANT ALL PRIVILEGES ON cloudkitty.* \
TO $CK_DB_USER@'%' IDENTIFIED BY $CK_DB_PASS;
FLUSH PRIVILEGES;
EOF
Now, we need to add some basic configuration to Cloudkitty:
$ cat > /etc/cloudkitty/cloudkitty.conf << EOF
[DEFAULT]
debug = True
transport_url = rabbit://$RABBIT_USER:$RABBIT_PASS@$RABBIT_URL:$RABBIT_PORT/
# [oslo_messaging_notifications]
# topics = notifications
[service_credentials]
auth_url = $KEYSTONE_URL
region_name = RegionOne
password = ******
username = cloudkitty
project_name = service
project_domain_id = default
user_domain_id = default
auth_type = password
[keystone_authtoken]
auth_section = service_credentials
[database]
connection = mysql+pymysql://CK_DB_USER:CK_PASS@127.0.0.1/cloudkitty?charset=utf8
# The storage backend that CloudKitty should use
[storage]
backend = sqlalchemy
[tenant_fetcher]
backend = keystone
[keystone_fetcher]
auth_section = service_credentials
keystone_version = 3
# Auth infos for monascaclient
[collector_monasca]
auth_section = service_credentials
EOF
Finally, we will need to configure the metric collection. Edit /etc/cloudkitty/metrics.yml
:
- name: OpenStack
collector: monasca
# CloudKitty will collect metrics every 3600 seconds. Each metric will be
# charged per 1hour periods
period: 3600
# CloudKitty will wait 2 collect periods, ie. the period from 9AM to 10AM
# will be processed at 12AM. This leaves some time to the storage backend
# for metric aggregation
wait_periods: 2
# For this post, we will rate cinder volumes and glance images
services:
- volume
- image
# Monasca has no resource notion, so we directly map services to metrics
services_objects:
volume: volume.size
image: image.size
# Specifying the aggregation method for each metric
services_metrics:
volume:
- volume.size: max
image:
- image.size: max
# Unit specification and conversion
metrics_units:
volume:
volume.size:
unit: GiB
# The image.size metric is in bytes, but we want to rate Mebibytes.
# You can specify a factor and an offset for each metric, the measures
# will be converted the following way:
# result = measures * factor + offset
# (factor being 1 and offset 0 by default)
image:
image:
unit: MiB
factor: 1/1048576
That’s it for the configuration part. CloudKitty must now be registered as an OpenStack service:
# Register the rating service $ openstack user create --password ****** cloudkitty $ openstack service create --name cloudkitty rating $ openstack role add --user cloudkitty --project service admin $ openstack role create rating # Create the required endpoints $ openstack endpoint create --region RegionOne rating admin http://$CK_URL:8889 $ openstack endpoint create --region RegionOne rating public http://$CK_URL:8889 $ openstack endpoint create --region RegionOne rating internal http://$CK_URL:8889 # IMPORTANT: Allow cloudkitty to fetch monasca metrics $ openstack role add --user cloudkitty --project service monasca-user # Configure CloudKitty to rate our project $ openstack role add --user cloudkitty --project myproject rating # Check that everything is fine $ openstack role assignment list --user cloudkitty --names +--------------+--------------------+-------+-------------------+--------+-----------+ | Role | User | Group | Project | Domain | Inherited | +--------------+--------------------+-------+-------------------+--------+-----------+ | rating | cloudkitty@Default | | myproject@Default | | False | | admin | cloudkitty@Default | | service@Default | | False | | monasca-user | cloudkitty@Default | | service@Default | | False | +--------------+--------------------+-------+-------------------+--------+-----------+
We can now initialize CloudKitty’s storage backends:
$ cloudkitty-dbsync upgrade $ cloudkitty-storage-init
It is time to define our rating rules. This implies to start the API. The API should be served as a WSGI app with a real server (see https://docs.openstack.org/cloudkitty/latest/install/mod_wsgi.html). But if you are on a testing environment, you may use the following command:
$ cloudkitty-api --port 8889 -- --config-dir /etc/cloudkitty/
Step 3: Profit!
In order to define our rating rules, we will use CloudKitty’s Hashmap module (https://docs.openstack.org/cloudkitty/latest/admin/rating/hashmap.html):
# Enable the hashmap module $ cloudkitty module-enable -n hashmap +---------+---------+----------+ | Module | Enabled | Priority | +---------+---------+----------+ | hashmap | True | 1 | +---------+---------+----------+ # Create the image service $ cloudkitty hashmap-service-create -n image +------------+--------------------------------------+ | Property | Value | +------------+--------------------------------------+ | name | image | | service_id | dfcf1764-b76f-45a1-b671-339cfcc65abf | +------------+--------------------------------------+ # We charge every stored image 0.002 per MiB per collect period (1 hour). # This is a global rating rule, but you may specify a tenant if you want to # apply different rates between your tenants $ cloudkitty hashmap-mapping-create -s dfcf1764-b76f-45a1-b671-339cfcc65abf -t flat -c 0.002 +------------+--------------------------------------+ | Property | Value | +------------+--------------------------------------+ | cost | 0.00200000 | | field_id | None | | group_id | None | | mapping_id | e47704bf-831a-459c-88b0-ec10c8ac9c21 | | service_id | dfcf1764-b76f-45a1-b671-339cfcc65abf | | tenant_id | None | | type | flat | | value | | +------------+--------------------------------------+ $ cloudkitty hashmap-service-create -n volume +------------+--------------------------------------+ | Property | Value | +------------+--------------------------------------+ | name | volume | | service_id | 67fcaa4d-ca36-42ff-bd70-82f860d298e3 | +------------+--------------------------------------+ # Volumes will be charged 0.001 per GiB per hour $ cloudkitty hashmap-mapping-create -s 67fcaa4d-ca36-42ff-bd70-82f860d298e3 -c 0.001 -t flat +------------+--------------------------------------+ | Property | Value | +------------+--------------------------------------+ | cost | 0.00100000 | | field_id | None | | group_id | None | | mapping_id | 72a65d37-89f8-4573-ba51-8980916dc258 | | service_id | 67fcaa4d-ca36-42ff-bd70-82f860d298e3 | | tenant_id | None | | type | flat | | value | | +------------+--------------------------------------+
All we need now is some data for the ‘myproject’ tenant. Create a few Cinder volumes, upload some images to Glance, and wait for Ceilometer to publish metrics to Monasca.
If you want immediate results, you may set the collector’s wait_period
to 0, but this is not recommended in production (Monasca, Gnocchi, etc… need some time to aggregate measures so you could miss some).
You can now start CloudKitty’s processor:
$ cloudkitty-processor --config-file /etc/cloudkitty/cloudkitty.conf
The processor collects metrics starting at the beginning of the current month. Wait for a while until the processor has caught up with the current time.
Once you’ve waited, you can get the cost of your cloud:
# The following commands are ran as a user of the 'myproject' tenant # Get the total cost $ cloudkitty summary-get +----------------------------------+---------------+---------+---------------------+ | Tenant ID | Resource Type | Rate | Begin Time | End Time | +----------------------------------+---------------+---------+---------------------+ | 9a7[...]87 | ALL | 0.35468 | 2018-02-01T00:00:00 | 2018-03-01T00:00:00 | +----------------------------------+---------------+---------+---------------------+ # Get the total cost grouped by resource type $ cloudkitty summary-get -g res_type +----------------------------------+---------------+---------+---------------------+ | Tenant ID | Resource Type | Rate | Begin Time | End Time | +----------------------------------+---------------+---------+---------------------+ | 9a7[...]87 | image | 0.30368 | 2018-02-01T00:00:00 | 2018-03-01T00:00:00 | | 9a7[...]87 | volume | 0.051 | 2018-02-01T00:00:00 | 2018-03-01T00:00:00 | +----------------------------------+---------------+---------+---------------------+
Conclusion
It is now possible to integrate CloudKitty, Ceilometer and Monasca and to apply field mappings on any dimension specified in /etc/ceilometer/monasca_field_definitions.yml.
Given that CloudKitty services and metrics can be configured via YAML now, you can rate any metric published to Monasca by Ceilometer.