This article first appeared on Christian’s blog. Christian Berendt
is currently working as a cloud solution architect for B1 Systems. You should follow him on GitHub.
Heat is the orchestration service included in OpenStack. In teamwork with Ceilometer it is possible to build auto scaling environments. A good entry point to learn how to write Heat Orchestration Templates (HOT) is the HOT Guide. A list of all available resource types (only a few of them are used in the following example) is available in the HOT Reference. Tons of example templates are available in the repository openstack/heat-templates. This article is based on the autoscaling.yaml example template.
Presumptions for the following example:
- an image with the name
Cirros 0.3.3
is available (glance image-create --name "Cirros 0.3.3" --disk-format qcow2 --container-format bare --is-public True --copy http://download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img
) - a flavor with the name
m1.nano
is available (nova flavor-create m1.nano 42 64 0 1
) - a network with the name
internal001
is available (neutron net-create internal001; neutron subnet-create --name internal001 internal001 192.168.200.0/24
)
First create a template for a stack with a single instance in the file cirros.yaml
.
heat_template_version: 2014-10-16
description: A simple server.
resources:
server:
type: OS::Nova::Server
properties:
block_device_mapping:
- device_name: vda
delete_on_termination: true
volume_id: { get_resource: volume }
flavor: m1.nano
networks:
- network: internal001
volume:
type: OS::Cinder::Volume
properties:
image: 'Cirros 0.3.3'
size: 1
To validate the syntax use heat template-validate --template-file cirros.yaml
.
Test if the template is working like expected with heat stack-create -f cirros.yaml cirros
. After a few seconds (or minutes, depends on the environment) heat stack-list
should show a stack with stack_status = CREATE_COMPLETE
. If not have a look in the output of heat event-list cirros
to identify the issue.
To delete the stack run heat stack-delete cirros
.
Let’s add a script that generates a high load on all cores of the instance. A high CPU load will be the trigger to launch further instances.
Add the properties user_data_format
and user_data
to the definition of server
.
user_data_format: RAW
user_data: |
#!/bin/sh
while [ 1 ] ; do echo $((13**99)) 1>/dev/null 2>&1; done &
The cirros.yaml
file should now have the following content:
heat_template_version: 2014-10-16
description: A simple server.
resources:
server:
type: OS::Nova::Server
properties:
block_device_mapping:
- device_name: vda
delete_on_termination: true
volume_id: { get_resource: volume }
flavor: m1.nano
networks:
- network: internal001
user_data_format: RAW
user_data: |
#!/bin/sh
while [ 1 ] ; do echo $((13**99)) 1>/dev/null 2>&1; done
volume:
type: OS::Cinder::Volume
properties:
image: 'Cirros 0.3.3'
size: 1
Create the file environment.yaml
to define a new resource type OS::Nova::Server::Cirros
.
resource_registry:
"OS::Nova::Server::Cirros": "cirros.yaml"
Create a OS::Heat::AutoScalingGroup resource in the file simple.yaml
. This group defines the resources that should be scaled.
heat_template_version: 2014-10-16
description: A simple auto scaling group.
resources:
group:
type: OS::Heat::AutoScalingGroup
properties:
cooldown: 60
desired_capacity: 2
max_size: 5
min_size: 1
resource:
type: OS::Nova::Server::Cirros
Start the stack with heat stack-create simple -f simple.yaml -e environment.yaml
. There should be 2 instances, the value of the desired_capacity
parameter, and nothing more should happen.
Delete the stack with heat stack-delete simple
and add the following resources to complete the example.
First a OS::Heat::ScalingPolicy resource.
scaleup_policy:
type: OS::Heat::ScalingPolicy
properties:
adjustment_type: change_in_capacity
auto_scaling_group_id: { get_resource: group }
cooldown: 60
scaling_adjustment: 1
Finally a OS::Ceilometer::Alarm resource. This resource will notify the scaling policy resource. The scaling policy resource will increase the number of the resources defined in the scaling group.
cpu_alarm_high:
type: OS::Ceilometer::Alarm
properties:
meter_name: cpu_util
statistic: avg
period: 60
evaluation_periods: 1
threshold: 50
alarm_actions:
- {get_attr: [scaleup_policy, alarm_url]}
comparison_operator: gt
The simple.yaml
file should now have the following content:
heat_template_version: 2014-10-16
description: A simple auto scaling group.
resources:
group:
type: OS::Heat::AutoScalingGroup
properties:
cooldown: 60
desired_capacity: 2
max_size: 5
min_size: 1
resource:
type: OS::Nova::Server::Cirros
scaleup_policy:
type: OS::Heat::ScalingPolicy
properties:
adjustment_type: change_in_capacity
auto_scaling_group_id: { get_resource: group }
cooldown: 60
scaling_adjustment: 1
cpu_alarm_high:
type: OS::Ceilometer::Alarm
properties:
meter_name: cpu_util
statistic: avg
period: 60
evaluation_periods: 1
threshold: 50
alarm_actions:
- {get_attr: [scaleup_policy, alarm_url]}
comparison_operator: gt
Start the complete stack with heat stack-create simple -f simple.yaml -e environment.yaml
.
At the beginning there are only 2 instances. After some time (more than 10 minutes because of the default interval of Ceilometer) the number of instances increases to a maximum of 5, the value of the max_size
parameter.
Photo by rogersmith // CC BY NC ND
- Simple auto scaling environment with Heat - February 9, 2015