Ribbon provides a set of Heat template examples to assist you in developing a template to instantiate the type of deployment that fits your needs and environment. Beyond the required SBC parameters, these reference templates provide examples of deployment variations that are common in SBC deployments. The use cases described in this section are not specific to the SBC, they are based on standard OpenStack concepts and parameters. Refer to OpenStack documentation, or documentation from your OpenStack provider, for more information on implementing SR-IOV, VLANs, or Cinder volumes in your deployment.  

Enabling SR-IOV Interfaces

The heatRgNoDhcp.yaml reference template includes the statements required to enable single root input/output virtualization (SR-IOV) in the section where virtual NICs (ports) are defined. In the reference template, these lines are commented out for all of the interfaces and therefore does not enable SR-IOV until you edit it. Use the following procedure to modify the sample template file to enable SR-IOV support for one or more interfaces.  

To enable SR-IOV on an interface:

  1. Locate the section in the template that define the characteristics of a specified interface by executing a search for the string: <interfaceName> EDIT 
    Where <interfaceName> is one of the following: pkt0 | pkt1 | mgt0 | ha0
    This search takes you to the section of the template file where the interface definition is specified.
  2. For the specified interface, uncomment the following line by removing the leading # character: binding:vnic_type: direct
  3. Repeat the previous steps for other interfaces on which you want to enable SR-IOV.

Implementing VLANs on virt-io Interfaces

The heatRgActiveVlanProviderNetworkNoDhcpTemplate.yaml reference template includes statements to set up virtual local area networks (VLANs) on the provider (pkt) networks. 

To support using VLANs on virt-io vNICs in OpenStack you must create three types of neutron ports:

  • Parent port - a single port that is attached to the instance
  • Sub-ports - one or more VLAN ports that reference the MAC address of the parent port
  • Trunk-ports - a single port that bridges a parent port with its sub-ports

The following excerpts from the template show statements to define the resources required for the deployment, including the ports. In the final two lines of the excerpt, notice that the statements attaching the pkt0 and pkt1 ports use get_attr rather than get_resource because the parent ports were created earlier in the resources section..

resources:

  parent_port_pkt0:
    type: OS::Neutron::Port
    properties:
      network: { get_param : private_network_pkt0 }

  sub_port_pkt0:
    type: OS::Neutron::Port
    properties:
      network: { get_param : provider_vlan_network_pkt0 }
      mac_address: { get_attr: [parent_port_pkt0, mac_address] }
      fixed_ips:
        - ip_address: { get_param: pkt0VlanIPAddress }
      security_groups:
        - { get_param: security_group }

  trunk_port_pkt0:
    type: OS::Neutron::Trunk
    properties:
      port: { get_resource: parent_port_pkt0 }
      sub_ports:
        - { port: { get_resource: sub_port_pkt0 },
          segmentation_type: vlan,
          segmentation_id: {get_param: pkt0VlanId } }

  parent_port_pkt1:
    type: OS::Neutron::Port
    properties:
      network: { get_param : private_network_pkt1 }

  sub_port_pkt1:
    type: OS::Neutron::Port
    properties:
      network: { get_param : provider_vlan_network_pkt1 }
      mac_address: { get_attr: [parent_port_pkt1, mac_address] }
      fixed_ips:
        - ip_address: { get_param: pkt1VlanIPAddress }
      security_groups:
        - { get_param: security_group }

  trunk_port_pkt1:
    type: OS::Neutron::Trunk
    properties:
      port: { get_resource: parent_port_pkt1 }
      sub_ports:
        - { port: { get_resource: sub_port_pkt1 },
          segmentation_type: vlan,
          segmentation_id: {get_param: pkt1VlanId } }


  # Create active vSBC instance
  vSBC_ACTIVE:
    type: OS::Nova::Server
    properties:
      name: { get_param: "OS::stack_name" }
      image: { get_param: image }
      flavor: { get_param: flavor }
      config_drive: True
      availability_zone: {get_param: availability_zone}

      # Attach previously created network ports to the instance networks:
        - port: { get_resource: mgt0_port1 }
        - port: { get_resource: ha0_port1 }
        - { port: { get_attr: [trunk_port_pkt0, port_id] } }
        - { port: { get_attr: [trunk_port_pkt1, port_id] } }

Later in the template the VLAN IDs and IP addresses are provided as input in the metadata section, as shown in the following excerpt.

        IF_PKT0_V01:
            str_replace:
                template: |
                  { "VlanId": "$vlan_id",
                    "Port": "$port_name",
                    "DHCP": "False",
                    "GW$ip_version": "$gateway_ip", 
                    "IP$ip_version": "$ip_address"
                  }
                params:
                  $port_name:  "Pkt0"
                  $vlan_id:    { get_param: pkt0VlanID }
                  $ip_version: { get_param: pkt0VlanIpVersion }
                  $ip_address: { list_join: ['/', [ { get_param: pkt0VlanIPAddress }, { get_param: pkt0VlanSubnetPrefix}]] }
                  $gateway_ip: { get_param: pkt0VlanGateway }

        IF_PKT1_V01:
            str_replace:
                template: |
                  { "VlanId": "$vlan_id",
                    "Port": "$port_name",
                    "DHCP": "False",
                    "GW$ip_version": "$gateway_ip", 
                    "IP$ip_version": "$ip_address"
                  }
                params:
                  $port_name:  "Pkt1"
                  $vlan_id:    { get_param: pkt1VlanID }
                  $ip_version: { get_param: pkt1VlanIpVersion }
                  $ip_address: { list_join: ['/', [ { get_param: pkt1VlanIPAddress }, { get_param: pkt1VlanSubnetPrefix}]] }
                  $gateway_ip: { get_param: pkt1VlanGateway }

For more information on using VLANs in Openstack, refer to the following:

https://specs.openstack.org/openstack/neutron-specs/specs/newton/vlan-aware-vms.html

https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/13/html/networking_guide/sec-trunk-vlan

Using a Cinder Volume for Persistent Storage of Log and CDR Files

Note

Ribbon recommends creating a separate volume for logs and attaching it to the instance during launch. Without a separate volume, the SBC writes logs to the root volume (/), which is lost if you rebuild or recreate the instance.


The heatRgActiveTemplate.yaml reference template includes example statements for adding a Cinder volume for CDR and logging. When deployed in an OpenStack environment, the SBC writes CDR and logging data to locations on the ephemeral SBC instance. However, if the instance is deleted the data is lost. However you can create and attach an external OpenStack Cinder volume to use as a persistent storage location. If necessary, this volume can be re-attached to a different instance for analysis of the stored log or CDR data. When deploying the SBC instance you must include statements in the Heat template that attach the Cinder volume and specify the mount point. In the reference template file, the lines related to creating and attaching Cinder volumes are commented out and the template must be edited to create them.

To implement a Cinder volume as a persistent storage location: 

  1. Using the OpenStack CLI or Horizon GUI, create a Cinder volume for each SBC instance and record the UUID for the volume. Refer to OpenStack documentation for information on creating a Cinder volume. When creating the volume, consider the following formula to determine a minimum size to accommodate CDRs, and then add approximately 60GB for log and core files:
     (40% of peak CPS) * (records/call) * 86400 * (days) * 2K
    where:
    CPS is calls per second
    records per call is typically one or two, and depends on your deployment
    86400 is the number of seconds per day
    days is the number of days of CDR records to store
  2. Modify the Heat template to specify the UUID of the volume, attach the volume, and specify the mount point during launch. An example template segment is shown below. 

    volume_attachment:
        type: OS::Cinder::VolumeAttachment
        properties:
          volume_id: { get_param: cinder_volume_id }
          instance_uuid: { get_resource: vSBC_ACTIVE }
  3. Include the boot command in the template user-data to indicate that the attached volume should be mounted and the logs should be stored on the volume. An example template segment is shown below. 

    user_data:
     bootcmd:
         -   /opt/sonus/bin/mountVolume.sh -v "$cinderVolumeIdForLogs"

 

Note

You also have the option to create and attach a Cinder volume that boots the SBC instance. When you attach a Cinder boot volume, the Cinder volume holds the root partition which includes the path used for storing logs and CDRs. Therefore, rather than using ephemeral storage, the boot volume holds the operating system, application, CDR, and log files. Refer to the heatRgActiveTemplate.yaml file for examples of the template statements required to attach a Cinder volume for boot.

Note that if you choose to implement both a Cinder log volume and a Cinder boot volume, the log and CDR files are stored on the log volume while the application and operating system files are stored on the boot volume.