=== Service Function Scheduling Algorithms ==== Overview When creating the Rendered Service Path, the origin SFC controller chose the first available service function from a list of service function names. This may result in many issues such as overloaded service functions and a longer service path as SFC has no means to understand the status of service functions and network topology. The service function selection framework supports at least four algorithms (Random, Round Robin, Load Balancing and Shortest Path) to select the most appropriate service function when instantiating the Rendered Service Path. In addition, it is an extensible framework that allows 3rd party selection algorithm to be plugged in. ==== Architecture The following figure illustrates the service function selection framework and algorithms. .SF Selection Architecture image::sfc/sf-selection-arch.png["SF Selection Architecture",width=500] A user has three different ways to select one service function selection algorithm: . Integrated RESTCONF Calls. OpenStack and/or other administration system could provide plugins to call the APIs to select one scheduling algorithm. . Command line tools. Command line tools such as curl or browser plugins such as POSTMAN (for Google Chrome) and RESTClient (for Mozilla Firefox) could select schedule algorithm by making RESTCONF calls. . SFC-UI. Now the SFC-UI provides an option for choosing a selection algorithm when creating a Rendered Service Path. The RESTCONF northbound SFC API provides GUI/RESTCONF interactions for choosing the service function selection algorithm. MD-SAL data store provides all supported service function selection algorithms, and provides APIs to enable one of the provided service function selection algorithms. Once a service function selection algorithm is enabled, the service function selection algorithm will work when creating a Rendered Service Path. ==== Select SFs with Scheduler Administrator could use both the following ways to select one of the selection algorithm when creating a Rendered Service Path. * Command line tools. Command line tools includes Linux commands curl or even browser plugins such as POSTMAN(for Google Chrome) or RESTClient(for Mozilla Firefox). In this case, the following JSON content is needed at the moment: Service_function_schudule_type.json + { "service-function-scheduler-types": { "service-function-scheduler-type": [ { "name": "random", "type": "service-function-scheduler-type:random", "enabled": false }, { "name": "roundrobin", "type": "service-function-scheduler-type:round-robin", "enabled": true }, { "name": "loadbalance", "type": "service-function-scheduler-type:load-balance", "enabled": false }, { "name": "shortestpath", "type": "service-function-scheduler-type:shortest-path", "enabled": false } ] } } + If using the Linux curl command, it could be: + curl -i -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data '$${Service_function_schudule_type.json}' -X PUT --user admin:admin http://localhost:8181/restconf/config/service-function-scheduler-type:service-function-scheduler-types/ + Here is also a snapshot for using the RESTClient plugin: .Mozilla Firefox RESTClient image::sfc/RESTClient-snapshot.png["Mozilla Firefox RESTClient",width=500] * SFC-UI.SFC-UI provides a drop down menu for service function selection algorithm. Here is a snapshot for the user interaction from SFC-UI when creating a Rendered Service Path. .Karaf Web UI image::sfc/karaf-webui-select-a-type.png["Karaf Web UI",width=500] NOTE: Some service function selection algorithms in the drop list are not implemented yet. Only the first three algorithms are committed at the moment. ===== Random Select Service Function from the name list randomly. ====== Overview The Random algorithm is used to select one Service Function from the name list which it gets from the Service Function Type randomly. ====== Prerequisites * Service Function information are stored in datastore. * Either no algorithm or the Random algorithm is selected. ====== Target Environment The Random algorithm will work either no algorithm type is selected or the Random algorithm is selected. ====== Instructions Once the plugins are installed into Karaf successfully, a user can use his favorite method to select the Random scheduling algorithm type. There are no special instructions for using the Random algorithm. ===== Round Robin Select Service Function from the name list in Round Robin manner. ====== Overview The Round Robin algorithm is used to select one Service Function from the name list which it gets from the Service Function Type in a Round Robin manner, this will balance workloads to all Service Functions. However, this method cannot help all Service Functions load the same workload because it's flow-based Round Robin. ====== Prerequisites * Service Function information are stored in datastore. * Round Robin algorithm is selected ====== Target Environment The Round Robin algorithm will work one the Round Robin algorithm is selected. ====== Instructions Once the plugins are installed into Karaf successfully, a user can use his favorite method to select the Round Robin scheduling algorithm type. There are no special instructions for using the Round Robin algorithm. ===== Load Balance Algorithm Select appropriate Service Function by actual CPU utilization. ====== Overview The Load Balance Algorithm is used to select appropriate Service Function by actual CPU utilization of service functions. The CPU utilization of service function obtained from monitoring information reported via NETCONF. ====== Prerequisites * CPU-utilization for Service Function. * NETCONF server. * NETCONF client. * Each VM has a NETCONF server and it could work with NETCONF client well. ====== Instructions Set up VMs as Service Functions. enable NETCONF server in VMs. Ensure that you specify them separately. For example: .1 *Setting up the VM* .. Set up 4 VMs include 2 SFs' type are Firewall, Others are Napt44. Name them as firewall-1, firewall-2, napt44-1, napt44-2 as Service Function. The four VMs can run either the same server or different servers. .. Install NETCONF server on every VM and enable it. More information on NETCONF can be found on the OpenDaylight wiki here: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:Netconf:Manual_netopeer_installation .. Get Monitoring data from NETCONF server. These monitoring data should be get from the NETCONF server which is running in VMs. The following static XML data is an example: static XML data like this: ---- 2 5 10 2000 200 100 1 10.0.0.1 00:1e:67:a2:5f:f4 20 2 10.0.0.2 01:1e:67:a2:5f:f6 10 true 10 15 12 17 8 20 25 30 1 20 2 30 ---- .2 *Start SFC* .. Unzip SFC release tarball. .. Run SFC: ${SFC}/bin/karaf. More information on Service Function Chaining can be found on the OpenDaylight SFC's wiki page: https://wiki.opendaylight.org/view/Service_Function_Chaining:Main .3 *Verify the Load Balance Algorithm* .. Deploy the SFC2 (firewall-abstract2=>napt44-abstract2) and click button to Create Rendered Service Path in SFC UI (http://localhost:8181/sfc/index.html). .. Verify the Rendered Service Path to ensure the CPU utilization of the selected hop is the minimum one among all the service functions with same type. The correct RSP is firewall-1=>napt44-2 ===== Shortest Path Algorithm Select appropriate Service Function by Dijkstra's algorithm. Dijkstra's algorithm is an algorithm for finding the shortest paths between nodes in a graph. ====== Overview The Shortest Path Algorithm is used to select appropriate Service Function by actual topology. ====== Prerequisites * Depolyed topology (include SFFs, SFs and their links). * Dijkstra's algorithm. More information on Dijkstra's algorithm can be found on the wiki here: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm ====== Instructions .1 *Start SFC* .. Unzip SFC release tarball. .. Run SFC: ${SFC}/bin/karaf. .. Depoly SFFs and SFs. import the service-function-forwarders.json and service-functions.json in UI (http://localhost:8181/sfc/index.html#/sfc/config) service-function-forwarders.json: ---- { "service-function-forwarders": { "service-function-forwarder": [ { "name": "SFF-br1", "service-node": "OVSDB-test01", "rest-uri": "http://localhost:5001", "sff-data-plane-locator": [ { "name": "eth0", "service-function-forwarder-ovs:ovs-bridge": { "uuid": "4c3778e4-840d-47f4-b45e-0988e514d26c", "bridge-name": "br-tun" }, "data-plane-locator": { "port": 5000, "ip": "192.168.1.1", "transport": "service-locator:vxlan-gpe" } } ], "service-function-dictionary": [ { "sff-sf-data-plane-locator": { "port": 10001, "ip": "10.3.1.103" }, "name": "napt44-1", "type": "service-function-type:napt44" }, { "sff-sf-data-plane-locator": { "port": 10003, "ip": "10.3.1.102" }, "name": "firewall-1", "type": "service-function-type:firewall" } ], "connected-sff-dictionary": [ { "name": "SFF-br3" } ] }, { "name": "SFF-br2", "service-node": "OVSDB-test01", "rest-uri": "http://localhost:5002", "sff-data-plane-locator": [ { "name": "eth0", "service-function-forwarder-ovs:ovs-bridge": { "uuid": "fd4d849f-5140-48cd-bc60-6ad1f5fc0a1", "bridge-name": "br-tun" }, "data-plane-locator": { "port": 5000, "ip": "192.168.1.2", "transport": "service-locator:vxlan-gpe" } } ], "service-function-dictionary": [ { "sff-sf-data-plane-locator": { "port": 10002, "ip": "10.3.1.103" }, "name": "napt44-2", "type": "service-function-type:napt44" }, { "sff-sf-data-plane-locator": { "port": 10004, "ip": "10.3.1.101" }, "name": "firewall-2", "type": "service-function-type:firewall" } ], "connected-sff-dictionary": [ { "name": "SFF-br3" } ] }, { "name": "SFF-br3", "service-node": "OVSDB-test01", "rest-uri": "http://localhost:5005", "sff-data-plane-locator": [ { "name": "eth0", "service-function-forwarder-ovs:ovs-bridge": { "uuid": "fd4d849f-5140-48cd-bc60-6ad1f5fc0a4", "bridge-name": "br-tun" }, "data-plane-locator": { "port": 5000, "ip": "192.168.1.2", "transport": "service-locator:vxlan-gpe" } } ], "service-function-dictionary": [ { "sff-sf-data-plane-locator": { "port": 10005, "ip": "10.3.1.104" }, "name": "test-server", "type": "service-function-type:dpi" }, { "sff-sf-data-plane-locator": { "port": 10006, "ip": "10.3.1.102" }, "name": "test-client", "type": "service-function-type:dpi" } ], "connected-sff-dictionary": [ { "name": "SFF-br1" }, { "name": "SFF-br2" } ] } ] } } ---- service-functions.json: ---- { "service-functions": { "service-function": [ { "rest-uri": "http://localhost:10001", "ip-mgmt-address": "10.3.1.103", "sf-data-plane-locator": [ { "name": "preferred", "port": 10001, "ip": "10.3.1.103", "service-function-forwarder": "SFF-br1" } ], "name": "napt44-1", "type": "service-function-type:napt44", "nsh-aware": true }, { "rest-uri": "http://localhost:10002", "ip-mgmt-address": "10.3.1.103", "sf-data-plane-locator": [ { "name": "master", "port": 10002, "ip": "10.3.1.103", "service-function-forwarder": "SFF-br2" } ], "name": "napt44-2", "type": "service-function-type:napt44", "nsh-aware": true }, { "rest-uri": "http://localhost:10003", "ip-mgmt-address": "10.3.1.103", "sf-data-plane-locator": [ { "name": "1", "port": 10003, "ip": "10.3.1.102", "service-function-forwarder": "SFF-br1" } ], "name": "firewall-1", "type": "service-function-type:firewall", "nsh-aware": true }, { "rest-uri": "http://localhost:10004", "ip-mgmt-address": "10.3.1.103", "sf-data-plane-locator": [ { "name": "2", "port": 10004, "ip": "10.3.1.101", "service-function-forwarder": "SFF-br2" } ], "name": "firewall-2", "type": "service-function-type:firewall", "nsh-aware": true }, { "rest-uri": "http://localhost:10005", "ip-mgmt-address": "10.3.1.103", "sf-data-plane-locator": [ { "name": "3", "port": 10005, "ip": "10.3.1.104", "service-function-forwarder": "SFF-br3" } ], "name": "test-server", "type": "service-function-type:dpi", "nsh-aware": true }, { "rest-uri": "http://localhost:10006", "ip-mgmt-address": "10.3.1.103", "sf-data-plane-locator": [ { "name": "4", "port": 10006, "ip": "10.3.1.102", "service-function-forwarder": "SFF-br3" } ], "name": "test-client", "type": "service-function-type:dpi", "nsh-aware": true } ] } } ---- The depolyed topology like this: ---- +----+ +----+ +----+ |sff1|+----------|sff3|---------+|sff2| +----+ +----+ +----+ | | +--------------+ +--------------+ | | | | +----------+ +--------+ +----------+ +--------+ |firewall-1| |napt44-1| |firewall-2| |napt44-2| +----------+ +--------+ +----------+ +--------+ ---- .2 *Verify the Shortest Path Algorithm* ** Deploy the SFC2(firewall-abstract2=>napt44-abstract2), select "Shortest Path" as schedule type and click button to Create Rendered Service Path in SFC UI (http://localhost:8181/sfc/index.html). .select schedule type image::sfc/sf-schedule-type.png["select schedule type",width=500] ** Verify the Rendered Service Path to ensure the selected hops are linked in one SFF. The correct RSP is firewall-1=>napt44-1 or firewall-2=>napt44-2. The first SF type is Firewall in Service Function Chain. So the algorithm will select first Hop randomly among all the SFs type is Firewall. Assume the first selected SF is firewall-2. All the path from firewall-1 to SF which type is Napt44 are list: * Path1: firewall-2 -> sff2 -> napt44-2 * Path2: firewall-2 -> sff2 -> sff3 -> sff1 -> napt44-1 The shortest path is Path1, so the selected next hop is napt44-2. .rendered service path image::sfc/sf-rendered-service-path.png["rendered service path",width=500]