Getting Started

Let’s move K-SOT!

In this tutorial, you will build K-SOT and check its operation by following the steps below.

  1. Create a local Kubernetes cluster
  2. Create a Github repository for verification
  3. Install K-SOT and configure various files
  4. Start up the device emulator
  5. Deploy K-SOT
  6. Operation check

Advance preparation

  1. Install golang (v1.21.0+)). You will need it to write the device configuration derivation logic.
  2. Install docker (v20.10.24+). Required to run KIND.
  3. Install kind (v0.12.0+). Used to build local Kubernetes clusters.
  4. Install kubectl (v1.25.4+). Used to execute commands against a Kubernetes cluster.

1. Create a local Kubernetes cluster

Run the following command to start a local Kubernetes cluster.

kind create cluster --name ksot-started

When execution is complete, confirm that the Kubernetes cluster has been successfully created by running the following command.

kubectl cluster-info

If you see output similar to the following, the local cluster is working properly.

Kubernetes control plane is running at https://127.0.0.1:52096
CoreDNS is running at https://127.0.0.1:52096/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

2. Create a Github repository for verification

In order for K-SOT to manage the configuration of network devices using Github, a GitHub repository must be created. Using the K-SOT Example repository as a template, these repositories can be easily created.

Create a GitHub repository by doing the following

  1. Click on the Use this template button in the K-SOT Example repository.

  2. Enter a repository name and click the Create repository from template button. You can choose to make the repository public or private as you like. In this case, set the repository owner to the user’s account and the repository name to ksot-example.

3. Install K-SOT and configure various files

Clone the K-SOT repository and initialize submodules.

Repository clone

git clone https://github.com/nttcom/ksot.git

Submodule initialization

git submodule update --init --recursive

Configuration of env file

Place the following env file in the K-SOT repository cloned above.

/.env

KIND_NAME=ksot-started
GITHUB_REPO_URL=https://{GithubUserName}:{GithubUserToken}@github.com/{GithubUserName}/ksot-example
GITHUB_USER_NAME={GithubUserName}
GITHUB_USER_MAIL={GithubMailAddress}

/github-server/config/overlays/test/.env

GITHUB_REPO_URL=https://{GithubUserName}:{GithubUserToken}@github.com/{GithubUserName}/ksot-example

Configuration of the YANG

YANG settings for equipment

Acquire all YANG in YANG Folder of ODTN-emulator, which is the device to be managed in this article. Create a folder (name: cassini) under ```nb-server/pkg/tf/yang/devices`` and place the YANG files you just acquired.

Setting up YANG for services

Create a folder (name: transceivers) under nb-server/pkg/tf/yang/devices and place the yang files with the following contents in it.

module transceivers {
    namespace "tf-ksot/transceivers";
	prefix ts;
	grouping transceivers-top {
		list transceivers {
			key "name";
			leaf name {
				type string;
			}
			leaf-list  up {
				type string;
			}
			leaf-list down {
				type string;
			}
		}
	}
    uses transceivers-top;
}

Configuration of equipment configuration derivation package

nb-server/pkg/tf/transceivers.gowith the following contents.

package tf

import (
	"encoding/json"
	"fmt"

	"github.com/nttcom-ic/ksot/nb-server/pkg/model/pathmap"
)

type Transceiver struct {
	Name string   `json:"name"`
	Nos  string   `json:"nos"`
	Up   []string `json:"up"`
	Down []string `json:"down"`
}
type Transceivers map[string][]Transceiver

func TfTransceivers(ts interface{}) (map[string]pathmap.PathMapInterface, error) {
	fmt.Println("hello")
	mapByte, err := json.Marshal(ts)
	if err != nil {
		return nil, err
	}
	var transceivers Transceivers
	if err := json.Unmarshal(mapByte, &transceivers); err != nil {
		fmt.Println(err)
		return nil, err
	}
	results := make(map[string]pathmap.PathMapInterface)
	fmt.Println("tflogic: ", transceivers)
	for _, devices := range transceivers {
		for _, device := range devices {
			result, err := pathmap.NewPathMap(map[string]interface{}{})
			if err != nil {
				return nil, err
			}
			for _, v := range device.Up {
				path := fmt.Sprintf("/openconfig-platform:components/component[name=%v]/openconfig-platform-transceiver:transceiver/config/enabled", v)
				err = result.SetValue(path, true, map[string]string{})
				if err != nil {
					return nil, err
				}
			}
			for _, v := range device.Down {
				path := fmt.Sprintf("/openconfig-platform:components/component[name=%v]/openconfig-platform-transceiver:transceiver/config/enabled", v)
				err = result.SetValue(path, false, map[string]string{})
				if err != nil {
					return nil, err
				}
			}
			results[device.Name] = result
		}
	}
	fmt.Println("check: ", results)
	return results, nil
}

nb-server/pkg/tf/tf.go to the following content.

package tf

import (
	"github.com/nttcom-ic/ksot/nb-server/pkg/model"
)

var TfLogic = model.NewPathMapLogic()

func init() {
	// User needs to create a function to generate a pathmap and add it to the MAP.
	// Example.
	// TfLogic["serviceName"] = serviceName
	TfLogic["transceivers"] = TfTransceivers
}

4. Start up the device emulator

Add an env file with emulator connection information. /sb-server/config/overlays/test/.env

cassini=root

Launch OTDN-emulator with the following command.

docker pull onosproject/oc-cassini:0.21
docker run -it -d --name odtn-emulator_openconfig_cassini_1 -p 11002:830 onosproject/oc-cassini:0.21

Make sure the container is up and running as follows.

% docker ps
CONTAINER ID  IMAGE             COMMAND          CREATED    STATUS    PORTS                   NAMES
52da5c9f1c79  onosproject/oc-cassini:0.21  "sh /root/script/pus…"  4 hours ago  Up 4 hours  22/tcp, 8080/tcp, 0.0.0.0:11002->830/tcp  odtn-emulator_openconfig_cassini_1

Create sb-server/connect.json in the K-SOT repository to add connection information from the controller to OTDN-emulator and save it with the following contents.

{
    "cassini": {
        "ip": "host.docker.internal",
        "port": 11002,
        "username": "root",
        "hostKeyVerify": false,
        "if": "netconf"
    }
}

5. Deploy K-SOT

Execute the following command in the root of the K-SOT repository.

make getting-started

After execution, check the pods running with ```kubectl get pod`` and you will see the following three pods have been created.

NAMESPACE            NAME                                                 READY   STATUS    RESTARTS   AGE
default              ksot-github-deployment-766b6ff499-72zkr              1/1     Running   0          24s
default              ksot-nb-deployment-967757888-dqzw7                   1/1     Running   0          24s
default              ksot-sb-deployment-6d89c6f85c-zksl5                  1/1     Running   0          24s
...

6. Operation check

Implementing port-forwarding

First, port-forwarding should be performed on the k8s service that will be the Northbound.

kubectl port-forward svc/ksot-nb-service 8080:8080

Get equipment information.

Perform PUT: http://localhost:8080/sync/devices to reflect the current device configuration in the Github repository. It is successful if the following files are created in Devices/cassini of the Github repository for verification.

  • actual.json: configuration obtained from the actual device
  • ref.json: parameters set from each service (default value is empty JSON)
  • set.json: settings submitted by the controller (initial values are the same as those obtained from the actual device)

Service Creation

POST: http://localhost:8080/services is executed with the following JSON as the body, the service specified in the body is created, and the device settings are changed.

{
    "transceivers": {
        "transceivers:transceivers":  [
            {
                "name": "cassini",
                "up": [],
                "down": [
                    "oe1",
                    "oe2",
                ]
            }
        ]
    }
}

Make sure the following files are created in Services/transceivers in the verification Github repository.

  • input.json: the value of the submitted service
  • output.json: xpath and corresponding values for the device whose configuration you have changed

Get equipment information (after service creation)

Perform PUT: http://localhost:8080/sync/devices to reflect the current device configuration in the Github repository. The Devices/cassini/actual.json in the Github repository for verification is updated as follows, and the transceivers in the specified location of OTDN-emulator are down. The Devices/cassini/actual.json is updated as follows.

{
...
				"name": "oe1",
				"config": {
					"name": "oe1"
				},
				"state": {
					"type": "openconfig-platform-types:TRANSCEIVER",
					"empty": false
				},
				"openconfig-platform-transceiver:transceiver": {
					"config": {
						- "enabled": true,
						+  "enabled": false,
						"form-factor-preconf": "openconfig-transport-types:CFP2_ACO"
					}
				}
...
				"name": "oe2",
				"config": {
					"name": "oe2"
				},
				"state": {
					"type": "openconfig-platform-types:TRANSCEIVER",
					"empty": false
				},
				"openconfig-platform-transceiver:transceiver": {
					"config": {
						- "enabled": true,
						+  "enabled": false
						"form-factor-preconf": "openconfig-transport-types:CFP2_ACO"
					}
				}
...
}

Updating services

Execute PUT: http://localhost:8080/services with the following JSON as the body, update the service specified in the body, and change the device settings. In this case, we will update the oe1 transceiver.

{
    "transceivers": {
        "transceivers:transceivers":  [
            {
                "name": "cassini",
                "up": [
					"oe1",
				],
                "down": [
                    "oe2",
                ]
            }
        ]
    }
}

Get equipment information (after service update)

Perform PUT: http://localhost:8080/sync/devices to reflect the current equipment configuration in the Github repository. The Devices/cassini/actual.json in the Github repository for verification is updated as follows, and the transceivers in the specified location of OTDN-emulator are updated. The Devices/cassini/actual.json is updated as follows

{
...
				"name": "oe1",
				"config": {
					"name": "oe1"
				},
				"state": {
					"type": "openconfig-platform-types:TRANSCEIVER",
					"empty": false
				},
				"openconfig-platform-transceiver:transceiver": {
					"config": {
						+  "enabled": true,
						- "enabled": false,
						"form-factor-preconf": "openconfig-transport-types:CFP2_ACO"
					}
				}
...
}

delete service.

DELETE: http://localhost:8080/services?name=transceivers. Delete the service with the name specified in the query parameters and change the configuration of the device. Check the Services/transceivers folder in the verification Github repository as it will disappear.

Get device information (after deleting the service)

Perform PUT: http://localhost:8080/sync/devices to reflect the current equipment configuration in the Github repository. The Devices/cassini/actual.json in the Github repository for verification will be updated as follows, and you will see that the configuration points that were submitted from the service will disappear.

{
...
				"name": "oe1",
				"config": {
					"name": "oe1"
				},
				"state": {
					"type": "openconfig-platform-types:TRANSCEIVER",
					"empty": false
				},
				"openconfig-platform-transceiver:transceiver": {
					"config": {
						- "enabled": true,
						"form-factor-preconf": "openconfig-transport-types:CFP2_ACO"
					}
				}
...
				"name": "oe2",
				"config": {
					"name": "oe2"
				},
				"state": {
					"type": "openconfig-platform-types:TRANSCEIVER",
					"empty": false
				},
				"openconfig-platform-transceiver:transceiver": {
					"config": {
						-  "enabled": false
						"form-factor-preconf": "openconfig-transport-types:CFP2_ACO"
					}
				}
...
}

External tools used in this section


Last modified July 24, 2024: Replacement to v1.0.0 (#27) (c442526)