299 lines
16 KiB
PHP
299 lines
16 KiB
PHP
===========================
|
|
Gluon Plugin Wrapper Design
|
|
===========================
|
|
|
|
**Original Gluon Architecture**
|
|
|
|
In the original design of Gluon, the Gluon Server was placed in the
|
|
communication path between Nova and the networking backends. Its main purpose
|
|
was to maintain a mapping of ports to networking backends and to route
|
|
port-related requests to the correct backend. See diagram below.
|
|
|
|
::
|
|
|
|
+-------------------------+
|
|
| |
|
|
| Nova |
|
|
| |
|
|
| +---------------+ |
|
|
| | Gluon | |
|
|
| | Plugin | |
|
|
+----+---------------+----+
|
|
|
|
|
| Port Requests
|
|
|
|
|
v
|
|
+-------------------------+
|
|
| |
|
|
| Gluon |
|
|
Register Port | Server | Register Port
|
|
+------------------>| |<-------------------+
|
|
| | +---------+---------+ | |
|
|
| | | Neutron | Proton | | |
|
|
| +--+---------+---------+--+ |
|
|
| | | |
|
|
| Neutron Port Requests | | Gluon Port Requests |
|
|
| +-----------+ +------------+ |
|
|
| | | |
|
|
| | | |
|
|
| v v |
|
|
| +-------------------------+ +-------------------------+ |
|
|
| | | | | |
|
|
| | Neutron | | Proton | |
|
|
+--| Server | | Server |--+
|
|
| | | |
|
|
+-------------------------+ +-------------------------+
|
|
|
|
The set of networking backends could be the Neutron Server plus one or more
|
|
Proton Servers. In the original design, each networking backend would register
|
|
a new port with the Gluon Server in order to populate the mapping. When the
|
|
Gluon Server received a port-related request, it would look up the port and
|
|
then forward the request to the correct backend by calling its associated
|
|
client driver. This required the Gluon Server to import and manage drivers
|
|
for the different types of networking backends. Another important aspect of
|
|
the original design is that the port objects and associated networking service
|
|
objects were maintained in each networking backend database. Hence, the
|
|
Neutron Server had no visibility to the ports defined in the Proton Server(s).
|
|
|
|
In order to get the port-related requests directed to the Gluon Server, the
|
|
original design of Gluon replaced the Networking API plugin in Nova with a
|
|
modified version of the code that would provide a port-centric model of
|
|
networking and forward all requests to the Gluon Server. In the Mitaka
|
|
release, the Networking API plugin in Nova was deprecated allowing Nova to only
|
|
communicate with Neutron. This requires a significant change to the Gluon
|
|
design.
|
|
|
|
**New Gluon Architecture**
|
|
|
|
This document describes a way to loosely integrate the Gluon Server
|
|
functionality into Neutron while minimizing changes to the existing Proton
|
|
Server design. In this proposed design, the Proton Server will remain an API
|
|
endpoint and maintain a separate database from the Neutron Server. Since we
|
|
can no longer replace the plugin in Nova, the integration point for Gluon can
|
|
be done in the Neutron Server using the Core plugin interface.
|
|
|
|
The Gluon Wrapper Plugin will subclass off of the ML2 core plugin class (or
|
|
any other Core Plugin class) and override just the port-related methods. If
|
|
the method call is for a Gluon port, the Gluon Wrapper Plugin code will forward
|
|
the request to the Proton Server for processing. Otherwise, the superclass
|
|
method will be called. The goal is to introduce the Gluon networking
|
|
functionality without breaking the existing ML2 networking - and to ensure
|
|
that a user that doesn't need extended network functionality does not have
|
|
to install it and is not affected by Gluon development - the stability of their
|
|
system remains as before because the code they're running is no different.
|
|
The following diagram provides an overview of this design.
|
|
|
|
::
|
|
|
|
+-------------------------+
|
|
| |
|
|
| Nova |
|
|
| |
|
|
| +---------------+ |
|
|
| | Neutron | |
|
|
| | API Plugin | |
|
|
+----+---------------+----+
|
|
|
|
|
| Port Requests
|
|
|
|
|
v
|
|
+--------------------------------+
|
|
| Neutron |
|
|
| Server |
|
|
| |
|
|
| +-------------------+ |
|
|
| |+-----------------+| |
|
|
| || ML2 Plugin || |
|
|
| |+-----------------+| |
|
|
| | Gluon Wrapper | |
|
|
| | Plugin | |
|
|
| | +-------------+| |
|
|
| | |Proton Driver|| |
|
|
+------+----+-------------++-----+
|
|
^ |
|
|
| |
|
|
Check Gluon Port | | Gluon Port Requests
|
|
+-----------+ +-----------+
|
|
| |
|
|
| |
|
|
v v
|
|
+---------+ +-------------------------+
|
|
| etcd | | |
|
|
| | | Proton |
|
|
+---------+ | Server |
|
|
^ | |
|
|
| | |
|
|
| | |
|
|
| | |
|
|
| +-------------------------+
|
|
| |
|
|
| |
|
|
+---------------------------------+
|
|
Register Port
|
|
|
|
|
|
The Gluon Wrapper Plugin will determine if a port belongs to Gluon by examining
|
|
(looking up the UUID) the etcd database. The port registration code in the
|
|
Proton Server will be changed to also update the etcd database when a new port is
|
|
created or deleted. When a port is registered in the etcd database, the
|
|
following backend information is stored: tenant identifier, networking service
|
|
identifier and Proton Server base URL. In order to forward the requests to the
|
|
Proton Server(s), the same backend driver mechanism will be used by the Gluon
|
|
Wrapper Plugin as was used by the Gluon Sever.
|
|
|
|
Since we can no longer replace the Networking API plugin in Nova, we must
|
|
provide a consistent “Neutron” networking model to Nova. Therefore, we have
|
|
to maintain the Network, Subnet and Port associations required by the logic in
|
|
the Neutron API plugin (in Nova), at least until we can simplify the Nova-Neutron
|
|
communication so that Nova does not need to retrieve subnet and network objects.
|
|
In the short term, we can create a “dummy”
|
|
Network and Subnet object in the Neutron Server that can be associated with all
|
|
Gluon ports. In the long term, it may be possible to add attributes to the
|
|
Network and Subnet objects to change the semantics of the objects to reflect a
|
|
more logical association with the Gluon ports. This document describes the
|
|
creation and usage of the Network and Subnet “dummy” objects without any
|
|
changes to the existing Neutron model.
|
|
|
|
The “dummy” Network and Subnet objects need to be created during system turn
|
|
up. The Network and Subnet objects must be uniquely identifiable by the Gluon
|
|
Wrapper Plugin. One approach would be to specify the UUID of these objects in
|
|
the configuration file which can be loaded when the Neutron Server starts.
|
|
Another approach would be to give the objects unique names that can be
|
|
retrieved at runtime. The Network object needs to be created as a local shared
|
|
provider network. The Subnet object created for the Network should have the
|
|
gateway and DHCP disabled. The CIDR should not matter.
|
|
|
|
**Plugin Processing**
|
|
|
|
The Gluon Wrapper Plugin only has to intercept and handle the following methods
|
|
from the Core plugin base class:
|
|
|
|
- update_port() - Update port values for bind/unbind operations
|
|
- get_port() - Return port values for specific port
|
|
- get_ports() - Return a list of ports
|
|
|
|
The following diagram show the component interaction required to support the
|
|
processing of the above requests.
|
|
|
|
|
|
::
|
|
|
|
Neutron API
|
|
|
|
| update_port()
|
|
| get_port()
|
|
| get_ports()
|
|
|
|
|
v
|
|
+------------------+ Function +------------------+
|
|
| | Call | |
|
|
| | | |
|
|
| Gluon Wrapper | | Proton Backend |
|
|
| Plugin |-------------------->| Driver |
|
|
| | bind_port() | |
|
|
| | unbind_port() | |
|
|
+------------------+ get_port() +------------------+
|
|
| |
|
|
| |
|
|
| read(port) |
|
|
| read(directory) | HTTP/REST
|
|
| |
|
|
| |
|
|
v v
|
|
+-----------+ +------------------+
|
|
| etcd | | |
|
|
| | | |
|
|
+-----------+ | Proton Server |
|
|
| |
|
|
| |
|
|
| |
|
|
+------------------+
|
|
|
|
The Neutron API will convert updates to the port object into an update_port()
|
|
method call to the Core Plugin. The port UUID is passed as a parameter to this
|
|
method. The Gluon Wrapper Plugin overrides this method and will attempt to read
|
|
the corresponding backend information for the port from the etcd database. The
|
|
key used is “/gluon/port/<uuid>”. If no backend information is found, the port
|
|
is assumed to be a Neutron port and the superclass update_port() method is
|
|
called. If the backend information is found, the network service identifier is
|
|
used to retrieve the backend driver for the specific networking service. The
|
|
port values are examined to determine if the port is being bound or unbound.
|
|
The host identifier field is used for this determination. The bind_port() or
|
|
unbind_port() method is called on the backend driver. The backend driver will
|
|
convert the "bind/unbind" operation into the appropriate REST calls to a Proton
|
|
Server. It is possible to have multiple Proton Server endpoints. The base URL
|
|
from the backend information is used to identify the Proton Server hosting the
|
|
networking service API. It is the responsibility of the backend driver to
|
|
collect the response(s) from the Proton Server and reformat the response into
|
|
the format expected by the plugin. In this case, the entire set of port values
|
|
is expected in the response. The backend driver will also insert the network_id
|
|
and fixed_ips fields in the response to make the object fit in the Neutron
|
|
model. The network_id is the UUID of the “dummy” Gluon Network object. The
|
|
fixed_ips field contains the UUID of the “dummy” Gluon Subnet object with the
|
|
IP address taken from the Gluon port (if applicable).
|
|
|
|
The Neutron API will convert a retrieval of a port object into a get_port()
|
|
method call to the Core Plugin. The port UUID is passed as a parameter to this
|
|
method. The Gluon Wrapper Plugin overrides this method and will attempt to read
|
|
the corresponding backend information for the port from the etcd database. The
|
|
key used is “/gluon/port/<uuid>”. If no backend information is found, the port
|
|
is assumed to be a Neutron port and the superclass get_port() method is called.
|
|
If the backend information is found, the network service identifier is used to
|
|
retrieve the backend driver for the specific networking service. The
|
|
get_port() method is called on the backend driver. The backend driver will
|
|
convert the “get" operation into the appropriate REST calls to a Proton Server.
|
|
It is possible to have multiple Proton Server endpoints. The base URL from the
|
|
backend information is used to identify the Proton Server hosting the
|
|
networking service API. It is the responsibility of the backend driver to
|
|
collect the response(s) from the Proton Server and reformat the response into
|
|
the format expected by the plugin. In this case, the entire set of port values
|
|
is expected in the response. The backend driver will also insert the network_id
|
|
and fixed_ips fields in the response to make the object fit in the Neutron
|
|
model. The network_id is the UUID of the “dummy” Gluon Network object. The
|
|
fixed_ips field contains the UUID of the “dummy” Gluon Subnet object with the
|
|
IP address taken from the Gluon port (if applicable).
|
|
|
|
The Neutron API will convert a retrieval of multiple port objects into a
|
|
get_ports() method call to the Core Plugin. An optional filter parameter may
|
|
be passed to restrict the list of ports to be returned. The Gluon Wrapper
|
|
Plugin overrides this method and will first call the superclass method to get
|
|
the list of Neutron ports meeting the filter criteria. Next the etcd database
|
|
is read to get all of the values in the “/gluon/port” directory. For each UUID
|
|
found, the corresponding backend driver get_port() method is called to retrieve
|
|
the port information. The filter is applied to the port data and if passes the
|
|
port is appended to the port list. The final result is a list of Neutron and
|
|
Gluon ports that meet the filter criteria.
|
|
|
|
**Plugin Usage**
|
|
|
|
The Gluon package must be installed on the same controller server as the Neutron
|
|
package. The core_plugin option in the neutron.conf has to be changed to
|
|
point to the Gluon Wrapper plugin. For example, edit /etc/neutron.conf and set
|
|
core_plugin as follows:
|
|
|
|
``core_plugin = gluon.plugin.core.GluonPlugin``
|
|
|
|
Restart the Neutron Server. It should pickup the Gluon Plugin. You can verify
|
|
by looking for "gluon" in the neutron server log file.
|
|
|
|
For now, the GluonPlugin expects the etcd server and Proton Server to be
|
|
running on the same server. This will be changed when configuration parameters
|
|
are added to the .conf file.
|
|
|
|
Before a Gluon port can be used, the "dummy" objects need to be created in
|
|
Neutron (as admin). The names are significant for now.
|
|
|
|
Create Gluon Network object:
|
|
|
|
*neutron net-create --shared --provider:network_type local GluonNetwork*
|
|
|
|
Create Gluon Subnet object:
|
|
|
|
*neutron subnet-create --name GluonSubnet --no-gateway --disable-dhcp GluonNetwork 0.0.0.0/1*
|
|
|
|
At this point you should be able to create the objects in the Proton Server and
|
|
use nova boot to create a VM using the Gluon port.
|
|
|
|
|
|
|