Cinder with Heat
Nova adapts ephemeral storage for VMs by default. The ephemeral storage resides on the local hard disks of the host computes and present a virtual disk for each VM. These virtual disks are created at the time of the VM creation, and are deleted with the VM, so are called ephemeral. If the host machine crashes, you lose the VM with all its data stored in disk.
This is not a good situation to be in. You want your data to retain even if the VM is lost, so that a new VM can be created in a different host. How do we do that in OpenStack? Answer is Cinder.
OpenStack Cinder is block storage service which manage storage volumes independet from VMs. Unlike Nova ephemeral storage, Cinder uses centralized storage solutions as its storage back end, so the storage is decoupled from the host machine running the VM. These back end storage systems uses redundancy mechanisms like multiple disk arrays with RAID configurations so that Cinder can provide a fault tolerant storage solution for VMs.
Reserving the discussion of the functionality of Cinder to another day, let’s focus on using the Cinder block storage in Heat templates.
Creating a VM with a block storage volume
Most of the time, we create applications with Heat, rather than creating individual VMs. Here’s a part of a Heat template that creates the block storage for a VM running Ansible.
#Cinder volume
ansible_volume:
type: OS::Cinder::Volume
properties:
name: "ansible_vda"
image: { get_param: image }
size: 10
deletion_policy: Retain
It is creating a 10GB volume using a QCOW2 image
which means we are creating a bootable volume, to be used as the primary disk of a VM.
An importat attribute in this resource is the deletion_policy: Retain
. If this is ommited, the volume would be deleted whenever the Heat stack is deleted. When deletion_policy
is set to Retain
, the volume is preserved even when the stack is deleted, so that you could reuse the voluem to create the application again.
The deletion_policy
parameter should be set based on the requirement of the application. If you want to delete and recreate the application multiple times, then it’s best to set this option, so that you don’t have to recreate your VMs from scratch everytime.
Now, let’s assign this volume to a VM.
#VM
ansible_server:
type: OS::Nova::Server
properties:
config_drive: "true"
name: { get_param: stack_name }
flavor: { get_resource: flavor }
availability_zone: "zone-A"
block_device_mapping_v2:
- device_name: vda
boot_index: 0
delete_on_termination: False
volume_id : { get_resource : ansible_volume }
For clarity, we have eliminated some parts of the resource.
The property block_device_mapping_v2
is used to attach the volume to a VM. It accepts a list of volumes, but we have provided only one in this template.
The boot_index
refers the order of boot disks. Since we have only one disk we are setting it to 0
.
delete_on_termination: False
means that the volume will not be deleted even if the individual VM is terminated.
volume_id
refers to the volume we have created earlier.
The device_name
property matches to the device name in /dev/device_name
in the created VM, and we have set it as vda
.
The complete HOT file can be found here.
Attaching Multiple Volumes
This is a part of a Heat template which creates two storage volumes, and attach them to a single VM.
#Cinder volume
vm_volume_1:
type: OS::Cinder::Volume
properties:
name:
list_join: ['_', [{get_param: stack_name}, 'vda']]
image: { get_param: Image }
size: 85
vm_volume_2:
type: OS::Cinder::Volume
properties:
name:
list_join: ['_', [{get_param: stack_name}, 'vda2']]
size: 5
The first volume is of 85 GB, and is created from a QCOW2 image. The second one is a 5GB volume that does not have an image, so will not be a bootable disk.
vm_test_1:
type: OS::Nova::Server
properties:
name:
list_join: ['-', [{get_param: vapp_name}, '1']]
#image: { get_param: Image }
block_device_mapping_v2:
- device_name: vda
boot_index: 0
delete_on_termination: False
volume_id : { get_resource : vm_volume_1 }
- device_name: vdb
boot_index: 1
delete_on_termination: False
volume_id : { get_resource : vm_volume_2 }
When assigning the two volumes, we are setting boot_index: 0
in the vm_volume_1
which is created based on an image, and which is going to be the boot disk. The first volume will be mapped to /dev/vda
and the second to /dev/vdb
in the VM
The complete HOT file can be found here
Reusing a Cinder Volume
Once we set the deletion_policy: Retain
the volume will not be deleted, when the stack is deleted. We can reuse this volume to create a new VM.
vm_test_1:
type: OS::Nova::Server
properties:
name:
list_join: ['-', [{get_param: stack_name}, '1']]
block_device_mapping_v2:
- device_name: vda
boot_index: 0
delete_on_termination: False
volume_id : "c9c44eae-b5b2-43dd-92c8-47e53eb8bff0"
The volume_id
refers to the ID
of the volume and not the name. Therefore, we have to get it using CLI command openstack volume show <volume_name>
The complete template can be found here.
In this brief post, we have described how to use Cinder in Heat templates. In future, let’s dig deeper in to the architecture and functions of Cinder.