From: Miguel Angel Ajo Date: Tue, 14 Jul 2015 12:31:55 +0000 (+0200) Subject: QoS Service devref X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=6140da5f25da126cdbfae3e9ee397315e7834fc5;p=openstack-build%2Fneutron-build.git QoS Service devref This is initial version that should be ready for merge. After we get it in the tree, we'll be able to expand on demand or even as part of patches that change the implementation in significant way. Co-Authored-By: Ihar Hrachyshka Change-Id: I3d89bcbb9c64b87d7425155c33b2f753176e94fd --- diff --git a/doc/source/devref/quality_of_service.rst b/doc/source/devref/quality_of_service.rst index 7d0e8e368..53b9942d3 100644 --- a/doc/source/devref/quality_of_service.rst +++ b/doc/source/devref/quality_of_service.rst @@ -1,4 +1,256 @@ +================== Quality of Service ================== +Quality of Service advanced service is designed as a service plugin. The +service is decoupled from the rest of Neutron code on multiple levels (see +below). + +QoS is the first service/api extension to extend core resources (ports, +networks) without using mixins inherited from plugins. + +Details about the DB models, API extension, and use cases can be found here: `qos spec `_ +. + +Service side design +=================== +* neutron.extensions.qos: + base extension + API controller definition. + +* neutron.services.qos.qos_plugin: + QoSPlugin, service plugin that implements 'qos' extension, receiving and + handling API calls to create/modify policies and rules. It also handles core + plugin requests to associate ports and networks with a QoS policy. + +* neutron.services.qos.drivers.qos_base: + the interface class for server-side QoS backend which will receive {create, + update, delete} events on any rule change. + +* neutron.services.qos.drivers.rpc.mq_qos: + message queue based reference backend driver which provides messaging + notifications to any interested agent, using `RPC callbacks `_. + + +QoS resources +------------- + +QoS design defines the following two conceptual resources to define QoS rules +for a port or a network: + +* QoS policy +* QoS rule (type specific) + +Each QoS policy contains zero or more QoS rules. A policy is then applied to a +network or a port, making all rules of the policy applied to the corresponding +Neutron resource (for a network, applying a policy means that the policy will +be applied to all ports that belong to it). + +From database point of view, following objects are defined in schema: + +* QosPolicy: directly maps to the conceptual policy resource. +* QosNetworkPolicyBinding, QosPortPolicyBinding: defines attachment between a + Neutron resource and a QoS policy. +* QosRule: defines common rule fields for all supported rule types. +* QosBandwidthLimitRule: defines rule fields that are specific to + bandwidth_limit type (the only type supported by the service as of time of + writing). + +There is a one-to-one relationship between QosRule and type specific +QosRule database objects. We represent the single object with two tables +to avoid duplication of common fields. (That introduces some complexity in +neutron objects for rule resources, but see below). + +All database models are defined under: + +* neutron.db.qos.models + +There is a long history of passing database dictionaries directly into business +logic of Neutron. This path is not the one we wanted to take for QoS effort, so +we've also introduced a new objects middleware to encapsulate the database logic +from the rest of the Neutron code that works with QoS resources. For this, we've +adopted oslo.versionedobjects library and introduced a new NeutronObject class +that is a base for all other objects that will belong to the middle layer. +There is an expectation that Neutron will evolve into using objects for all +resources it handles, though that part is obviously out of scope for the QoS +effort. + +Every NeutronObject supports the following operations: + +* get_by_id: returns specific object that is represented by the id passed as an + argument. +* get_objects: returns all objects of the type, potentially with a filter + applied. +* create/update/delete: usual persistence operations. + +Base object class is defined in: + +* neutron.objects.base + +For QoS, new neutron objects were implemented: + +* QosPolicy: directly maps to the conceptual policy resource, as defined above. +* QosBandwidthLimitRule: class that represents the only rule type supported by + initial QoS design. + +Those are defined in: + +* neutron.objects.qos.policy +* neutron.objects.qos.rule + +For QosPolicy neutron object, the following public methods were implemented: + +* get_network_policy/get_port_policy: returns a policy object that is attached + to the corresponding Neutron resource. +* attach_network/attach_port: attach a policy to the corresponding Neutron + resource. +* detach_network/detach_port: detach a policy from the corresponding Neutron + resource. + +In addition to the fields that belong to QoS policy database object itself, +synthetic fields were added to the object that represent lists of rules, +per-type, that belong to the policy. For example, to get a list of all +bandwidth_limit rules for a specific policy, a consumer of the object can just +access corresponding attribute via: + +* policy.bandwidth_limit_rules + +Implementation is done in a way that will allow adding a new rule list field +with little or no modifications in the policy object itself. This is achieved +by smart introspection of existing available rule object definitions and +automatic definition of those fields on the policy class. + +Note that synthetic fields are lazily loaded, meaning there is no hit into +the database if the field is not inspected by consumers. + +For QosRule objects, an extendable approach was taken to allow easy +addition of objects for new rule types. To accomodate this, all the methods +that access the database were implemented in a base class called QosRule that +is then inherited into type-specific rule implementations that, ideally, only +define additional fields and some other minor things. + +Note that the QosRule base class is not registered with oslo.versionedobjects +registry, because it's not expected that 'generic' rules should be +instantiated (and to enforce just that, the base rule class is marked as ABC). + +QoS objects rely on some primitive database API functions that are added in: + +* neutron.db.api +* neutron.db.qos.api + + +Callback changes +---------------- + +TODO(QoS): We're changing strategy here to not rely on AFTER_READ callbacks, + and foster discussion about how to do decouple core resource + extension in the community. So, update next phrase when that + happens. + +To extend ports and networks with qos_policy_id field, AFTER_READ callback +event is introduced. + +Note: a better mechanism is being built by @armax to make resource extensions +more explicit and under control. We will migrate to that better mechanism as +soon as it's available. + + +RPC communication +----------------- +Details on RPC communication implemented in reference backend driver are +discussed in `a separate page `_. + +One thing that should be mentioned here explicitly is that RPC callback +endpoints communicate using real versioned objects (as defined by serialization +for oslo.versionedobjects library), not vague json dictionaries. Meaning, +oslo.versionedobjects are on the wire and not just used internally inside a +component. + +There is expectation that after RPC callbacks are introduced in Neutron, we +will be able to migrate propagation from server to agents for other resources +(f.e. security groups) to the new mechanism. This will need to wait until those +resources get proper NeutronObject implementations. + + +Agent side design +================= + +To facilitate code reusability between agents and agent extensions without +patching the agent code itself, agent extensions were introduced. They can be +especially interesting to third parties that don't want to maintain their code +in Neutron tree. + +Extensions are meant to receive basic events like port update or delete, and do +whatever they need with it. + +* neutron.agent.l2.agent_extension: + extension interface definition. + +* neutron.agent.l2.agent_extensions_manager: + manager that allows to register multiple extensions, and pass events down to + all enabled extensions. + +* neutron.agent.l2.extensions.qos_agent: + defines QoSAgentExtension that is also pluggable using QoSAgentDriver + implementations that are specific to agent backends being used. + +* neutron.agent.l2.l2_agent: + provides the API entry point for process_{network,subnet,port}_extension, + and holds an agent extension manager inside. + TODO(QoS): clarify what this is for, I don't follow a bit. + + +ML2 +--- + +TODO(QoS): there is work ongoing that will need to be reflected here. + + +Agent backends +-------------- + +TODO(QoS): this section needs rework. + +Open vSwitch + +* neutron.plugins.ml2.drivers.openvswitch.agent.extension_drivers.qos_driver + This module implements the QoSAgentDriver interface used by the + QosAgentExtension. + +* neutron.agent.common.ovs_lib +* neutron.agent.ovsdb.api +* neutron.agent.ovsdb.impl_idl +* neutron.agent.ovsdb.impl_vsctl +* neutron.agent.ovsdb.native.commands + +SR-IOV + + +Configuration +============= + TODO(QoS) + + +Testing strategy +================ + +Neutron objects +--------------- + +Base unit test classes to validate neutron objects were implemented in a way +that allows code reuse when introducing a new object type. + +There are two test classes that are utilized for that: + +* BaseObjectIfaceTestCase: class to validate basic object operations (mostly + CRUD) with database layer isolated. +* BaseDbObjectTestCase: class to validate the same operations with models in + place and database layer unmocked. + +Every new object implemented on top of one of those classes is expected to +either inherit existing test cases as is, or reimplement it, if it makes sense +in terms of how those objects are implemented. Specific test classes can +obviously extend the set of test cases as they see needed (f.e. you need to +define new test cases for those additional methods that you may add to your +object implementations on top of base semantics common to all neutron objects). +