Multi-Region Support
A proposal for implementing multiple region support by simply allocating instances in different regions using the existing --os-region-name support. Includes support for allocating instances in multiple regions for replication and clustering. Support for restoring backups to different regions will also be included. APIImpact Implements Blueprint: bp/multi-region Change-Id: I6270310716944272651d6ac62bdd3e41e056f975
This commit is contained in:
parent
366287c8a8
commit
0ea5bb1712
577
specs/ocata/multi-region.rst
Normal file
577
specs/ocata/multi-region.rst
Normal file
@ -0,0 +1,577 @@
|
||||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
Sections of this template were taken directly from the Nova spec
|
||||
template at:
|
||||
https://github.com/openstack/nova-specs/blob/master/specs/juno-template.rst
|
||||
|
||||
..
|
||||
This template should be in ReSTructured text. The filename in the git
|
||||
repository should match the launchpad URL, for example a URL of
|
||||
https://blueprints.launchpad.net/trove/+spec/awesome-thing should be named
|
||||
awesome-thing.rst.
|
||||
|
||||
Please do not delete any of the sections in this template. If you
|
||||
have nothing to say for a whole section, just write: None
|
||||
|
||||
Note: This comment may be removed if desired, however the license notice
|
||||
above should remain.
|
||||
|
||||
|
||||
==================
|
||||
Multi-Region Trove
|
||||
==================
|
||||
|
||||
.. If section numbers are desired, unindent this
|
||||
.. sectnum::
|
||||
|
||||
.. If a TOC is desired, unindent this
|
||||
.. contents::
|
||||
|
||||
|
||||
Trove is currently able to deploy instances to multiple availability
|
||||
zones within a region, but is limited to deployments within a single
|
||||
Openstack region. This specification outlines a proposal for allowing
|
||||
Trove to deploy instances to multiple Openstack regions.
|
||||
|
||||
There are three different approaches to implementing multi-region
|
||||
support in Trove. The first approach would be for each region to have
|
||||
it's own Trove controller and to implement a consistent view of Trove
|
||||
instances across them; this would allow a user in any region to see
|
||||
all trove instances within their region, regardless of which Trove
|
||||
contoller created them. The second approach would be to have a single
|
||||
trove controller across all regions coordinated by a shared database
|
||||
(such as Galera); this would allow users in any region to see all
|
||||
trove instances in all regions. The third approach would be to have
|
||||
the Trove controller in each region to be independent, but able to
|
||||
create instances in other regions; this would allow a user to see all
|
||||
Trove instances created by the Trove controller in their region,
|
||||
regardless of which region the instance is in, but they would not be
|
||||
able to see Trove instances in their own region created by Trove
|
||||
contollers in other regions.
|
||||
|
||||
This specification outlines a proposal that would allow the second and
|
||||
third alternatives to be implemented. It is the author's belief that
|
||||
the first alternative would be far more complex, difficult to
|
||||
implement, and error prone than the second and third options.
|
||||
|
||||
Launchpad Blueprint:
|
||||
https://blueprints.launchpad.net/trove/+spec/multi-region
|
||||
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
Trove will be modified to be able to use Openstack's cross-region
|
||||
client access to implement support for creating Trove instances in
|
||||
other regions. Essentially, one Trove controller will be able to
|
||||
access Nova and Cinder services in multiple Openstack regions.
|
||||
|
||||
Multi-region support will require that the Keystone service be
|
||||
federated between the regions, effectively allowing the Trove
|
||||
controller to access services in multiple regions using a single,
|
||||
common authentication. This functionality is currently supported in
|
||||
Openstack.
|
||||
|
||||
Object storage (such as Swift) may be federated between the regions,
|
||||
or each region may have an independent object storage service. Where
|
||||
regions represent physically distinct data centres, a single shared
|
||||
implementation of object storage may be preferrable as it would allow
|
||||
data to be shared efficiently between the regions, rather than being
|
||||
transferred in it's entirety upon each access.
|
||||
|
||||
In the default configuration, each region will host an independent set
|
||||
of Trove contoller services, with each region having it's own Trove
|
||||
API, Taskmanager, and Conductor services backed by a separate Trove
|
||||
database for each region. When a Taskmanager in one region needs to
|
||||
allocate resources (compute and block storage) in a different region,
|
||||
it will use the OS_REGION_NAME parameter to the Nova and Cinder
|
||||
clients to access the appropriate Openstack services in the other
|
||||
region. The Trove instances allocated in the second region will only
|
||||
be visible to trove cli commands executed in the first region.
|
||||
|
||||
A second configuration will be possible where each region will host a
|
||||
set of Trove services which share a common Trove database implemented
|
||||
via a federated database product such as Galera clustering. This will
|
||||
allow users in each region to see all Trove instances, regardless of
|
||||
in which region they are hosted, but may expose the Trove services to
|
||||
the usual issues associated with running Openstack services on a
|
||||
database which uses optimistic locking. No testing of this
|
||||
alternative is envisioned for the initial implementation of
|
||||
multi-region support.
|
||||
|
||||
Implementing multi-region support as described in this document will
|
||||
require that the instances in each region be on a network shared
|
||||
across all regions, and that the instances be able to access the
|
||||
Rabbit network in each region.
|
||||
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
Supporting multiple regions, as laid out in this document, will
|
||||
primary consist of allowing the Trove services (API, Taskmanager, and
|
||||
Guestagent) to provide an OS_REGION_NAME parameter when accessing the
|
||||
clients for Nova and Cinder. Adding this support will encompass the
|
||||
following components:
|
||||
|
||||
* Add 'region' field to the Instances table in the Trove database.
|
||||
* Enhance the CLI and REST API to allow 'region name' to be specified
|
||||
for each instance to be created (both single instance and clusters)
|
||||
* Add 'region name' to guest agent RPC calls as needed (backup_info
|
||||
parameter of prepare call)
|
||||
* Enhance each datastore to use the 'region name' as appropriate
|
||||
|
||||
When specifying that an instance be started in a different region,
|
||||
Trove will need to ensure that an appropriate image is available in
|
||||
the target region. To do so, trove will contact the Glance service in
|
||||
the other region to retrieve the metadata for the image of the same
|
||||
name as specified in the datastore (in the first region). The
|
||||
checksums of the images in both regions will be compared to ensure
|
||||
that the same image in installed in each region.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
No changes to configuration files are envisioned.
|
||||
|
||||
Database
|
||||
--------
|
||||
|
||||
A 'region_name' field will be added to the Trove 'instances' table.
|
||||
|
||||
Migration scripts will be provided to add 'region_name' parameters to
|
||||
the above listed tables during Openstack release upgrades.
|
||||
|
||||
A region_name property will be added to the DBInstance class and
|
||||
shadowed in the SimpleInstance class.
|
||||
|
||||
Public API
|
||||
----------
|
||||
|
||||
A "region" parameter will be added to the following REST APIs to
|
||||
indicate the region in which the specified resource should be created.
|
||||
If the "region" parameter is not specified, the resource will be
|
||||
created in the region in which the command is executed.
|
||||
|
||||
Operations which do not create new resources, such as the list and
|
||||
show APIs, do not require additional region parameters. For those
|
||||
APIs, the region would be specified via the --os-region-name
|
||||
parameter.
|
||||
|
||||
When the Taskmanager is requested to create an instance in a region
|
||||
different than its own, it will need to ensure that a suitable image
|
||||
is available in that region to create the instance (as it will not be
|
||||
possible to tell the Nova in RegionB to use an image from RegionA).
|
||||
To create an instance in RegionB, the Taskmanager in RegionA will
|
||||
proceed as follows:
|
||||
|
||||
#. Retrieve the name of the appropriate image from the appropriate
|
||||
datastore_version in RegionA
|
||||
#. Retrieve the checksum from Glance for the image in RegionA
|
||||
#. Ensure that trove in RegionB has a datastore_version of the same
|
||||
name, and that datastore_version specifies an image of the same
|
||||
name
|
||||
#. Retrieve the checksum of the image from the Glance in RegionB
|
||||
#. Ensure that the image in both regions have identical checksums
|
||||
#. Follow a procedure similar to that above to ensure that a similarly
|
||||
named flavour exists in both regions and has similar properties
|
||||
#. Ask Nova in RegionB to create an instance with the appropriate
|
||||
image name and flavour
|
||||
|
||||
|
||||
Instance Create
|
||||
///////////////
|
||||
|
||||
Request::
|
||||
|
||||
POST v1/<tenant_id>/instances
|
||||
{
|
||||
"instance": {
|
||||
"volume": {
|
||||
"type": null,
|
||||
"size": 1
|
||||
},
|
||||
"flavorRef": 11,
|
||||
"name": "m",
|
||||
"replica_count": 1,
|
||||
"replica_of": "0d5e5bcc-5c60-4703-b4b3-17f32e0abe72",
|
||||
"region": "RegionA"
|
||||
}
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
"instance": {
|
||||
"created": "2016-03-08T16:13:30",
|
||||
"datastore": {
|
||||
"type": "mysql",
|
||||
"version": "5.6"
|
||||
},
|
||||
"flavor": {
|
||||
"id": "11",
|
||||
"links": [
|
||||
{
|
||||
"href": "https://<ip>:8779/v1.0/adbe7218e9f54369a0898f36d9c7a66d/flavors/11",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "https://<ip>:8779/flavors/11",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "0d5e5bcc-5c60-4703-b4b3-17f32e0abe64",
|
||||
"links": [
|
||||
{
|
||||
"href": "https://<ip>:8779/v1.0/adbe7218e9f54369a0898f36d9c7a66d/instances/0d5e5bcc-5c60-4703-b4b3-17f32e0abe64",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "https://<ip>:8779/instances/0d5e5bcc-5c60-4703-b4b3-17f32e0abe64",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"name": "m",
|
||||
"status": "BUILD",
|
||||
"updated": "2016-03-08T16:13:30",
|
||||
"volume": {
|
||||
"size": 1
|
||||
},
|
||||
"region": "RegionA"
|
||||
}
|
||||
}
|
||||
|
||||
Cluster Create
|
||||
//////////////
|
||||
|
||||
Request::
|
||||
|
||||
POST /v1.0/<tenant_id>/clusters
|
||||
{
|
||||
"cluster": {
|
||||
"name": "products",
|
||||
"datastore": {
|
||||
"type": "percona",
|
||||
"version": "5.5"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"flavorRef": "2",
|
||||
"volume": {
|
||||
"size": 100
|
||||
},
|
||||
"region": "RegionA",
|
||||
},
|
||||
{
|
||||
"flavorRef": "2",
|
||||
"volume": {
|
||||
"size": 100
|
||||
},
|
||||
"region": "RegionA",
|
||||
},
|
||||
{
|
||||
"flavorRef": "2",
|
||||
"volume": {
|
||||
"size": 100
|
||||
},
|
||||
"region": "RegionB",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
"cluster": {
|
||||
"id": "dfbbd9ca-b5e1-4028-adb7-f78643e17998",
|
||||
"task": {
|
||||
"id": 2,
|
||||
"name": "BUILDING",
|
||||
"description": "Building the initial cluster."
|
||||
},
|
||||
"name": "products",
|
||||
"created": "2014-04-25T20:19:23",
|
||||
"updated": "2014-04-25T20:19:23",
|
||||
"links": [{...}],
|
||||
"datastore": {
|
||||
"type": "percona",
|
||||
"version": "5.5"
|
||||
},
|
||||
"region": "RegionA",
|
||||
"instances": [
|
||||
{
|
||||
"id": "416b0b16-ba55-4302-bbd3-ff566032e1c1",
|
||||
"status": "BUILD",
|
||||
"flavor": {
|
||||
"id": "2",
|
||||
"links": [{...}]
|
||||
},
|
||||
"volume": {
|
||||
"size": 100
|
||||
},
|
||||
"region": "RegionA",
|
||||
},
|
||||
{
|
||||
"id": "965ef811-7c1d-47fc-89f2-a89dfdd23ef2",
|
||||
"status": "BUILD",
|
||||
"flavor": {
|
||||
"id": "2",
|
||||
"links": [{...}]
|
||||
},
|
||||
"volume": {
|
||||
"size": 100
|
||||
},
|
||||
"region": "RegionA",
|
||||
},
|
||||
{
|
||||
"id": "3642f41c-e8ad-4164-a089-3891bf7f2d2b",
|
||||
"status": "BUILD",
|
||||
"flavor": {
|
||||
"id": "2",
|
||||
"links": [{...}]
|
||||
},
|
||||
"volume": {
|
||||
"size": 100
|
||||
},
|
||||
"region": "RegionB",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cluster-grow
|
||||
////////////
|
||||
|
||||
Request::
|
||||
|
||||
POST /v1.0/<tenant_id>/clusters/<cluster-id>/action
|
||||
{
|
||||
"grow": [
|
||||
{
|
||||
"name": "redis-clstr-member-5",
|
||||
"instance_type": "master",
|
||||
"flavorRef": "2",
|
||||
"volume": {
|
||||
"size": 2
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "redis-clstr-member-6",
|
||||
"instance_type": "slave",
|
||||
"related_to": "redis-clstr-member-5",
|
||||
"flavorRef": "2",
|
||||
"volume": {
|
||||
"size": 2
|
||||
},
|
||||
"region": "RegionB",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Response::
|
||||
|
||||
{
|
||||
"cluster": {
|
||||
"id": "edaac9ca-b5e1-4028-adb7-fa7653e11224",
|
||||
"task": {
|
||||
"id": 2,
|
||||
"name": "BUILDING",
|
||||
"description": "Building the initial cluster."
|
||||
},
|
||||
"name": "redis-clstr",
|
||||
"created": "2015-01-29T20:19:23",
|
||||
"updated": "2015-01-29T20:19:23",
|
||||
"links": [{...}],
|
||||
"datastore": {
|
||||
"type": "redis",
|
||||
"version": "3.0"
|
||||
},
|
||||
"ip": [],
|
||||
"region": "RegionA",
|
||||
"instances": [
|
||||
{
|
||||
"id": "416b0b16-ba55-4302-bbd3-ff566032e1c1",
|
||||
"name": "redis-clstr-member-5",
|
||||
"instance_type": "master",
|
||||
"status": "BUILD",
|
||||
"ip": [],
|
||||
"links": [{...}],
|
||||
"flavor": {
|
||||
"id": "2",
|
||||
"links": [{...}]
|
||||
},
|
||||
"volume": {
|
||||
"size": 2
|
||||
}
|
||||
"region": "RegionA",
|
||||
},
|
||||
{
|
||||
"id": "965ef811-7c1d-47fc-89f2-a89dfdd23ef2",
|
||||
"name": "redis-clstr-member-6",
|
||||
"instance_type": "slave",
|
||||
"related_to": "redis-clstr-member-5",
|
||||
"status": "BUILD",
|
||||
"ip": [],
|
||||
"links": [{...}],
|
||||
"flavor": {
|
||||
"id": "2",
|
||||
"links": [{...}]
|
||||
},
|
||||
"volume": {
|
||||
"size": 2
|
||||
}
|
||||
"region": "RegionB",
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Public API Security
|
||||
-------------------
|
||||
|
||||
This change should not have security impact.
|
||||
|
||||
Python API
|
||||
----------
|
||||
|
||||
"region" parameters will be added to the Instances.create(),
|
||||
Clusters.create(), and Clusters.grow() calls.
|
||||
|
||||
CLI (python-troveclient)
|
||||
------------------------
|
||||
|
||||
A "--region" option will be added to the "trove create" CLI command
|
||||
corresponding to the "region" parameter in the Instances.create() Python API.
|
||||
|
||||
A "region" option will be added to the "--instance" option of the
|
||||
"trove cluster-create" and "trove cluster-grow" CLI commands
|
||||
corresponding to the Clusters.create() and Clusters.grow() Python
|
||||
APIs.
|
||||
|
||||
Internal API
|
||||
------------
|
||||
|
||||
The "region" parameter will be added to the appropriate Taskmanager
|
||||
calls to support instance creation for both single instance and
|
||||
cluster creation.
|
||||
|
||||
The Trove Instance class already has a nova_client property that
|
||||
creates a unique client connection for each guest instance. That call
|
||||
will be enhanced to specify the name of the region in which the
|
||||
instance exists; the create_nova_client() method in remote.py will be
|
||||
enhanced to optionally take a region name parameter.
|
||||
|
||||
|
||||
Guest Agent
|
||||
-----------
|
||||
|
||||
The only change to the guest agent should be to support initializing a
|
||||
database with data stored in a different region. This would occur
|
||||
during the prepare process, and is to support creating a replica from
|
||||
a backup of a master in a differnt region.
|
||||
|
||||
The guest.prepare() call already takes a structure called backup_info
|
||||
which contains details of the backup to be used to initialize the
|
||||
database. This change will add a member "region" to the backup_info
|
||||
structure which will be the name of the region containing the backup.
|
||||
That region name will be passed to the Swift client to tell Swift in
|
||||
which region the backup was created; note, however, that it is
|
||||
expected that Swift will normally be configured to be shared across
|
||||
regions and so be able to optimize object access from all regions.
|
||||
|
||||
When a taskmanager in RegionA creates an instance in RegionB, it will
|
||||
pass a guestagent.conf to the new instance. The new instance in
|
||||
RegionB will use the rabbit configuration parameters in the conf file
|
||||
to determine how to connect to the rabbit broker in RegionA. No
|
||||
changes should be required to the existing guest agent to support this
|
||||
functionality.
|
||||
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
As indicated in the introduction, an alternative to the design
|
||||
suggested here would be to have the trove controllers perform their
|
||||
own synchronization giving each controller a view of every Trove
|
||||
instance. This would require that all operations be coordinated with
|
||||
the Trove controllers in every region, either via some form of Two
|
||||
Phase Commit or some Eventual Consistency mechanism. Implementing
|
||||
this would be quite complex and offer little benefit beyond the shared
|
||||
database implementation.
|
||||
|
||||
|
||||
|
||||
Dashboard Impact (UX)
|
||||
=====================
|
||||
|
||||
The user should be able to select the region in which a new instance
|
||||
or cluster is to be created.
|
||||
|
||||
Panels which display properties of instances or clusters should be
|
||||
enhanced to display the region name.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
6-morgan
|
||||
|
||||
Milestones
|
||||
----------
|
||||
|
||||
Target Milestone for completion:
|
||||
eg. Liberty-1
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
Already implemented, code awaiting spec approval.
|
||||
|
||||
|
||||
Upgrade Implications
|
||||
====================
|
||||
|
||||
No upgrade implications are envisioned as a result of this change.
|
||||
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
No dependecies.
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
No int-tests will be developed for this feature due to the difficulty
|
||||
of creating multiple regions within devstack.
|
||||
|
||||
|
||||
Documentation Impact
|
||||
====================
|
||||
|
||||
Documentation will be necessary for the new parameters to the Trove
|
||||
CLI commands.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
|
||||
Appendix
|
||||
========
|
||||
|
||||
None.
|
Loading…
x
Reference in New Issue
Block a user