summaryrefslogtreecommitdiffstats
path: root/docs/release/scenarios/os-nosdn-performance-ha/os-nosdn-performance-ha.rst
blob: 1319f4272e32e0b8e724ba314d8b6ad9b16f59a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
.. (c) <optionally add copywriters name>

This document provides scenario level details for Euphrates 1.0 of
deployment with no SDN controller and performance options enabled.

.. contents::
   :depth: 3
   :local:

============
Introduction
============

This scenario is used primarily to demonstrate the performance settings and
capabilities in Apex. This scenario will  deploy a Newton OpenStack
deployment without any NFV features or SDN controller enabled.

Scenario components and composition
===================================

This scenario is composed of common OpenStack services enabled by default,
including Nova, Neutron, Glance, Cinder, Keystone, Horizon.  Optionally and
by default, Tacker and Congress services are also enabled.  Ceph is used as
the backend storage to Cinder on all deployed nodes.

All services are in HA, meaning that there are multiple cloned instances of
each service, and they are balanced by HA Proxy using a Virtual IP Address
per service.

The main purpose of this scenario is to serve as an example to show how to
set optional performance settings in an Apex deploy settings file.

Scenario usage overview
=======================

The performance options listed in os-nosdn-performance-ha.yaml give an example
of the different options a user can set in any deploy settings file.  Some
of these performance options are actually required for other scenarios which
rely on DPDK.  Options under the nova section like 'libvirtpin' allow a
user to choose which core to pin nova instances to on the overcloud compute
node.  Options under 'kernel' allow a user to set kernel specific arguments
at boot, which include options like hugepages, isolcpus, enabling iommu, etc.


Limitations, Issues and Workarounds
===================================

* `APEX-389 <https://jira.opnfv.org/browse/APEX-389>`_:
   Compute kernel parameters are applied to all nodes

References
==========

For more information on the OPNFV Euphrates release, please visit
http://www.opnfv.org/euphrates
ww.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """VSwitch controller for Physical to Physical deployment """ import logging import netaddr from core.vswitch_controller import IVswitchController from conf import settings _FLOW_TEMPLATE = { 'idle_timeout': '0' } _PROTO_TCP = 6 _PROTO_UDP = 17 class VswitchControllerP2P(IVswitchController): """VSwitch controller for P2P deployment scenario. Attributes: _vswitch_class: The vSwitch class to be used. _vswitch: The vSwitch object controlled by this controller _deployment_scenario: A string describing the scenario to set-up in the constructor. """ def __init__(self, vswitch_class, traffic): """Initializes up the prerequisites for the P2P deployment scenario. :vswitch_class: the vSwitch class to be used. """ self._logger = logging.getLogger(__name__) self._vswitch_class = vswitch_class self._vswitch = vswitch_class() self._deployment_scenario = "P2P" self._logger.debug('Creation using ' + str(self._vswitch_class)) self._traffic = traffic.copy() def setup(self): """Sets up the switch for p2p. """ self._logger.debug('Setup using ' + str(self._vswitch_class)) try: self._vswitch.start() bridge = settings.getValue('VSWITCH_BRIDGE_NAME') self._vswitch.add_switch(bridge) (_, _) = self._vswitch.add_phy_port(bridge) (_, _) = self._vswitch.add_phy_port(bridge) self._vswitch.del_flow(bridge) # table#0 - flows designed to force 5 & 13 tuple matches go here flow = {'table':'0', 'priority':'1', 'actions': ['goto_table:1']} self._vswitch.add_flow(bridge, flow) # table#1 - flows to route packets between ports goes here. The # chosen port is communicated to subsequent tables by setting the # metadata value to the egress port number # configure flows according to the TC definition flow_template = _FLOW_TEMPLATE.copy() if self._traffic['flow_type'] == 'IP': flow_template.update({'dl_type':'0x0800', 'nw_src':self._traffic['l3']['srcip'], 'nw_dst':self._traffic['l3']['dstip']}) flow = flow_template.copy() flow.update({'table':'1', 'priority':'1', 'in_port':'1', 'actions': ['write_actions(output:2)', 'write_metadata:0x2', 'goto_table:2']}) self.process_flow_template(bridge, flow) flow = flow_template.copy() flow.update({'table':'1', 'priority':'1', 'in_port':'2', 'actions': ['write_actions(output:1)', 'write_metadata:0x1', 'goto_table:2']}) self.process_flow_template(bridge, flow) # Frame modification table. Frame modification flow rules are # isolated in this table so that they can be turned on or off # without affecting the routing or tuple-matching flow rules. flow = {'table':'2', 'priority':'1', 'actions': ['goto_table:3']} self._vswitch.add_flow(bridge, flow) # Egress table # (TODO) Billy O'Mahony - the drop action here actually required in # order to egress the packet. This is the subject of a thread on # ovs-discuss 2015-06-30. flow = {'table':'3', 'priority':'1', 'actions': ['drop']} self._vswitch.add_flow(bridge, flow) except: self._vswitch.stop() raise def stop(self): """Tears down the switch created in setup(). """ self._logger.debug('Stop using ' + str(self._vswitch_class)) self._vswitch.stop() def __enter__(self): self.setup() def __exit__(self, type_, value, traceback): self.stop() def get_vswitch(self): """See IVswitchController for description """ return self._vswitch def get_ports_info(self): """See IVswitchController for description """ self._logger.debug('get_ports_info using ' + str(self._vswitch_class)) return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME')) def dump_vswitch_flows(self): """See IVswitchController for description """ self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME')) def process_flow_template(self, bridge, flow_template): """Method adds flows into the vswitch based on given flow template and configuration of multistream feature. """ if ('pre_installed_flows' in self._traffic and self._traffic['pre_installed_flows'].lower() == 'yes' and 'multistream' in self._traffic and self._traffic['multistream'] > 0 and 'stream_type' in self._traffic): # multistream feature is enabled and flows should be inserted into OVS # so generate flows based on template and multistream configuration if self._traffic['stream_type'] == 'L2': # iterate through destimation MAC address dst_mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value for i in range(self._traffic['multistream']): tmp_mac = netaddr.EUI(dst_mac_value + i) tmp_mac.dialect = netaddr.mac_unix_expanded flow_template.update({'dl_dst':tmp_mac}) # optimize flow insertion by usage of cache self._vswitch.add_flow(bridge, flow_template, cache='on') elif self._traffic['stream_type'] == 'L3': # iterate through destimation IP address dst_ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value for i in range(self._traffic['multistream']): tmp_ip = netaddr.IPAddress(dst_ip_value + i) flow_template.update({'dl_type':'0x0800', 'nw_dst':tmp_ip}) # optimize flow insertion by usage of cache self._vswitch.add_flow(bridge, flow_template, cache='on') elif self._traffic['stream_type'] == 'L4': # read transport protocol from configuration and iterate through its destination port proto = _PROTO_TCP if self._traffic['l3']['proto'].lower() == 'tcp' else _PROTO_UDP for i in range(self._traffic['multistream']): flow_template.update({'dl_type':'0x0800', 'nw_proto':proto, 'tp_dst':i}) # optimize flow insertion by usage of cache self._vswitch.add_flow(bridge, flow_template, cache='on') else: self._logger.error('Stream type is set to uknown value %s', self._traffic['stream_type']) # insert cached flows into the OVS self._vswitch.add_flow(bridge, [], cache='flush') else: self._vswitch.add_flow(bridge, flow_template)