Set lock_path correctly.
[openstack-build/neutron-build.git] / doc / source / devref / quality_of_service.rst
1 ..
2       Licensed under the Apache License, Version 2.0 (the "License"); you may
3       not use this file except in compliance with the License. You may obtain
4       a copy of the License at
5
6           http://www.apache.org/licenses/LICENSE-2.0
7
8       Unless required by applicable law or agreed to in writing, software
9       distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10       WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11       License for the specific language governing permissions and limitations
12       under the License.
13
14
15       Convention for heading levels in Neutron devref:
16       =======  Heading 0 (reserved for the title in a document)
17       -------  Heading 1
18       ~~~~~~~  Heading 2
19       +++++++  Heading 3
20       '''''''  Heading 4
21       (Avoid deeper levels because they do not render well.)
22
23
24 Quality of Service
25 ==================
26
27 Quality of Service advanced service is designed as a service plugin. The
28 service is decoupled from the rest of Neutron code on multiple levels (see
29 below).
30
31 QoS extends core resources (ports, networks) without using mixins inherited
32 from plugins but through an ml2 extension driver.
33
34 Details about the DB models, API extension, and use cases can be found here: `qos spec <http://specs.openstack.org/openstack/neutron-specs/specs/liberty/qos-api-extension.html>`_
35 .
36
37 Service side design
38 -------------------
39
40 * neutron.extensions.qos:
41   base extension + API controller definition. Note that rules are subattributes
42   of policies and hence embedded into their URIs.
43
44 * neutron.services.qos.qos_plugin:
45   QoSPlugin, service plugin that implements 'qos' extension, receiving and
46   handling API calls to create/modify policies and rules.
47
48 * neutron.services.qos.notification_drivers.manager:
49   the manager that passes object notifications down to every enabled
50   notification driver.
51
52 * neutron.services.qos.notification_drivers.qos_base:
53   the interface class for pluggable notification drivers that are used to
54   update backends about new {create, update, delete} events on any rule or
55   policy change.
56
57 * neutron.services.qos.notification_drivers.message_queue:
58   MQ-based reference notification driver which updates agents via messaging
59   bus, using `RPC callbacks <rpc_callbacks.html>`_.
60
61 * neutron.core_extensions.base:
62   Contains an interface class to implement core resource (port/network)
63   extensions. Core resource extensions are then easily integrated into
64   interested plugins. We may need to  have a core resource extension manager
65   that would utilize those extensions, to avoid plugin modifications for every
66   new core resource extension.
67
68 * neutron.core_extensions.qos:
69   Contains QoS core resource extension that conforms to the interface described
70   above.
71
72 * neutron.plugins.ml2.extensions.qos:
73   Contains ml2 extension driver that handles core resource updates by reusing
74   the core_extensions.qos module mentioned above. In the future, we would like
75   to see a plugin-agnostic core resource extension manager that could be
76   integrated into other plugins with ease.
77
78
79 Supported QoS rule types
80 ~~~~~~~~~~~~~~~~~~~~~~~~
81
82 Any plugin or Ml2 mechanism driver can claim support for some QoS rule types by
83 providing a plugin/driver class property called 'supported_qos_rule_types' that
84 should return a list of strings that correspond to QoS rule types (for the list
85 of all rule types, see: neutron.services.qos.qos_consts.VALID_RULE_TYPES).
86
87 In the most simple case, the property can be represented by a simple Python
88 list defined on the class.
89
90 For Ml2 plugin, the list of supported QoS rule types is defined as a common
91 subset of rules supported by all active mechanism drivers.
92
93 Note: the list of supported rule types reported by core plugin is not enforced
94 when accessing QoS rule resources. This is mostly because then we would not be
95 able to create any rules while at least one ml2 driver in gate lacks support
96 for QoS (at the moment of writing, linuxbridge is such a driver).
97
98
99 Database models
100 ~~~~~~~~~~~~~~~
101
102 QoS design defines the following two conceptual resources to apply QoS rules
103 for a port or a network:
104
105 * QoS policy
106 * QoS rule (type specific)
107
108 Each QoS policy contains zero or more QoS rules. A policy is then applied to a
109 network or a port, making all rules of the policy applied to the corresponding
110 Neutron resource.
111
112 When applied through a network association, policy rules could apply or not
113 to neutron internal ports (like router, dhcp, load balancer, etc..). The QosRule
114 base object provides a default should_apply_to_port method which could be
115 overridden. In the future we may want to have a flag in QoSNetworkPolicyBinding
116 or QosRule to enforce such type of application (for example when limiting all
117 the ingress of routers devices on an external network automatically).
118
119 From database point of view, following objects are defined in schema:
120
121 * QosPolicy: directly maps to the conceptual policy resource.
122 * QosNetworkPolicyBinding, QosPortPolicyBinding: defines attachment between a
123   Neutron resource and a QoS policy.
124 * QosBandwidthLimitRule: defines the only rule type available at the moment.
125
126
127 All database models are defined under:
128
129 * neutron.db.qos.models
130
131
132 QoS versioned objects
133 ~~~~~~~~~~~~~~~~~~~~~
134
135 There is a long history of passing database dictionaries directly into business
136 logic of Neutron. This path is not the one we wanted to take for QoS effort, so
137 we've also introduced a new objects middleware to encapsulate the database logic
138 from the rest of the Neutron code that works with QoS resources. For this, we've
139 adopted oslo.versionedobjects library and introduced a new NeutronObject class
140 that is a base for all other objects that will belong to the middle layer.
141 There is an expectation that Neutron will evolve into using objects for all
142 resources it handles, though that part was obviously out of scope for the QoS
143 effort.
144
145 Every NeutronObject supports the following operations:
146
147 * get_by_id: returns specific object that is represented by the id passed as an
148   argument.
149 * get_objects: returns all objects of the type, potentially with a filter
150   applied.
151 * create/update/delete: usual persistence operations.
152
153 Base object class is defined in:
154
155 * neutron.objects.base
156
157 For QoS, new neutron objects were implemented:
158
159 * QosPolicy: directly maps to the conceptual policy resource, as defined above.
160 * QosBandwidthLimitRule: class that represents the only rule type supported by
161   initial QoS design.
162
163 Those are defined in:
164
165 * neutron.objects.qos.policy
166 * neutron.objects.qos.rule
167
168 For QosPolicy neutron object, the following public methods were implemented:
169
170 * get_network_policy/get_port_policy: returns a policy object that is attached
171   to the corresponding Neutron resource.
172 * attach_network/attach_port: attach a policy to the corresponding Neutron
173   resource.
174 * detach_network/detach_port: detach a policy from the corresponding Neutron
175   resource.
176
177 In addition to the fields that belong to QoS policy database object itself,
178 synthetic fields were added to the object that represent lists of rules that
179 belong to the policy. To get a list of all rules for a specific policy, a
180 consumer of the object can just access the corresponding attribute via:
181
182 * policy.rules
183
184 Implementation is done in a way that will allow adding a new rule list field
185 with little or no modifications in the policy object itself. This is achieved
186 by smart introspection of existing available rule object definitions and
187 automatic definition of those fields on the policy class.
188
189 Note that rules are loaded in a non lazy way, meaning they are all fetched from
190 the database on policy fetch.
191
192 For Qos<type>Rule objects, an extendable approach was taken to allow easy
193 addition of objects for new rule types. To accommodate this, fields common to
194 all types are put into a base class called QosRule that is then inherited into
195 type-specific rule implementations that, ideally, only define additional fields
196 and some other minor things.
197
198 Note that the QosRule base class is not registered with oslo.versionedobjects
199 registry, because it's not expected that 'generic' rules should be
200 instantiated (and to suggest just that, the base rule class is marked as ABC).
201
202 QoS objects rely on some primitive database API functions that are added in:
203
204 * neutron.db.api: those can be reused to fetch other models that do not have
205   corresponding versioned objects yet, if needed.
206 * neutron.db.qos.api: contains database functions that are specific to QoS
207   models.
208
209
210 RPC communication
211 ~~~~~~~~~~~~~~~~~
212
213 Details on RPC communication implemented in reference backend driver are
214 discussed in `a separate page <rpc_callbacks.html>`_.
215
216 One thing that should be mentioned here explicitly is that RPC callback
217 endpoints communicate using real versioned objects (as defined by serialization
218 for oslo.versionedobjects library), not vague json dictionaries. Meaning,
219 oslo.versionedobjects are on the wire and not just used internally inside a
220 component.
221
222 One more thing to note is that though RPC interface relies on versioned
223 objects, it does not yet rely on versioning features the oslo.versionedobjects
224 library provides. This is because Liberty is the first release where we start
225 using the RPC interface, so we have no way to get different versions in a
226 cluster. That said, the versioning strategy for QoS is thought through and
227 described in `the separate page <rpc_callbacks.html>`_.
228
229 There is expectation that after RPC callbacks are introduced in Neutron, we
230 will be able to migrate propagation from server to agents for other resources
231 (f.e. security groups) to the new mechanism. This will need to wait until those
232 resources get proper NeutronObject implementations.
233
234 The flow of updates is as follows:
235
236 * if a port that is bound to the agent is attached to a QoS policy, then ML2
237   plugin detects the change by relying on ML2 QoS extension driver, and
238   notifies the agent about a port change. The agent proceeds with the
239   notification by calling to get_device_details() and getting the new port dict
240   that contains a new qos_policy_id. Each device details dict is passed into l2
241   agent extension manager that passes it down into every enabled extension,
242   including QoS. QoS extension sees that there is a new unknown QoS policy for
243   a port, so it uses ResourcesPullRpcApi to fetch the current state of the
244   policy (with all the rules included) from the server. After that, the QoS
245   extension applies the rules by calling into QoS driver that corresponds to
246   the agent.
247 * on existing QoS policy update (it includes any policy or its rules change),
248   server pushes the new policy object state through ResourcesPushRpcApi
249   interface. The interface fans out the serialized (dehydrated) object to any
250   agent that is listening for QoS policy updates. If an agent have seen the
251   policy before (it is attached to one of the ports it maintains), then it goes
252   with applying the updates to the port. Otherwise, the agent silently ignores
253   the update.
254
255
256 Agent side design
257 -----------------
258
259 To ease code reusability between agents and to avoid the need to patch an agent
260 for each new core resource extension, pluggable L2 agent extensions were
261 introduced. They can be especially interesting to third parties that don't want
262 to maintain their code in Neutron tree.
263
264 Extensions are meant to receive handle_port events, and do whatever they need
265 with them.
266
267 * neutron.agent.l2.agent_extension:
268   This module defines an abstract extension interface.
269
270 * neutron.agent.l2.extensions.manager:
271   This module contains a manager that allows to register multiple extensions,
272   and passes handle_port events down to all enabled extensions.
273
274 * neutron.agent.l2.extensions.qos
275   defines QoS L2 agent extension. It receives handle_port and delete_port
276   events and passes them down into QoS agent backend driver (see below). The
277   file also defines the QosAgentDriver interface. Note: each backend implements
278   its own driver. The driver handles low level interaction with the underlying
279   networking technology, while the QoS extension handles operations that are
280   common to all agents.
281
282
283 Agent backends
284 ~~~~~~~~~~~~~~
285
286 At the moment, QoS is supported by Open vSwitch and SR-IOV ml2 drivers.
287
288 Each agent backend defines a QoS driver that implements the QosAgentDriver
289 interface:
290
291 * Open vSwitch (QosOVSAgentDriver);
292 * SR-IOV (QosSRIOVAgentDriver).
293
294
295 Open vSwitch
296 ++++++++++++
297
298 Open vSwitch implementation relies on the new ovs_lib OVSBridge functions:
299
300 * get_egress_bw_limit_for_port
301 * create_egress_bw_limit_for_port
302 * delete_egress_bw_limit_for_port
303
304 An egress bandwidth limit is effectively configured on the port by setting
305 the port Interface parameters ingress_policing_rate and
306 ingress_policing_burst.
307
308 That approach is less flexible than linux-htb, Queues and OvS QoS profiles,
309 which we may explore in the future, but which will need to be used in
310 combination with openflow rules.
311
312 SR-IOV
313 ++++++
314
315 SR-IOV bandwidth limit implementation relies on the new pci_lib function:
316
317 * set_vf_max_rate
318
319 As the name of the function suggests, the limit is applied on a Virtual
320 Function (VF).
321
322 ip link interface has the following limitation for bandwidth limit: it uses
323 Mbps as units of bandwidth measurement, not kbps, and does not support float
324 numbers. So in case the limit is set to something less than 1000 kbps, it's set
325 to 1 Mbps only. If the limit is set to something that does not divide to 1000
326 kbps chunks, then the effective limit is rounded to the nearest integer Mbps
327 value.
328
329
330 Configuration
331 -------------
332
333 To enable the service, the following steps should be followed:
334
335 On server side:
336
337 * enable qos service in service_plugins;
338 * set the needed notification_drivers in [qos] section (message_queue is the default);
339 * for ml2, add 'qos' to extension_drivers in [ml2] section.
340
341 On agent side (OVS):
342
343 * add 'qos' to extensions in [agent] section.
344
345
346 Testing strategy
347 ----------------
348
349 All the code added or extended as part of the effort got reasonable unit test
350 coverage.
351
352
353 Neutron objects
354 ~~~~~~~~~~~~~~~
355
356 Base unit test classes to validate neutron objects were implemented in a way
357 that allows code reuse when introducing a new object type.
358
359 There are two test classes that are utilized for that:
360
361 * BaseObjectIfaceTestCase: class to validate basic object operations (mostly
362   CRUD) with database layer isolated.
363 * BaseDbObjectTestCase: class to validate the same operations with models in
364   place and database layer unmocked.
365
366 Every new object implemented on top of one of those classes is expected to
367 either inherit existing test cases as is, or reimplement it, if it makes sense
368 in terms of how those objects are implemented. Specific test classes can
369 obviously extend the set of test cases as they see needed (f.e. you need to
370 define new test cases for those additional methods that you may add to your
371 object implementations on top of base semantics common to all neutron objects).
372
373
374 Functional tests
375 ~~~~~~~~~~~~~~~~
376
377 Additions to ovs_lib to set bandwidth limits on ports are covered in:
378
379 * neutron.tests.functional.agent.test_ovs_lib
380
381
382 API tests
383 ~~~~~~~~~
384
385 API tests for basic CRUD operations for ports, networks, policies, and rules were added in:
386
387 * neutron.tests.api.test_qos