12 February 2021

SDN / NFV

How to configure VNFs using a Virtual Network Function Descriptor

12 minutes reading

How to configure VNFs using a Virtual Network Function Descriptor

Virtual Network Functions (VNFs) are software network elements like routers, firewalls or load balancers that replace networking hardware. Network services are performed by dedicated software that runs on Virtual Machines (VMs) managed by Virtual Infrastructure Managers (VIMs). In this blog post, we describe how to configure VNFs using a Virtual Network Function Descriptor (VNFD) together with a Network Service Descriptor (NSD) and the Open Source MANO platform. Additionally, we will present an initial configuration of a new Virtual Machine (VM) instance using cloud-init.

Why do we need VNFDs and NSDs?

VNFD is a component of a VNF package and has been designed by ETSI (the European Telecommunications Standards Institute). It makes it possible to standardize the operations of VNFs in a cloud environment. VNFD is used to describe the process of deploying, configuring and managing a VNF instance. 

The VNFD defines all VNF properties including:

  • Required resources (e.g. CPU, memory, interfaces, etc.)
  • VNF image(s)
  • External connectivity and connectivity between virtualized instances
  • Lifecycle management and configuration
  • Supported VNF-specific parameters
  • Software metadata

A Network Service Descriptor (NSD) allows you to standardize the network operation of VNFs. It is used to define how VNFs are interconnected to provide the service.

Open Source MANO—an overview

To illustrate how to create a VNFD template, we have chosen ETSI Open Source MANO (OSM) for NFV Management and Orchestration. In our example, OpenStack is used as a Virtual Infrastructure Manager (VIM). The following figure illustrates how OSM interacts with VIMs and VNFs:

The OSM interaction with VIMs and VNFs

Fig 1. The OSM interaction with VIMs and VNFs (source)

A VNFD example—what we want to achieve

The final result of our VNFD template is to create one VM instance in the OpenStack environment with the following requirements:

  • CPUs: 2

  • RAM size: 2 GB

  • Hard disk size: 20 GB

  • Network interfaces: 2: 1 for inside the network, 1 for outside

  • System version: Ubuntu 16.04 (cloud image)

  • Cloud-init configuration to do the following:

    • Set password for default user (Ubuntu)
    • Force the above password to be changed after first login to the instance
    • Disable ssh password authentication
    • Add your public key for ssh authentication for default user (Ubuntu)
    • Update apt database on the first boot
    • Download and install nginx

How to configure an environment to build a VNF using Open Source MANO

Our OpenStack environment is configured with the following:

  • Ubuntu 16.04 (cloud image version) imported as a QCOW2 disk, named “ubuntu16.04”

  • Three networks:

    • public with public subnet and floating IP pool assigned
    • outside with subnet (10.10.0.0/24) will use floating IP
    • inside with subnet (10.11.0.0/24)
  • Virtual router with default route through public for the outside and inside networks (network topology below)

  • Default security group with additional rules to allow TCP ports: SSH (22), HTTP (80) and HTTPS (443)


The OpenStack network topology looks like this:

The OpenStack network topology

Fig 2. The OpenStack network topology

In OSM (the latest version 9), we define a VIM account for the OpenStack environment with option use_floating_ip set to true, so it ensures floating IP assignment for management network (in our case, an outside network).

How to create a VNFD template

To build a VNFD we need to define a package that contains a vnfd.yaml file and optional cloud-init.cfg file which will run post-deployment scripts to initialize the system. Our example focuses on quick VNF deployment using OSM and uses cloud-init to configure the system faster. In other cases, this feature may not be required. 

We define the following folder structure:

cloud_init_example_VNF/

  • vnfd.yaml

  • cloud_init/

    • cloud_init.cfg

Inside vnfd.yaml we define options to successfully deploy an instance in OpenStack. Please note that all values used to build vnfd.yaml are taken from the ETSI schema.

The first step is to define characteristics of VNF like a unique ID and version of the VNF descriptor.

vnfd:
  id: cloud_init_example_VNF    #identifier of the vnfd, must be globally unique value
  #below options are not mandatory, but they are helpful to distinguish VNF when using OSM GUI/CLI
  description: Example VNF with cloud-init feature
  product-name: cloud_init_example_VNF
  provider: CodiLime
  version: '1.0'

In the next step, we define the DF and VDU profiles. DF (Deployment Flavour) defines specific requirements for capacity and performance.

VDU (Virtual Deployment Units) represents an individual VM inside the VNF. In our case, we are deploying a single VNF with only one VDU but it is possible to define a single VNF that will contain multiple VDUs to provide a more advanced service. Please also note that VDU and its ID will be defined in the last step.

  df:
  - id: default_df #unique identifier of the deployment flavour
    instantiation-level:
    - id: default_instantiation_level #unique identifier of the a level within df
      vdu-level:
      - number-of-instances: 1
        vdu-id: cloud_init_example_VNF_VM #unique name of the VDU
    vdu-profile:
    - id: cloud_init_example_VNF_VM
      min-number-of-instances: 1

The next step is to configure ext-cpd (external-connection point descriptor), which specifies the characteristics of one or more external connection points (CP) exposed by VNF. 

We configure two interfaces in our environment. It is also possible to describe internal CP, which enables connectivity between the VDU and internal VL (Virtual Link) or external CP. VLs are used to establish connections between VNF components.

  ext-cpd:
  - id: vnf_cp0_ext #identifier of the CPD
    int-cpd:
      cpd: eth0 #unique ID of int-cpd that will be described later under VDU 
      vdu-id: cloud_init_example_VNF_VM #unique name of the VDU
  - id: vnf_cp1_int
    int-cpd:
      cpd: eth1
      vdu-id: cloud_init_example_VNF_VM
 
  mgmt-cp: vnf_cp0_ext #management interface 

In our example, we use Ubuntu 16.04 and this is what we specify in VNFD. The image must exist in the VIM.

  sw-image-desc:
  - id: ubuntu16.04
    image: ubuntu16.04
    name: ubuntu16.04

We also need to define resources for the VM, memory, CPU and storage in this case.

  virtual-compute-desc:
  - id: cloud_init_example_VNF_VM_compute #unique compute ID used when creating VDU
    virtual-cpu:
      num-virtual-cpu: 2
    virtual-memory:
      size: 2.0 #2 GB RAM
  virtual-storage-desc:
  - id: cloud_init_example_VNF_VM_storage #unique storage ID referenced when creating VDU
    size-of-storage: 20 #20 GB of disk size

In the last step, we define the VDU. It contains a type of virtual interface, cloud init file name and reference to the resources we created earlier.

  vdu:
  - cloud-init-file: cloud_init.cfg #reference to the cloud init file with startup configuration for the system
    description: cloud_init_example_VNF_VM
    id: cloud_init_example_VNF_VM #unique value for the VDU
    int-cpd: 
    - id: eth0 #unique ID of the interface
      virtual-network-interface-requirement:
      - name: eth0 #interface name of the interface to be presented on VIM (Openstack)
        virtual-interface:
          type: PARAVIRT #type of the interface, PARAVIRT is default value, more types are that are supported are mentioned in the schema
    - id: eth1
      virtual-network-interface-requirement:
      - name: eth1
        virtual-interface:
          type: PARAVIRT
    #when creating VDU, we reference image, storage and compute IDs created earlier
    name: cloud_init_example_VNF_VM
    sw-image-desc: ubuntu16.04
    virtual-compute-desc: cloud_init_example_VNF_VM_compute
    virtual-storage-desc: cloud_init_example_VNF_VM_storage

In the next stage, we prepare our cloud_init.cfg file. You can find documentation about the cloud-init feature and how to configure it here.

In our example, after creating and initializing the VM instance, we configure a password for the Ubuntu user that must be changed after the first login. In addition, we disable SSH password authentication allowing SSH access to the VM only with authorized public keys. Next, we get apt updates and install the nginx packages.

#cloud-config
password: ubuntuUserPassword
chpasswd:
  expire: true
ssh_pwauth: false
ssh_authorized_keys:
  - put your public rsa key for ssh connection (for default user ubuntu)
package_update: true
packages:
  - nginx

At the beginning of this paragraph, we have defined the folder structure. This structure is required by OSM to read the VNFD template. We need to pack our directory to tar.gz. We will be using OSM CLI to accomplish that.

$ tar -czvf cloud_init_example_VNF.tar.gz cloud_init_example_VNF/
cloud_init_example_VNF/
cloud_init_example_VNF/cloud_init_example_VNF.yaml
cloud_init_example_VNF/cloud_init/
cloud_init_example_VNF/cloud_init/cloud_init.cfg

$ osm vnfd-create cloud_init_example_VNF.tar.gz 
4a78707d-9bec-4856-8e88-cb5d2c163729

Verify that our VNFD is imported correctly (some outputs have been omitted for brevity).

$ osm vnfd-list
+------------------------+--------------------------------------+-----------+
| nfpkg name             | id                                   | desc type |
+------------------------+--------------------------------------+-----------+
| cloud_init_example_VNF | 4a78707d-9bec-4856-8e88-cb5d2c163729 | sol006    |
+------------------------+--------------------------------------+-----------+

$ osm vnfd-