Jump to: navigation, search

Difference between revisions of "Nova/InstanceLevelSnapshots"

(Instance-Level Snapshots)
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
There are currently three ways in Nova to create a snapshot of one, some, or all of the volumes attached to a particular instance. But none of these options allow a user to create volume snapshots after I/O is quiesced as a single transaction. This proposal explains how this missing feature could be implemented, thus substantially improving the snapshotting capabilities of Nova.
  
== Instance-Level Snapshots ==
+
= Existing Behaviour =
  
Openstack should have the ability to take a snapshot of a running instance that includes all of its attached volumes. A coordinated snapshot of multiple volumes for backup purposes. The snapshot operation should occur while the instance is in a paused and quiesced state so that each snapshot is both consistent within itself and with respect to its sibling snapshots.
+
These are three ways of creating a snapshot-like thing in Nova:
  
=== Existing Behaviour ===
+
# <code>create_image</code> - takes a snapshot of the root volume and may take snapshots of the attached volumes depending on the volume type of the root volume. I/O is not quiesced.
 +
# <code>create_backup</code> - takes a snapshot of the root volume with options to specify how often to repeat and how many previous snapshots to keep around. I/O is not quiesced.
 +
# <code>os-assisted-snapshot</code> - takes a snapshot of a single cinder volume. The volume is first quiesced before the snapshot is initiated.
  
There are two snapshot operations that exist in Openstack at the moment.
+
= Proposed Changes =
  
# A user can create an image of a running instance using the <code>createImage</code> API call. This will create a &quot;template&quot; that can be used to spin up new instances from and is referred to by Glance, regardless of where it's stored. This operation will only capture the contents of the root volume.
+
My general thesis is that I/O should be quiesced in all cases if the underlying driver supports it. Libvirt supports this feature and I would like to extend the existing functionality to take advantage of it.
# A user can create a snapshot of an attached volume through Cinder. This snapshot is a new volume that can be managed just as any other Cinder volume.
 
  
 +
It's not reasonable to change the names or behaviour of the existing public api calls. Instead I would like to create a new snapshot() call in the v3 API.
  
The user must choose between one of these two, thus I propose adding functionality that allows a user to create a snapshot that includes both the root volume and all attached cinder volumes in a single pseudo-atomic operation.
+
We only need a quiesce() call added to the driver and the rest of the implementation will live in the api layer. It was suggested that the conductor would be the correct place for this code. Once implemented, the existing snapshot calls (image, backup, os-assisted) could use the underlying snapshot routines to achieve their expected results. Leaving us with only one set of snapshot-related functions to maintain.
  
=== Timeline ===
+
The new snapshot call would take at least one option: the drives that should be snapshotted:
  
Maybe Icehouse 3 dependent on required libvirt changes. Libvirt may need to expose additional operations for this feature to be properly supported. See below for further details.
+
<pre>snapshot(devices=['vda', 'vdb'])</pre>
 +
Where a value of None implies all volumes.
  
=== API Changes ===
+
This allows the user to snapshot only the root volume if a small bootable image is desired.
  
There are two obvious choices:
+
There will be no exclusion based on volume type, both glance and cinder volumes will be snapshotted respectively. Otherwise we introduce unexpected behaviour that would be confusing to the user and difficult to explain.
  
# Foo
+
The flow will look like:
# Bar
 
  
 +
* call the compute node to quiesce
 +
* call the compute node to snapshot each individual glance drive
 +
* call the volume driver to snapshot each cinder volume
 +
* package the whole thing
  
The entry point to the Nova API for this feature is create_image(). This method will be modified to look for an additional aoption 'all_volumes'. If this option is presen and is set to True, then create_image() will ensure that a snapshot request is issued for all attached volumes. The resulting snapshot will be a combination of the root volume snapshot along with additional cinder volume snapshots. These snapshots will be named in such a way to make correlation by the user an easy operation. The naming scheme will be covered later in this document.
 
  
The all_volumes flag will be passed to the compute_api, either snapshot() for image-backed instances or snapshot_volume_backed() for volume-backed instances.
+
The packaged snapshot could be stored in either Swift or Glance. I think Glance is more appropriate since the resulting collection of snapshots could be used to spin up a new instance. There is a pending proposal for &quot;artifacts&quot; in Glance that would be perfect for this - an instance template artifact would contain metadata that references the volume snapshots for an instance. These references would point to either images stored within Glance or snapshots contained in Cinder. All together this data represents a perfect point-in-time snapshot of an entire virtual machine.
  
=== Snapshot Consistency ===
+
If <code>create_image</code> and <code>create_backup</code> are updated to use this implementation, then the behaviour will appear unchanged to the user with the exception that I/O was quiesced during the snapshot(s) and they therefore have a more reliable and useful result.
  
We should be able to support crash-consistent snapshots without too many requirements on libvirt by simply pausing the VM, requesting snapshots, and resuming. A stretch-goal would be to quiesce the instance to provide filesystem-consistent snapshots. The end goal is to use guest-assisted snapshots for application-consistent snapshots across all volumes.
+
Given this, I think it makes more sense to leave the implementation within the api layer of Nova so that existing functions can share in the implementation - as opposed to moving it into the client.
  
=== Volume Naming Scheme ===
+
= External Prerequisites =
  
We will need a way for the user to tell which Cinder volumes are members of a particular snapshot. I propose we can store the Glance snapshot UUID in the volume snapshot metadata for each Cinder volume.
+
This feature will require a support from libvirt - the ability to quiesce an instance without taking a snapshot. At the moment these two operations are bound together. I will begin working with the libvirt community to add support for this feature.
 
 
=== New Snapshot Logic ===
 
 
 
The basic pseudocode might look like:
 
 
 
<pre>volumes = get_all_attached_volumes()
 
 
 
PAUSE(quiesce=True)
 
 
 
UUID = snapshot_root_volume()
 
 
 
for volume in volumes:
 
    snapshot_volume(volume, UUID)            [volume_api.create_snapshot() via cinder]
 
 
 
wait for snaphots to complete
 
 
 
collect metadata for response
 
 
 
RESUME()
 
 
 
return response</pre>
 
 
 
=== Libvirt Support ===
 
 
 
I still have some pending questions about what is possible in the current version of libvirt:
 
 
 
# Foo
 
# Bar
 
# Baz
 

Latest revision as of 17:55, 26 February 2014

There are currently three ways in Nova to create a snapshot of one, some, or all of the volumes attached to a particular instance. But none of these options allow a user to create volume snapshots after I/O is quiesced as a single transaction. This proposal explains how this missing feature could be implemented, thus substantially improving the snapshotting capabilities of Nova.

Existing Behaviour

These are three ways of creating a snapshot-like thing in Nova:

  1. create_image - takes a snapshot of the root volume and may take snapshots of the attached volumes depending on the volume type of the root volume. I/O is not quiesced.
  2. create_backup - takes a snapshot of the root volume with options to specify how often to repeat and how many previous snapshots to keep around. I/O is not quiesced.
  3. os-assisted-snapshot - takes a snapshot of a single cinder volume. The volume is first quiesced before the snapshot is initiated.

Proposed Changes

My general thesis is that I/O should be quiesced in all cases if the underlying driver supports it. Libvirt supports this feature and I would like to extend the existing functionality to take advantage of it.

It's not reasonable to change the names or behaviour of the existing public api calls. Instead I would like to create a new snapshot() call in the v3 API.

We only need a quiesce() call added to the driver and the rest of the implementation will live in the api layer. It was suggested that the conductor would be the correct place for this code. Once implemented, the existing snapshot calls (image, backup, os-assisted) could use the underlying snapshot routines to achieve their expected results. Leaving us with only one set of snapshot-related functions to maintain.

The new snapshot call would take at least one option: the drives that should be snapshotted:

snapshot(devices=['vda', 'vdb'])

Where a value of None implies all volumes.

This allows the user to snapshot only the root volume if a small bootable image is desired.

There will be no exclusion based on volume type, both glance and cinder volumes will be snapshotted respectively. Otherwise we introduce unexpected behaviour that would be confusing to the user and difficult to explain.

The flow will look like:

  • call the compute node to quiesce
  • call the compute node to snapshot each individual glance drive
  • call the volume driver to snapshot each cinder volume
  • package the whole thing


The packaged snapshot could be stored in either Swift or Glance. I think Glance is more appropriate since the resulting collection of snapshots could be used to spin up a new instance. There is a pending proposal for "artifacts" in Glance that would be perfect for this - an instance template artifact would contain metadata that references the volume snapshots for an instance. These references would point to either images stored within Glance or snapshots contained in Cinder. All together this data represents a perfect point-in-time snapshot of an entire virtual machine.

If create_image and create_backup are updated to use this implementation, then the behaviour will appear unchanged to the user with the exception that I/O was quiesced during the snapshot(s) and they therefore have a more reliable and useful result.

Given this, I think it makes more sense to leave the implementation within the api layer of Nova so that existing functions can share in the implementation - as opposed to moving it into the client.

External Prerequisites

This feature will require a support from libvirt - the ability to quiesce an instance without taking a snapshot. At the moment these two operations are bound together. I will begin working with the libvirt community to add support for this feature.