Playing around with Cinder multi-backend

With Grizzly release, Cinder got equipped with another major feature – multi-backends with filter scheduler. So now you can have more than one storage boxes for block storage and manage them with one Cinder deployment. Here, I’m going to test it out using our favourite method – trying it out on DevStack!

DevStack can provide you with two LVM backends to play around with them. But you’ll need to restack it.

Go to the devstack directory and pull the latest code. Destroy previous DevStack deployment if it exists.

rushi@jio:~/devstack$ git pull origin master
rushi@jio:~/devstack$ ./unstack.sh

Add the config option to localrc which give you pre-cooked multi-backend setup with two LVM backends, both of 10G. Stack

rushi@jio:~$ echo "CINDER_MULTI_LVM_BACKEND=True" >> localrc
rushi@jio:~$ ./devstack/stack.sh

You can see that the cinder.conf file now has two values for enabled backends:

rushi@jio:~$ less /etc/cinder/cinder.conf | grep enabled_backends
enabled_backends = lvmdriver-1,lvmdriver-2
#enabled_backends=<None>

Also, you can see that there are two configuration groups created at the end of that config file, one each for configurations corresponding to that particular backend

rushi@jio:~$ tail /etc/cinder/cinder.conf 

[lvmdriver-1]
volume_backend_name = LVM_iSCSI
volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver
volume_group = stack-volumes

[lvmdriver-2]
volume_backend_name = LVM_iSCSI_2
volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver
volume_group = stack-volumes2

So you have two volume groups created for respective backends. Lets check it directly without using Cinder.

rushi@jio:~$ sudo vgs
  VG             #PV #LV #SN Attr   VSize   VFree 
  stack-volumes    1   0   0 wz--n-  10.01g 10.01g
  stack-volumes2   1   0   0 wz--n-  10.01g 10.01g
  ubuntu-vg        1   2   0 wz--n- 931.27g 44.00m

Hmmm. Two volume groups, each of size 10G.

Case 1: Spreading volumes across backends

Now, lets create a volume and see where it ends up.

rushi@jio:~$ cinder create 1
ERROR: You must provide a username via either --os-username or env[OS_USERNAME]

Oops! Let me try again..

rushi@jio:~$ . devstack/openrc 
rushi@jio:~$ cinder create 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T17:29:49.241493      |
|    description    |                 None                 |
|         id        | ecfbfebb-73d5-4faf-b625-e69f18020378 |
|      metadata     |                  {}                  |
|        name       |                 None                 |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   e441f49105f343da87316ab7157e2ab7   |
|    volume_type    |                 None                 |
+-------------------+--------------------------------------+

rushi@jio:~$ cinder list
+--------------------------------------+-----------+------+------+-------------+----------+-------------+
|                  ID                  |   Status  | Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+------+------+-------------+----------+-------------+
| ecfbfebb-73d5-4faf-b625-e69f18020378 | available | None |  1   |     None    |  false   |             |
+--------------------------------------+-----------+------+------+-------------+----------+-------------+

rushi@jio:~$ sudo vgs
  VG             #PV #LV #SN Attr   VSize   VFree 
  stack-volumes    1   0   0 wz--n-  10.01g 10.01g
  stack-volumes2   1   2   0 wz--n-  10.01g  9.01g
  ubuntu-vg        1   2   0 wz--n- 931.27g 44.00m

So it went to backend number 2. If you are admin (source devstack/openrc admin admin), you can do a cinder show too, to get information as to which host did this volume go to. Only the admin is allowed to view the host information.

The scheduler now gets reported of the capabilities which the backends have (check out the c-shr screen to see it). The scheduler then weighs the backend based on these capabilities and decides which of them has higher ‘weight’ to serve the next ‘create’ request. By default, the ‘weigher’ for scheduler is CapacityWeigher. That is, whichever backend has higher capacity, that backend will be chosen for the next ‘create’ request.

So in our case, when we’ll do another ‘create volume’ it will now land on to the first backend.

rushi@jio:~$ cinder create 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T17:39:23.958468      |
|    description    |                 None                 |
|         id        | aa79c608-47cc-44e3-a614-f4bddaab68e5 |
|      metadata     |                  {}                  |
|        name       |                 None                 |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   e441f49105f343da87316ab7157e2ab7   |
|    volume_type    |                 None                 |
+-------------------+--------------------------------------+

rushi@jio:~$ sudo vgs
  VG             #PV #LV #SN Attr   VSize   VFree 
  stack-volumes    1   0   0 wz--n-  10.01g  9.01g
  stack-volumes2   1   2   0 wz--n-  10.01g  9.01g
  ubuntu-vg        1   2   0 wz--n- 931.27g 44.00m

Neat!

Case 2 : Stacking all volumes at one backend

What if we want to keep all the volumes at only one backend? Cinder allows you to do that too! There is a configuration option in cinder.conf, capacity_weight_multiplier, which allows you to multiply the ‘capacity weight’ by a number. So if the multiplier is 1, a backend with higher capacity will have higher weight, and will be the choice for the next volume creation request. This is the default case. BUT what if we set it to -1? The backend with higher available capacity will have more negative weight, which will make that backend less preferable for next ‘create’ request, and hence the request will go to the backend which has lesser capacity!

Let us see this too in action.

Check out the config option from cinder.conf file.

rushi@jio:~$ cat /etc/cinder/cinder.conf | grep -B 3 ^capacity_weight_multiplier

# Multiplier used for weighing volume capacity. Negative
# numbers mean to stack vs spread. (floating point value)
# capacity_weight_multiplier=1.0

The config option is commented out and is there just so that you can easily change it. Now uncomment it and change it’s value to -1.

Delete previously created volumes. Kill all the three Cinder screen processes (c-api, c-sch and c-vol), and restart them.

Lets create two volumes and see where they end up..

rushi@jio:~$ cinder list
+----+--------+------+------+-------------+----------+-------------+
| ID | Status | Name | Size | Volume Type | Bootable | Attached to |
+----+--------+------+------+-------------+----------+-------------+
+----+--------+------+------+-------------+----------+-------------+
rushi@jio:~$ cinder create 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T17:56:59.845733      |
|    description    |                 None                 |
|         id        | b927b328-5ae0-411a-9de2-22ed732b4946 |
|      metadata     |                  {}                  |
|        name       |                 None                 |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   e441f49105f343da87316ab7157e2ab7   |
|    volume_type    |                 None                 |
+-------------------+--------------------------------------+
rushi@jio:~$ cinder create 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T17:57:01.132756      |
|    description    |                 None                 |
|         id        | 9f643f2d-7221-4a5c-bf48-1977c9b89fd3 |
|      metadata     |                  {}                  |
|        name       |                 None                 |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   e441f49105f343da87316ab7157e2ab7   |
|    volume_type    |                 None                 |
+-------------------+--------------------------------------+

rushi@jio:~$ sudo vgs
  VG             #PV #LV #SN Attr   VSize   VFree 
  stack-volumes    1   0   0 wz--n-  10.01g 10.01g
  stack-volumes2   1   2   0 wz--n-  10.01g  8.01g
  ubuntu-vg        1   2   0 wz--n- 931.27g 44.00m

:)

Case 3 : Custom choice

What if I have two different backends (maybe one is slower, or costlier, than the other), and my users want to exactly specify how many volumes they want of each ‘type’ of backends? Here, Cinder’s ‘volume types’ have us covered.

We can associate a volume type with a backend, and then the users can create a volume of whatever ‘type’ they want. Let’s throw some discrimination at these backends. I’ll create two volume types: ‘gold’ and ‘bronze’, and associate ‘stack-volumes’ with ‘gold’ and similarly for ‘stack-volumes2’. Note that this job can only be done by the administrator.

Let us be admins

rushi@jio:~$ . devstack/openrc admin admin

Create both the volume types and list them.

rushi@jio:~$ cinder type-create gold
+--------------------------------------+------+
|                  ID                  | Name |
+--------------------------------------+------+
| dd883ee0-24be-42e1-ab2e-b9a01454f2f9 | gold |
+--------------------------------------+------+
rushi@jio:~$ cinder type-create bronze
+--------------------------------------+--------+
|                  ID                  |  Name  |
+--------------------------------------+--------+
| f63dd2cb-f4e7-4d6d-a84f-5bf2cc6c5671 | bronze |
+--------------------------------------+--------+

rushi@jio:~$ cinder type-list
+--------------------------------------+--------+
|                  ID                  |  Name  |
+--------------------------------------+--------+
| dd883ee0-24be-42e1-ab2e-b9a01454f2f9 |  gold  |
| f63dd2cb-f4e7-4d6d-a84f-5bf2cc6c5671 | bronze |
+--------------------------------------+--------+

Get the backend names (volume_backend_name config option) from cinder.conf file.

rushi@jio:~$ tail /etc/cinder/cinder.conf 

[lvmdriver-1]
volume_backend_name = LVM_iSCSI
volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver
volume_group = stack-volumes

[lvmdriver-2]
volume_backend_name = LVM_iSCSI_2
volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver
volume_group = stack-volumes2

Now let’s associate backend LVM_iSCSI with volume type ‘gold’, and similarly for the other one.

rushi@jio:~$ cinder type-key gold set volume_backend_name=LVM_iSCSI
rushi@jio:~$ cinder type-key bronze set volume_backend_name=LVM_iSCSI_2

These association are stored as key-value pairs in the volume type’s ‘extra specs’. Let’s see them

rushi@jio:~$ cinder extra-specs-list 
+--------------------------------------+--------+------------------------------------------+
|                  ID                  |  Name  |               extra_specs                |
+--------------------------------------+--------+------------------------------------------+
| dd883ee0-24be-42e1-ab2e-b9a01454f2f9 |  gold  |  {u'volume_backend_name': u'LVM_iSCSI'}  |
| f63dd2cb-f4e7-4d6d-a84f-5bf2cc6c5671 | bronze | {u'volume_backend_name': u'LVM_iSCSI_2'} |
+--------------------------------------+--------+------------------------------------------+

You can add more key-value pairs for these volume types with different key names. volume_backend_name is a reserved key name, though.

Let’s create two volumes of type ‘gold’ and see where they end up being created:

rushi@jio:~$ cinder create --volume-type gold --name costly_vol_1 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T18:24:07.670635      |
|    description    |                 None                 |
|         id        | 767d4c56-6d3d-46f7-b0a3-4a00f696bcad |
|      metadata     |                  {}                  |
|        name       |             costly_vol_1             |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   c271eb32e71b411bb98ad7b93792d6d5   |
|    volume_type    |                 gold                 |
+-------------------+--------------------------------------+
rushi@jio:~$ cinder create --volume-type gold --name costly_vol_2 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T18:24:58.382180      |
|    description    |                 None                 |
|         id        | a938e556-65cf-4547-87ff-513d60f626d3 |
|      metadata     |                  {}                  |
|        name       |             costly_vol_2             |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   c271eb32e71b411bb98ad7b93792d6d5   |
|    volume_type    |                 gold                 |
+-------------------+--------------------------------------+
rushi@jio:~$ cinder list
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+
|                  ID                  |   Status  |     Name     | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+
| 767d4c56-6d3d-46f7-b0a3-4a00f696bcad | available | costly_vol_1 |  1   |     gold    |  false   |             |
| a938e556-65cf-4547-87ff-513d60f626d3 | available | costly_vol_2 |  1   |     gold    |  false   |             |
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+

rushi@jio:~$ sudo vgs
  VG             #PV #LV #SN Attr   VSize   VFree 
  stack-volumes    1   2   0 wz--n-  10.01g  8.01g
  stack-volumes2   1   0   0 wz--n-  10.01g 10.01g
  ubuntu-vg        1   2   0 wz--n- 931.27g 44.00m

Now create another one, but with type ‘bronze’ and ensure it is created on the other backend.

rushi@jio:~$ cinder create --volume-type bronze --name cheap_vol_1 1
+-------------------+--------------------------------------+
|      Property     |                Value                 |
+-------------------+--------------------------------------+
|    attachments    |                  []                  |
| availability_zone |                 nova                 |
|      bootable     |                false                 |
|     created_at    |      2014-01-16T18:27:05.852092      |
|    description    |                 None                 |
|         id        | 97f62c7a-b974-41e8-a659-1e6d3eb876d5 |
|      metadata     |                  {}                  |
|        name       |             cheap_vol_1              |
|        size       |                  1                   |
|    snapshot_id    |                 None                 |
|    source_volid   |                 None                 |
|       status      |               creating               |
|      user_id      |   c271eb32e71b411bb98ad7b93792d6d5   |
|    volume_type    |                bronze                |
+-------------------+--------------------------------------+

rushi@jio:~$ sudo pvs
  PV         VG             Fmt  Attr PSize   PFree 
  /dev/loop0 stack-volumes  lvm2 a--   10.01g  8.01g
  /dev/loop1 stack-volumes2 lvm2 a--   10.01g  9.01g
  /dev/sda5  ubuntu-vg      lvm2 a--  931.27g 44.00m

Done :)

Cheers!

w