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:
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:
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-