http driver

This is a proposal to create a new driver implementation which communicates RPC client and server directly over HTTP without messaging queue.

Problem description

In oslo.messaging, RabbitMQ driver is widely used and validated that the driver works very stably on most of OpenStack environment. However, in PUB/SUB model using message queue, message queue itself might be a single point of failure and also message queue is bit difficult to support large scale of client and server communications.

For example, if there are more than 10,000 hypervisors which host nova-compute and neutron-agent, each RabbitMQ node must always support large number (ex. more than 40,000) of network connections from nova and neutron clients. In this situation, if RabbitMQ cluster restart happens, large number of RPC clients started to connect RabbitMQ nodes simultaneously, this makes RabbitMQ nodes unstable.

Also due to large number of hypervisors, RabbitMQ must support huge number of message queues to allow to communicate neutron-server and neutron-agent, for example. All queue data must be synchronized between all RabbitMQ nodes, so having large number of queue also makes RabbitMQ cluster unstable.

Note, this is not a proposal to deny RabbitMQ (PUB/SUB model) backend. The proposal should be aware both PUB/SUB model and REQ/RESP model have different advantages described in the following section.

PUB/SUB advantage examples

  • Simple architecture in a small cluster

  • Easy ACL configuration in a secure cluster

REQ/RESP advantage examples

  • Fault tolerant against control plane (consul) down

  • Easy to scale out the cluster

As mentioned in above, the PUB/SUB model has simple and easy to use most of the cases, but for large scale OpenStack environment, REQ/RESP model for all RPC communications could be more proper and reliable.

This specification proposes to implement OpenAPI based REQ/RESP model driver called http driver which enable to communicates between RPC client to RPC server directly without a component which is single point of failure for OpenStack internal communication.

Proposed change

This is overview diagram of HTTP driver for RPC Call/Cast/Cast Fanout requests. There are 4 main components to realize the driver.

  • RPC client

  • RPC server

  • Endpoint datastore (ex. Consul)

  • Broadcaster

              +--------------+
      +------>|   Consul     |<------------------+
      |       +--------------+                   |
      |                                     +-------------+
      |                                +--->|  RPC server |
      |                                |    +-------------+
+-------------+   Call/Cast RPC        |    +-------------+
| RPC client  +---------------------------> |  RPC server |
+-------------+                        |    +-------------+
      |                                |    +-------------+
      | Cast Fanout                    +--->|  RPC server |
      |                                |    +-------------+
      |       +--------------+         |
      +------>| Broadcaster  |---------+
              +--------------+
           Send Cast to all RPC servers

Note

Scope of the proposal

  • The scope of this proposal covers Call/Cast/Cast Fanout RPC cases

  • Notification is out of scope in this proposal

Main points to be improved by the architecture

  • Separate control plane from data plane

  • Allow direct API call without single point of failure

  • Reduce RPC communication between multiple availability zones

Responsibility of each components like followings.

RPC Client

Fetch the RPC server list from the consul cluster for an RPC target service. Pick up appropriate RPC server for the RPC, then send a RPC request over HTTP protocol.

RPC Server

Listen and handle an in-coming rpc request over HTTP protocol

When the RPC server starts, the server registers its RPC server information to Consul cluster as Consul’s “service”. Also the PRC Server works as Push Style, not poll style.

For RPC client/server communication over HTTP with RESTful API, OpenAPI allows us to define formatted RESTful API definition easily. Once API definition is generated, it can be launched as http server using Web framework and WSGI server. For example, they are candidate for Web framework and WSGI server to enable HTTP client and server.

  • Web famework: connexion

  • WSGI server: eventlet

Endpoint datastore

Store the RPC server information.

The server information includes following items. oslo.messaging layer information(exchange, topic and server) RPC server information (IP address, port and etc).

In this spec, Consul is one example imeplementation for the endpoint datastore.

For other use-case, the service discovery feature code with backend selectable implementation should be added for users who would like to avoid introducing new dependency for datastore.

HTTP Broadcaster

An amplifier for an HTTP request

HTTP protocol doesn’t have broadcast mechanism though the oslo RPC has Cast Fanout RPC. The Broadcaster sends an in-coming RPC to all target RPC servers.

Sample RPC communication flow for Nova

              +--------------+
      +------>|   Consul     |
      |       +--------------+
      |
      |             * Call RPC
+----------------+  (1) select_destinations    +----------------+
| nova-conductor +---------------------------> | nova-scheduler |
|                +------+                      +----------------+
+----------------+      | * Cast RPC
                        | (2) build_and_run_instance
                        |                      +----------------+
                        +--------------------->|  nova-compute  |
                                               +----------------+

In this figure, nova-conductor on left side is RPC client and each nova-scheduler and nova-compute on right side are RPC servers.

select_destinations() Call RPC

During instance creation, in order to choose target nova-compute node to launch new instance, nova-conductor make a Call RPC request select_destinations() to nova-scheduler. In this case, Call RPC communication works with following steps.

  1. A nova-conductor fetches nova-scheduler’s hostn and port port information from Consul, and pick one of Call RPC target randomly

  2. A nova-conductor makes a select_destinations() Call RPC and wait a response.

build_and_run_instance() Cast RPC

During instance creation, once target nova-compute is choosen by scheduler, nova-conductor sends instance creation request to target nova-compute using build_and_run_instance() Cast RPC. In this case, Cast RPC communication works with following steps.

  1. A nova-conductor fetches a target nova-compute’s host and port information from Consul

  2. A nova-conductor makes a build_and_run_instance() Cast RPC and return immediately without waiting actual instance creation

Sample RPC server information registered in Consul

Nova’s RPC server information

This figure shows Nova’s RPC server information registered into nova AZ. Nova has nova.scheduler, nova-conductor, nova-compute and nova-consoleauth as RPC server.

../../_images/consul-service-list.png

nova-condutor RPC server list

This figure shows nova-conductor RPC server list on nova AZ. Each nova-conductor has <service name>:<port number> and also <IP address>:<port number> identifier. RPC client access to RPC server via the <IP address>:<port number>.

../../_images/conductor-service-list.png

Health check status of one of nova-condutor RPC server

Consul has health check mechanism for registered HTTP endpoint. The figure shows one of nova-conductor RPC server respond 200 OK to Consul’s periodical health check. If the endpoint is healthy, the endpoint marked as green check.

../../_images/conductor-health-check.png

Multi-AZ support

Consul has a feature to federate multiple Consul cluster into one to support multiple datacenter case. In the figure, there are multiple nova AZ such as nova, az-1, az-2 and az-3, then each nova AZ has one Consul cluster. These 4 Consule clusters are manged as one cluster using Consul federation.

../../_images/consul-federation.png

Alternatives

Datastore for host/topic management

In above architecture, Consul is chosen because it supports healthcheck mechanism and multi DC federation so that these features enable user to monitor RPC server status easily, and scale out easily to support large scale OpenStack.

But alternatively, managing service endpoint using Keystone service catalog, DNS or registering data into Redis cluster similar to ZeroMQ are another choices.

Once the endpoint datastore supports selectable mechanism, these alternative datasotre plugin can be developped based on use-cases.

Cast Fanout support design

In above diagram, broadcaster process is splitted out as one another service from RPC client. The Cast Fanout could be implemented into RPC client, but it takes much CPU and memory if number of targets are quite huge. Instead, by splitting out the broadcaster, the user easily scale out number of broadcaster processes based on number targets on OpenStack cluster.

API framework

For API schema definition, any approaches are available. For example, there are REST, OpenAPI, json-rpc, gRPC or any http protocol implementation are available if it allow to integrated with eventlet which is used by oslo.service. In above diagram, OpenAPI is chosen in order to realize HTTP protocol client-server model.

Advanced feature

Multi Availability zones support

  • Consul provides Federation mechanism between multiple Consul clusters.

  • By using the Federation, Consul cluster can be splitted per OpenStack Availability zones.

  • Splitting Consul to multiple cluster reduces workload of Consul and makes the cluster stable.

  • Also in basic, RPC client and server communication happen in one Availability zone. This reduces network communication between multiple AZ.

Availability Zone-A                Availability Zone-B
+----------------+                 +----------------+
|                |   RPC Request   |                |
|   RPC server   |        +------->+   RPC server   |
|       |        |        |        |       |        |
|       |        |        |        |       |        |
|   RPC client   +--------+        |   RPC client   |
|       |        |                 |       |        |
|       |        |   Federation    |       |        |
| Consul Cluster +<--------------->+ Consul Cluster |
|                |                 |                |
+----------------+                 +----------------+

Impact on Existing APIs

None.

Security impact

  • OpenAPI supports SSL based communication between client and server. This enables secure RPC communication same as other messaging drivers.

Performance Impact

Performance should become better because RPC client communicates to RPC server directly over HTTP.

Configuration Impact

New config options to configure http server are needed. Here is sample config parameters which is defined in oslo.messaging library user configuration file like nova.conf, neutron.conf.

[oslo_messaging_http]
port_range=20000:20100

[consul]
port = 8500
host = <Consul hostname>
token = <Consul token>
check_timeout = 60s
check_deregister = 30m

[http_driver]
http_token = <Token to access OpenAPI server>
http_api_config_file = <OpenAPI definition>
enable_ssl = True
ssl_certfile = <Path for SSL Cert file>
ssl_keyfile =  <Path for SSL Key file>
listen_timeout = 60

Detailed design for port_range

For port_range, following spec could reduce complexity of this option.

  1. If the port_range is not defined, unused ephemeral port is chosen randomly. For most of use cases, this satisfies the requirement.

  2. If the port_range is defined, RPC server pick port from the specified range during service launch.

Here is the reason why multiple ports are required for RPC server. For example, Nova has “conductor.workers” config parameter and Neutron-server has “rpc_workers” config parameter. By specifying more than “1” for these configs, multiple RPC workers are launched on single host. Therefore, from RPC client-server communication perspective, each RPC worker must have individual destination port number to launch it on a host.

And purpose of port_range is to support secure cloud environment which strictly manages network communication using dest/source port at firewall, it would be better that default behavior is random choice from unused ephemeral port.

Developer Impact

If other OpenStack component use http rpc_backend, oslo_messaging_http, consul and http_driver configuration section must be defined based on Consul and OpenAPI configuration.

Testing Impact

Basic unit test and integration test (using DevStack) will be implemented.

Implementation

Assignee(s)

Primary assignee:

Mitsuhiro Tanino (mitsuhiro-tanino)

Other contributors:

Xiang Wang

Yushiro Furukawa (y-furukawa-2)

Masahito Muroi (masahito-muroi)

Milestones

None

Work Items

  • Propose driver and test codes

  • Release note and docs

Documentation Impact

The http driver documentation will be added to the library. This documentation will follow the style of documentation provided by the other drivers and should include the following topics:

  • Overview of http driver architecture

  • pre-requisites

  • driver options overview

  • Consul configuration

  • HTTP broadcaster configuration

Dependencies

None

References

None

Note

This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode