Merge "Update the devref for volume migration"
This commit is contained in:
commit
a6f92ceaf0
@ -32,9 +32,9 @@ Programming HowTos and Tutorials
|
||||
drivers
|
||||
gmr
|
||||
replication
|
||||
migration
|
||||
api.apache
|
||||
|
||||
|
||||
Background Concepts for Cinder
|
||||
------------------------------
|
||||
.. toctree::
|
||||
@ -75,7 +75,6 @@ Module Reference
|
||||
fakes
|
||||
cinder
|
||||
|
||||
|
||||
Indices and tables
|
||||
------------------
|
||||
|
||||
|
300
doc/source/devref/migration.rst
Normal file
300
doc/source/devref/migration.rst
Normal file
@ -0,0 +1,300 @@
|
||||
..
|
||||
Copyright (c) 2015 OpenStack Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Introduction to volume migration
|
||||
--------------------------------
|
||||
Cinder provides the volume migration support within the same deployment,
|
||||
which means the node of cinder volume service, c-vol node where the
|
||||
source volume is located, is able to access the c-vol node where
|
||||
the destination volume is located, and both of them share the same
|
||||
Cinder API service, scheduler service, message queue service, etc.
|
||||
|
||||
As a general rule migration is possible for volumes in 'available' or
|
||||
‘in-use’ status, for the driver which has implemented volume migration.
|
||||
So far, we are confident that migration will succeed for 'available'
|
||||
volumes, whose drivers implement the migration routines. However,
|
||||
the migration of 'in-use' volumes is driver dependent. It depends on
|
||||
different drivers involved in the operation. It may fail depending on
|
||||
the source or destination driver of the volume.
|
||||
|
||||
For example, from RBD to LVM, the migration of 'in-use' volume will
|
||||
succeed, but from LVM to RBD, it will fail.
|
||||
|
||||
There are two major scenarios, which volume migration supports
|
||||
in Cinder:
|
||||
|
||||
Scenario 1: Migration between two back-ends with the same volume type,
|
||||
regardless if they are located on the same c-vol node or not.
|
||||
|
||||
Scenario 2: Migration between two back-ends with different volume types,
|
||||
regardless if the back-ends are located on the same c-vol node or not.
|
||||
|
||||
|
||||
How to do volume migration via CLI
|
||||
----------------------------------
|
||||
Scenario 1 of volume migration is done via the following command from
|
||||
the CLI:
|
||||
cinder migrate [--force-host-copy [<True|False>]]
|
||||
[--lock-volume [<True|False>]]
|
||||
<volume> <host>
|
||||
Mandatory arguments:
|
||||
<volume> ID of volume to migrate.
|
||||
<host> Destination host. The format of host is
|
||||
host@backend#POOL, while 'host' is the host
|
||||
name of the volume node, 'backend' is the back-end
|
||||
name and 'POOL' is a logical concept to describe
|
||||
a set of storage resource, residing in the
|
||||
back-end. If the back-end does not have specified
|
||||
pools, 'POOL' needs to be set with the same name
|
||||
as 'backend'.
|
||||
|
||||
Optional arguments:
|
||||
--force-host-copy [<True|False>]
|
||||
Enables or disables generic host-based force-
|
||||
migration, which bypasses the driver optimization.
|
||||
Default=False.
|
||||
--lock-volume [<True|False>]
|
||||
Enables or disables the termination of volume
|
||||
migration caused by other commands. This option
|
||||
applies to the available volume. True means it locks
|
||||
the volume state and does not allow the migration to
|
||||
be aborted. The volume status will be in maintenance
|
||||
during the migration. False means it allows the volume
|
||||
migration to be aborted. The volume status is still in
|
||||
the original status. Default=False.
|
||||
|
||||
Important note: Currently, error handling for failed migration operations is
|
||||
under development in Cinder. If we would like the volume migration to finish
|
||||
without any interruption, please set --lock-volume to True. If it is set
|
||||
to False, we cannot predict what will happen, if other actions like attach,
|
||||
detach, extend, etc, are issued on the volume during the migration.
|
||||
It all depends on which stage the volume migration has reached and when the
|
||||
request of another action comes.
|
||||
|
||||
|
||||
Scenario 2 of volume migration can be done via the following command
|
||||
from the CLI:
|
||||
cinder retype --migration-policy on-demand
|
||||
<volume> <volume-type>
|
||||
Mandatory arguments:
|
||||
<volume> Name or ID of volume for which to modify type.
|
||||
<volume-type> New volume type.
|
||||
|
||||
Source volume type and destination volume type must be different and
|
||||
they must refer to different back-ends.
|
||||
|
||||
|
||||
Configurations
|
||||
--------------
|
||||
To set up a an environment to try the volume migration, we need to
|
||||
configure at least two different back-ends on the same node of cinder
|
||||
volume service, c-vol node or two back-ends on two different volume
|
||||
nodes of cinder volume service, c-vol nodes. Which command to use,
|
||||
‘cinder migrate’ or ‘cinder retype’, depends on which type of volume
|
||||
we would like to test.
|
||||
|
||||
**Scenario 1 for migration**
|
||||
|
||||
To configure the environment for Scenario 1 migration, e.g. a
|
||||
volume is migrated from back-end <driver-backend> on Node 1 to back-end
|
||||
<driver-backend> on Node 2, cinder.conf needs to contains the following
|
||||
entries for the same back-end on both of source and the destination
|
||||
nodes:
|
||||
|
||||
For Node 1:
|
||||
...
|
||||
[<driver-backend>]
|
||||
volume_driver=xxxx
|
||||
volume_backend_name=<driver-backend>
|
||||
...
|
||||
|
||||
For Node 2:
|
||||
...
|
||||
[<driver-backend>]
|
||||
volume_driver=xxxx
|
||||
volume_backend_name=<driver-backend>
|
||||
...
|
||||
|
||||
If a volume with a predefined volume type is going to migrate,
|
||||
the back-end drivers from Node 1 and Node2 should have the same
|
||||
value for volume_backend_name, which means <driver-backend> should be
|
||||
the same for Noe 1 and Node 2. The volume type can be created
|
||||
with the extra specs {volume_backend_name: driver-biz}.
|
||||
|
||||
If we are going to migrate a volume with a volume type of none, it
|
||||
is not necessary to set the same value to volume_backend_name for
|
||||
both Node 1 and Node 2.
|
||||
|
||||
**Scenario 2 for migration**
|
||||
|
||||
To configure the environment for Scenario 2 migration:
|
||||
For example, a volume is migrated from driver-biz back-end on Node 1
|
||||
to driver-net back-end on Node 2, cinder.conf needs to contains
|
||||
the following entries:
|
||||
|
||||
For Node 1:
|
||||
...
|
||||
[driver-biz]
|
||||
volume_driver=xxxx
|
||||
volume_backend_name=driver-biz
|
||||
...
|
||||
|
||||
For Node 2:
|
||||
...
|
||||
[driver-net]
|
||||
volume_driver=xxxx
|
||||
volume_backend_name=driver-net
|
||||
...
|
||||
|
||||
For example, a volume is migrated from driver-biz back-end on Node 1
|
||||
to driver-biz back-net on the same node, cinder.conf needs to
|
||||
contains the following entries:
|
||||
|
||||
...
|
||||
[driver-biz]
|
||||
volume_driver=xxxx
|
||||
volume_backend_name=driver-biz
|
||||
...
|
||||
|
||||
...
|
||||
[driver-net]
|
||||
volume_driver=xxxx
|
||||
volume_backend_name=driver-net
|
||||
...
|
||||
|
||||
Two volume type needs to be created. One is with the extra specs:
|
||||
{volume_backend_name: driver-biz}. The other is with the extra specs:
|
||||
{volume_backend_name: driver-net}.
|
||||
|
||||
|
||||
What can be tracked during volume migration
|
||||
-------------------------------------------
|
||||
The volume migration is an administrator only action and it may take
|
||||
a relatively long time to finish. The property ‘migration status’ will
|
||||
indicate the stage of the migration process for the volume. The
|
||||
administrator can check the ‘migration status’ via the ‘cinder list’
|
||||
or ‘cinder show <volume-id>’ command. The ‘cinder list’ command presents
|
||||
a list of all the volumes with some properties displayed, including the
|
||||
migration status, only to the administrator. However, the migration status
|
||||
is not included if ‘cinder list’ is issued by an ordinary user. The
|
||||
‘cinder show <volume-id>’ will present all the detailed information of a
|
||||
specific volume, including the migration status, only to the administrator.
|
||||
|
||||
If the migration status of a volume shows ‘starting’, ‘migrating’ or
|
||||
‘completing’, it means the volume is in the process of a migration.
|
||||
If the migration status is ‘success’, it means the migration has finished
|
||||
and the previous migration of this volume succeeded. If the
|
||||
migration status is ‘error’, it means the migration has finished and
|
||||
the previous migration of this volume failed.
|
||||
|
||||
|
||||
How to implement volume migration for a back-end driver
|
||||
-------------------------------------------------------
|
||||
There are two kinds of implementations for the volume migration currently
|
||||
in Cinder.
|
||||
|
||||
The first is the generic host-assisted migration, which consists of two
|
||||
different transfer modes, block-based and file-based. This implementation
|
||||
is based on the volume attachment to the node of cinder volume service,
|
||||
c-vol node. Any back-end driver supporting iSCSI will be able to support
|
||||
the generic host-assisted migration for sure. The back-end driver without
|
||||
iSCSI supported needs to be tested to decide if it supports this kind of
|
||||
migration. The block-based transfer mode is done by ‘dd’ command,
|
||||
applying to drivers like LVM, Storwize, etc, and the file-based transfer
|
||||
mode is done by file copy, typically applying to the RBD driver.
|
||||
|
||||
The second is the driver specific migration.
|
||||
Since some storage back-ends have their special commands to copy the volume,
|
||||
Cinder also provides a way for them to implement in terms of their own
|
||||
internal commands to migrate.
|
||||
|
||||
If the volume is migrated between two nodes configured with the same
|
||||
storage back-end, the migration will be optimized by calling the method
|
||||
migrate_volume in the driver, if the driver provides an implementation for
|
||||
it to migrate the volume within the same back-end, and will fallback to
|
||||
the generic host-assisted migration provided in the manager, if no such
|
||||
implementation is found or this implementation is not applicable for
|
||||
this migration.
|
||||
|
||||
If your storage driver in Cinder provides iSCSI support, it should
|
||||
naturally work under the generic host-assisted migration, when
|
||||
--force-host-copy is set to True from the API request. Normally you
|
||||
do not need to change any code, unless you need to transfer the volume
|
||||
from your driver via a different way from the the block-based transfer
|
||||
or the file-based transfer.
|
||||
|
||||
If your driver uses a network connection to communicate the block data
|
||||
itself, you can use file I/O to participate in migration. Please take
|
||||
the RBD driver as a reference for this implementation.
|
||||
|
||||
If you would like to implement a driver specific volume migration for
|
||||
your driver, the API method associated with the driver specific migration
|
||||
is the following admin only method:
|
||||
|
||||
migrate_volume(self, ctxt, volume, host)
|
||||
|
||||
If your driver is taken as the destination back-end for a generic host-assisted
|
||||
migration and your driver needs to update the volume model after a successful
|
||||
migration, you need to implement the following method for your driver:
|
||||
|
||||
update_migrated_volume(self, ctxt, volume, new_volume, original_volume_status):
|
||||
|
||||
|
||||
Required methods
|
||||
----------------
|
||||
There is one mandatory method that needs to be implemented for
|
||||
the driver to implement the driver specific volume migration.
|
||||
|
||||
**migrate_volume**
|
||||
|
||||
Used to migrate the volume directly if source and destination are
|
||||
managed by same storage.
|
||||
|
||||
There is one optional method that could be implemented for
|
||||
the driver to implement the generic host-assisted migration.
|
||||
|
||||
**update_migrated_volume**
|
||||
|
||||
Used to return the key-value pairs to update the volume model after
|
||||
a successful migration. The key-value pairs returned are supposed to
|
||||
be the final values your driver would like to be in the volume model,
|
||||
if a migration is completed.
|
||||
|
||||
This method can be used in a generally wide range, but the most common
|
||||
use case covered in this method is to rename the back-end name to the
|
||||
original volume id in your driver to make sure that the back-end still
|
||||
keeps the same id or name as it is before the volume migration. For
|
||||
this use case, there are two important fields: _name_id and
|
||||
provider_location.
|
||||
|
||||
The field _name_id is used to map the cinder volume id and the back-end
|
||||
id or name. The default value is None, which means the cinder
|
||||
volume id is the same to the back-end id or name. If they are different,
|
||||
_name_id is used to saved the back-end id or name.
|
||||
|
||||
The field provider_location is used to save the export information,
|
||||
created by the volume attach. This field is optional, since some drivers
|
||||
support the export creation and some do not. It is the driver
|
||||
maintainer's responsibility to decide what this field needs to be.
|
||||
|
||||
If the back-end id or name is renamed successfully, this method can
|
||||
return {'_name_id': None, 'provider_location': None}. It is the choice
|
||||
for your driver to implement this method and decide what use cases should
|
||||
be covered.
|
||||
|
Loading…
x
Reference in New Issue
Block a user