新人が DevStack 上で TOSCA を使用して VNF を VM としてデプロイする話

# 目次

[1. はじめに](#はじめに)
[2. 環境](#環境)
[3. インストール手順](#インストール手順)
[4. 発生したエラー](#発生したエラー)
[5. まとめ](#まとめ)

# 参考 URL

- [ETSI NFV-SOL VNF Deployment as VM with TOSCA](https://docs.openstack.org/tacker/latest/user/etsi_vnf_deployment_as_vm_with_tosca.html)
- [VIM Management](https://docs.openstack.org/tacker/latest/cli/cli-legacy-vim.html)
- [VNF Package Management](https://docs.openstack.org/tacker/latest/cli/cli-etsi-vnfpkgm.html)
- [VNF パッケージ管理](https://docs.openstack.org/tacker/latest/cli/cli-etsi-vnfpkgm.html)
- [VNF ライフサイクル管理](https://docs.openstack.org/tacker/latest/cli/cli-etsi-vnflcm.html)

# はじめに

こんにちは。新入社員として約 3 か月目の新人です。

この記事では NFV という言葉すら知らなかった新人が [Install via Devstack]( https://docs.openstack.org/tacker/latest/install/devstack.html) を参考にして DevStack 環境をインストールし、VIM として OpenStack と Kubernetes を登録するまでの手順と発生したエラーを複数の章に分けて記載していきます。

- 第 1 章: [新人が DevStack 上で Tacker を動かそうとする話](https://qiita.com/yoshi_1010/items/c1db52099b5897e049d0)

[Install via Devstack]( https://docs.openstack.org/tacker/latest/install/devstack.html) を実際に試します。

- 第 2 章: この記事です。

[ETSI NFV-SOL VNF Deployment as VM with TOSCA](https://docs.openstack.org/tacker/latest/user/etsi_vnf_deployment_as_vm_with_tosca.html) を実際に試します。

- 第 3 章: 続く。。。

今回のインストールで自分が調べた用語は以下にまとめました。

## TOSCA (Topology and Orchestration Specification for Cloud Applications)

クラウドアプリケーション向けトポロジ・オーケストレーションに関する仕様のことです。

実現内容
- クラウド上のアプリケーション・サービスの可搬性の向上
- 既存アプリケーションのクラウドへのより容易な移行
- アプリケーション構成の柔軟な変更
- 複数のクラウドを跨いだアプリケーションの構築と管理

# 環境

ESXi 上に Devstack がインストール済みの状態です。
詳しくは [新人が DevStack 上で Tacker を動かそうとする話](https://qiita.com/yoshi_1010/items/c1db52099b5897e049d0) をお読みください。

# インストール手順

この手順は本環境でインストール完了までうまくいったものです。
手順完成までに発生したエラーは [4. 発生したエラー](#発生したエラー) にまとめます。

## Neutron に QoS の許可追加

Neutron の設定ファイルである neutron.conf ファイルに書かれている service_plugins の設定が下記のような状態となるように編集します。

```
$ vim /etc/neutron/neutron.conf

service_plugins = ovn-router,networking_sfc.services.flowclassifier.plugin.FlowClassifierPlugin,networking_sfc.services.sfc.plugin.SfcPlugin,neutron.services.qos.qos_plugin.QoSPlugin,qos
```

## VIM Management

VNF を作成するためには操作先である VIM を前もって作成している必要があります。
そのため、初期状態では VIM を先に作成します。

### 実行ユーザとディレクトリ

stack ユーザで実行します。

```
sudo -u stack -i
```

自分で作成したファイルを配置する work ディレクトリを作成します。

```
mkdir ~/work/
```

work ディレクトリに移動します。

```
cd ~/work
```

### openstack コマンド利用準備

openstack 関係のコマンドを利用する際にはパスワードなどの環境変数を設定する必要があります。

利用できるファイルが 2 種類あるため、どちらかを実施します。

#### devstack リポジトリのものを利用

Devstack をインストールする際に利用した stack.sh のあるディレクトリと同じディレクトリにある `openrc` というファイルを利用します。

これから先、ログイン後に openstack コマンドを利用する場合は同様に読み込む必要があります。

`admin admin` を付与することで毎回パスワード入力が求められなくなります。

```
source openrc admin admin
```

#### Horizon から取得

環境変数を設定するためのファイルは Horizon から取得します。

1. Horizon ダッシュボードにログイン
2. 右上のユーザー名クリック
3. OpenStack RC ファイルをダウンロード

ダウンロードしたファイルを作業用ディレクトリに配置しておきます。
ファイルの中身は基本的に Horizon から取得したまま利用できますが、必要があれば各個人の環境に合わせてください。


```
cat << _EOF_ > ~/work/admin-openrc.sh
#!/usr/bin/env bash
# To use an OpenStack cloud you need to authenticate against the Identity
# service named keystone, which returns a **Token** and **Service Catalog**.
# The catalog contains the endpoints for all services the user/tenant has
# access to - such as Compute, Image Service, Identity, Object Storage, Block
# Storage, and Networking (code-named nova, glance, keystone, swift,
# cinder, and neutron).
#
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
# OpenStack API is version 3. For example, your cloud provider may implement
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
# only for the Identity API served through keystone.
export OS_AUTH_URL=http://10.100.2.220/identity
# With the addition of Keystone we have standardized on the term **project**
# as the entity that owns the resources.
export OS_PROJECT_ID=7ef18f601b824be897934f6793130760
export OS_PROJECT_NAME="admin"
export OS_USER_DOMAIN_NAME="Default"
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
export OS_PROJECT_DOMAIN_ID="default"
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
# unset v2.0 items in case set
unset OS_TENANT_ID
unset OS_TENANT_NAME
# In addition to the owning entity (tenant), OpenStack stores the entity
# performing the action as the **user**.
export OS_USERNAME="admin"
# With Keystone you pass the keystone password.
echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
read -sr OS_PASSWORD_INPUT
export OS_PASSWORD=$OS_PASSWORD_INPUT
# If your configuration has multiple regions, we set that information here.
# OS_REGION_NAME is optional and only valid in certain environments.
export OS_REGION_NAME="RegionOne"
# Don't leave a blank variable, unset it if it was empty
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
_EOF_
```

これから先、ログイン後に openstack コマンドを利用する場合は `admin-openrc.sh` を読み込む必要があります。

```
source admin-openrc.sh admin admin
```

#### OpenStack VIM の登録

OpenStackVIM 用の vim_config.yaml ファイルを準備します。

```
cat << _EOF_ > ~/work/vim_config.yaml
auth_url: 'http://localhost/identity'
username: 'nfv_user'
password: 'devstack'
project_name: 'nfv'
project_domain_name: 'Default'
user_domain_name: 'Default'
cert_verify: 'False'
_EOF_
```

デフォルトの OpenStackVIM を登録します。

```
openstack vim register --config-file ./vim_config.yaml --is-default \
--description 'vim for nfv_user in nfv' \
openstack-nfv-vim
```

作成した結果下記のように表示されます。

```
+----------------+-------------------------------------------------+
| Field          | Value                                           |
+----------------+-------------------------------------------------+
| auth_cred      | {                                               |
|                |     "username": "nfv_user",                     |
|                |     "user_domain_name": "Default",              |
|                |     "cert_verify": "False",                     |
|                |     "project_id": null,                         |
|                |     "project_name": "nfv",                      |
|                |     "project_domain_name": "Default",           |
|                |     "auth_url": "http://localhost/identity/v3", |
|                |     "key_type": "barbican_key",                 |
|                |     "secret_uuid": "***",                       |
|                |     "password": "***"                           |
|                | }                                               |
| auth_url       | http://localhost/identity/v3                    |
| created_at     | 2022-07-07 04:51:43.625966                      |
| description    | vim for nfv_user in nfv                         |
| id             | 03179d72-ac26-4ac2-bdd4-43cc2672dea8            |
| is_default     | True                                            |
| name           | openstack-nfv-vim                               |
| placement_attr | {                                               |
|                |     "regions": [                                |
|                |         "RegionOne"                             |
|                |     ]                                           |
|                | }                                               |
| project_id     | 7ef18f601b824be897934f6793130760                |
| status         | PENDING                                         |
| type           | openstack                                       |
| updated_at     | None                                            |
| vim_project    | {                                               |
|                |     "name": "nfv",                              |
|                |     "project_domain_name": "Default"            |
|                | }                                               |
+----------------+-------------------------------------------------+
```

確認します。

```
$ openstack vim list
+--------------------------------------+-------------------+----------------------------------+-----------+------------+-----------+
| ID                                   | Name              | Tenant_id                        | Type      | Is Default | Status    |
+--------------------------------------+-------------------+----------------------------------+-----------+------------+-----------+
| 03179d72-ac26-4ac2-bdd4-43cc2672dea8 | openstack-nfv-vim | 7ef18f601b824be897934f6793130760 | openstack | True       | REACHABLE |
+--------------------------------------+-------------------+----------------------------------+-----------+------------+-----------+
```

## VM としての VNF の展開

VNF を VM としてデプロイするには、次の手順を実行する必要があります。 
CLI コマンドの詳細については、[VNF パッケージ管理](https://docs.openstack.org/tacker/latest/cli/cli-etsi-vnfpkgm.html) および[VNF ライフサイクル管理](https://docs.openstack.org/tacker/latest/cli/cli-etsi-vnflcm.html)で説明しています。

### VNF パッケージの作成

VNF パッケージを作成します。

```
$ openstack vnf package create
+-------------------+-------------------------------------------------------------------------------------------------+
| Field             | Value
+-------------------+-------------------------------------------------------------------------------------------------+
| ID                | 229c9fea-aaac-4741-a893-644ed5d27e37
| Links             | {
|                   |     "self": {
|                   |         "href": "/vnfpkgm/v1/vnf_packages/229c9fea-aaac-4741-a893-644ed5d27e37"                 |
|                   |     },
|                   |     "packageContent": {
|                   |         "href": "/vnfpkgm/v1/vnf_packages/229c9fea-aaac-4741-a893-644ed5d27e37/package_content" |
|                   |     }
|                   | }
| Onboarding State  | CREATED
| Operational State | DISABLED
| Usage State       | NOT_IN_USE
| User Defined Data | {}
+-------------------+-------------------------------------------------------------------------------------------------+
```

確認します。
229c9fea-aaac-4741-a893-644ed5d27e37 は VNF パッケージ ID です。

```
$ openstack vnf package show 229c9fea-aaac-4741-a893-644ed5d27e37 \
-c 'Onboarding State' -c 'Operational State' -c 'Usage State'

+-------------------+------------+
| Field             | Value      |
+-------------------+------------+
| Onboarding State  | CREATED    |
| Operational State | DISABLED   |
| Usage State       | NOT_IN_USE |
+-------------------+------------+
```

### VNF パッケージのアップロード

アップロードするファイルは tacker リポジトリから取得します。
取得には zip コマンドが必要であるため、zip コマンドがインストールされていない場合はインストールします。

```
sudo apt install zip
```

tacker リポジトリは stack.sh 実行時に自動的にクローンされています。

```
cd ../tacker/samples/vnf_packages/
zip -r sample_vnf_pkg.zip TOSCA-Metadata Definitions Files
cd -
mv ../tacker/samples/vnf_packages/sample_vnf_pkg.zip .
```

VNF パッケージをアップロードします。
229c9fea-aaac-4741-a893-644ed5d27e37 は前項の [VNF パッケージの作成] で作成された VNF パッケージ ID です。
忘れてしまった場合は `openstack vnf package list` コマンドで確認できます。

```
$ openstack vnf package upload --path sample_vnf_pkg.zip 229c9fea-aaac-4741-a893-644ed5d27e37
Upload request for VNF package 229c9fea-aaac-4741-a893-644ed5d27e37 has been accepted.
```

確認します。

```
$ openstack vnf package show 229c9fea-aaac-4741-a893-644ed5d27e37 \
-c 'Onboarding State' -c 'Operational State' -c 'Usage State' -c 'VNFD ID'

+-------------------+--------------------------------------+
| Field             | Value                                |
+-------------------+--------------------------------------+
| Onboarding State  | ONBOARDED                            |
| Operational State | ENABLED                              |
| Usage State       | NOT_IN_USE                           |
| VNFD ID           | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 |
+-------------------+--------------------------------------+
```

### VNF Identifier の作成

VNF インスタンスを作成します。
b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 は VNFD ID です。

```
$ openstack vnflcm create b1bb0ce7-ebca-4fa7-95ed-4840d70a1177

+-----------------------------+------------------------------------------------------------------------------------------------------------------+
| Field                       | Value                                                                                                            |
+-----------------------------+------------------------------------------------------------------------------------------------------------------+
| ID                          | da63cb64-45d2-4c25-a692-b14221fd7459                                                                             |
| Instantiation State         | NOT_INSTANTIATED                                                                                                 |
| Links                       | {                                                                                                                |
|                             |     "self": {                                                                                                    |
|                             |         "href": "http://localhost:9890/vnflcm/v1/vnf_instances/da63cb64-45d2-4c25-a692-b14221fd7459"             |
|                             |     },                                                                                                           |
|                             |     "instantiate": {                                                                                             |
|                             |         "href": "http://localhost:9890/vnflcm/v1/vnf_instances/da63cb64-45d2-4c25-a692-b14221fd7459/instantiate" |
|                             |     }                                                                                                            |
|                             | }                                                                                                                |
| VNF Configurable Properties |                                                                                                                  |
| VNF Instance Description    | None                                                                                                             |
| VNF Instance Name           | vnf-da63cb64-45d2-4c25-a692-b14221fd7459                                                                         |
| VNF Product Name            | Sample VNF                                                                                                       |
| VNF Provider                | Company                                                                                                          |
| VNF Software Version        | 1.0                                                                                                              |
| VNFD ID                     | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177                                                                             |
| VNFD Version                | 1.0                                                                                                              |
| vnfPkgId                    |                                                                                                                  |
+-----------------------------+------------------------------------------------------------------------------------------------------------------+
```

確認します。

da63cb64-45d2-4c25-a692-b14221fd7459 は VNF_INSTANCE_ID です。

```
$ openstack vnf package show 229c9fea-aaac-4741-a893-644ed5d27e37 \
-c 'Usage State'
+-------------+--------+
| Field       | Value  |
+-------------+--------+
| Usage State | IN_USE |
+-------------+--------+

$ openstack vnflcm show da63cb64-45d2-4c25-a692-b14221fd7459 \
-c 'Instantiation State'
+---------------------+------------------+
| Field               | Value            |
+---------------------+------------------+
| Instantiation State | NOT_INSTANTIATED |
+---------------------+------------------+
```

### VNF のインスタンス化

次の形式で sample_param_file.json ファイルを作成します。
これは、インスタンス化リクエストのパラメータを定義するファイルです。
これらのパラメータは、インスタンス化リクエストの中身で設定されます。

必須パラメータ

- flavourID

オプションのパラメータ

- instantiationLevelId
- extVirtualLinks
- extManagedVirtualLinks
- vimConnectionInfo

vimConnectionInfo はデフォルト VIM が存在する場合のみ省略可能です。

設定に必要な情報を収集します。

- extVirtualLinks.resourceId: 7539276f-fa1e-44f4-8ff3-f6fb44f2e7e9 

ネットワークの UUID であり、`openstack network list` コマンドで取得できます。
今回は VNF インスタンスへのインバウンドパケットのためのネットワークである net0 を利用します。

```
$ openstack network list 
+--------------------------------------+-------------------------------------------------------------------+----------------------------------------------------------------------------+
| ID                                   | Name                                                              | Subnets                                                                    |
+--------------------------------------+-------------------------------------------------------------------+----------------------------------------------------------------------------+
| 02bb6ed5-bd90-423a-9b8e-2de58bd45329 | public                                                            | 323e6649-5b29-4ff1-afe3-cac404325ce3, 5c234bb8-0372-494d-b701-94d5640b9067 |
| 0b83f650-5556-4d23-b72f-3767230e747b | net1                                                              | c3810efb-c74b-41d9-8041-9d1e684e3f2d                                       |
| 1cbda5ce-a7b7-4798-81d5-f97019f7fbb7 | k8s-pod-net                                                       | 140dfd97-deab-46f5-a6df-fea2a48f842b                                       |
| 45d5bdcc-a88a-4f23-84e7-570f9b1bc5ee | k8s-service-net                                                   | 45506c3b-441c-49d4-a9dd-4ba75eb0d86b                                       |
| 4b0c4d1f-9c01-4c80-be92-19e5c3b8dfaa | private                                                           | 512581fc-601e-42ad-b26d-10d98c356088, 6d0ce67d-434a-45fd-bab6-898fc93386cc |
| 7539276f-fa1e-44f4-8ff3-f6fb44f2e7e9 | net0                                                              | a94f82d5-2ecc-428d-97fc-2730c79b6170                                       |
| 7db2bc29-6625-40aa-bdf2-ab91e3d47143 | net_mgmt                                                          | 75620ca9-00b9-4cb9-a01a-c8f67d841ba4                                       |
| 9e42731b-4b36-4883-aac2-2838a044ba8e | vnf-da63cb64-45d2-4c25-a692-b14221fd7459-internalVL2-lfhb7p3nwewa | 7dd5508a-0547-44e7-89b4-c02a9a34e781                                       |
| fbd1da96-6631-41d0-a09d-6fca9b3edc0e | lb-mgmt-net                                                       | db9b1b01-bde5-4e81-969a-013ac5181f7a                                       |
+--------------------------------------+-------------------------------------------------------------------+----------------------------------------------------------------------------+
```

- vimConnectionInfo.id: e24f9796-a8e9-4cb0-85ce-5920dcddafa1 

識別に利用するランダムな値の UUID でありますが、実際の設定で VIM と VID を利用して一意に紐づいているため、重複していたとしても問題ない値です。

今回は [ETSI NFV-SOL VNF Deployment as VM with TOSCA](https://docs.openstack.org/tacker/latest/user/etsi_vnf_deployment_as_vm_with_tosca.html) にサンプルとして準備されている値をそのまま利用しています。

- vimConnectionInfo.vimId: 03179d72-ac26-4ac2-bdd4-43cc2672dea8 

結びつける対象の VIM の ID であり、`openstack vim list` コマンドで取得します。

```
$ openstack vim list
+--------------------------------------+-------------------+----------------------------------+-----------+------------+-----------+
| ID                                   | Name              | Tenant_id                        | Type      | Is Default | Status    |
+--------------------------------------+-------------------+----------------------------------+-----------+------------+-----------+
| 03179d72-ac26-4ac2-bdd4-43cc2672dea8 | openstack-nfv-vim | 7ef18f601b824be897934f6793130760 | openstack | True       | REACHABLE |
+--------------------------------------+-------------------+----------------------------------+-----------+------------+-----------+
```

取得した情報から設定ファイルを作成します。

```
cat << _EOF_ > ~/work/sample_param_file.json
{
  "flavourId": "simple",
  "instantiationLevelId": "instantiation_level_1",
  "extVirtualLinks": [
    {
      "id": "net0",
      "resourceId": "7539276f-fa1e-44f4-8ff3-f6fb44f2e7e9",
      "extCps": [
        {
          "cpdId": "CP1",
          "cpConfig": [
            {
              "cpProtocolData": [
                {
                  "layerProtocol": "IP_OVER_ETHERNET"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "vimConnectionInfo": [
    {
      "id": "e24f9796-a8e9-4cb0-85ce-5920dcddafa1",
      "vimId": "03179d72-ac26-4ac2-bdd4-43cc2672dea8",
      "vimType": "ETSINFV.OPENSTACK_KEYSTONE.v_2"
    }
  ]
}
_EOF_
```

VNF インスタンスをインスタンス化します。

da63cb64-45d2-4c25-a692-b14221fd7459 は [VNF Identifier の作成] にて作成された  VNF_INSTANCE_ID です。
忘れてしまった場合は `openstack vnflcm list` コマンドで確認できます。

```
$ openstack vnflcm instantiate da63cb64-45d2-4c25-a692-b14221fd7459 \
./sample_param_file.json
Instantiate request for VNF Instance da63cb64-45d2-4c25-a692-b14221fd7459 has been accepted.
```

確認します。

```
$ openstack vnflcm show da63cb64-45d2-4c25-a692-b14221fd7459 \
-c 'Instantiation State'
+---------------------+--------------+
| Field               | Value        |
+---------------------+--------------+
| Instantiation State | INSTANTIATED |
+---------------------+--------------+
```

openstack server が立っていることも確認できます。

```
$ openstack server list --all-projects
+--------------------------------------+----------------------------------------------+---------+------------------------------------------------------------------------------------------------+--------------------------+-------------------------------------------------------------------+
| ID                                   | Name                                         | Status  | Networks                                                                                       | Image                    | Flavor                                                            |
+--------------------------------------+----------------------------------------------+---------+------------------------------------------------------------------------------------------------+--------------------------+-------------------------------------------------------------------+
| 01a06a8b-93fe-4023-bbbe-f1de5a3b987c | VDU2                                         | ACTIVE  | vnf-da63cb64-45d2-4c25-a692-b14221fd7459-internalVL2-lfhb7p3nwewa=11.11.0.42                   | N/A (booted from volume) | vnf-da63cb64-45d2-4c25-a692-b14221fd7459-VDU2_flavor-q7r7louhdugv |
| 2a113907-3fcf-4934-83a4-c44673dcc43f | VDU1                                         | ACTIVE  | net0=10.10.0.156; vnf-da63cb64-45d2-4c25-a692-b14221fd7459-internalVL2-lfhb7p3nwewa=11.11.0.97 | Software of VDU1         | vnf-da63cb64-45d2-4c25-a692-b14221fd7459-VDU1_flavor-egnpid7drpmp |
| 5fff29fc-e0d5-434a-a340-d077347f9845 | amphora-e3f67a49-45aa-4309-801b-a16152e49909 | SHUTOFF | k8s-service-net=10.0.0.166; lb-mgmt-net=192.168.0.163                                          | amphora-x64-haproxy      | m1.amphora                                                        |
+--------------------------------------+----------------------------------------------+---------+------------------------------------------------------------------------------------------------+--------------------------+-------------------------------------------------------------------+
```

Openstack の stack の確認も可能です。

```
$ openstack stack list
+--------------------------------------+------------------------------------------+----------------------------------+-----------------+----------------------+--------------+
| ID                                   | Stack Name                               | Project                          | Stack Status    | Creation Time        | Updated Time |
+--------------------------------------+------------------------------------------+----------------------------------+-----------------+----------------------+--------------+| 32497662-99bd-4f30-8c80-66bc0da890b6 | vnf-da63cb64-45d2-4c25-a692-b14221fd7459 | 66415ef3b0dc44e394b74d75b1945c50 | CREATE_COMPLETE | 2022-07-08T02:31:21Z | None         |+--------------------------------------+------------------------------------------+----------------------------------+-----------------+----------------------+--------------+ 

# 詳細を確認したい場合
$ openstack stack show  32497662-99bd-4f30-8c80-66bc0da890b6
```

## VNF の終了

VNF インスタンスを終了させます。

```
$ openstack vnflcm terminate da63cb64-45d2-4c25-a692-b14221fd7459 
Terminate request for VNF Instance 'da63cb64-45d2-4c25-a692-b14221fd7459' has been accepted.
```

確認します。

```
$ openstack vnflcm show da63cb64-45d2-4c25-a692-b14221fd7459 \
-c 'Instantiation State'
+---------------------+------------------+
| Field               | Value            |
+---------------------+------------------+
| Instantiation State | NOT_INSTANTIATED |
+---------------------+------------------+
```

## VNF Identifier を削除

VNF Identifier を削除します.

```
$ openstack vnflcm delete da63cb64-45d2-4c25-a692-b14221fd7459
Vnf instance 'da63cb64-45d2-4c25-a692-b14221fd7459' deleted successfully
```

確認します。

```
$ openstack vnf package show 229c9fea-aaac-4741-a893-644ed5d27e37 \
-c 'Usage StateI
+-------------+------------+
| Field       | Value      |
+-------------+------------+
| Usage State | NOT_IN_USE |
+-------------+------------+

$ openstack vnflcm show da63cb64-45d2-4c25-a692-b14221fd7459 \
-c 'Instantiation State'
Can not find requested vnf instance: da63cb64-45d2-4c25-a692-b14221fd7459
```

# 発生したエラー

## openstack コマンドの Permission Error

openstack 関係のコマンドを打つと下記のように表示されました。

```
$ openstack endpoint list
/usr/lib/python3/dist-packages/secretstorage/dhcrypto.py:15: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
/usr/lib/python3/dist-packages/secretstorage/util.py:19: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead
  from cryptography.utils import int_from_bytes
Missing value auth-url required for auth plugin password
```

上 2 つの Warning は軽く調べたところでは pip で依存関係解決したらなくなるとかなんとかとのことでした。

表示を消したい場合には `export PYTHONWARNINGS="ignore"` を bashrc などに書いて読み込むことで消すことができます。

しかし、他のパッケージで発生する Warning も一緒に消えてしまうため、他の問題に対処する際に何かうまくいかない箇所が発生した場合はこの ignore の設定を削除してください。

もう 1 つの対応としてこの Warning の解消もあります。
今回の Warning は int_from_bytes が deprecated (非推奨) であるために発生している Warning です。
`/usr/lib/python3/dist-packages/secretstorage/dhcrypto.py` を見に行くと `from cryptography.utils import int_from_bytes` となっており、確かに `int.from_bytes` ではないです。
この Warning を解消するためには cryptography が int_from_bytes を利用していたバージョンである  3.3 以下にする必要があります。

```
pip uninstall cryptography 
pip install cryptography==3.3 
```

ただし、この手法では cryptography のバージョンが下がってしまうため、ご自身の環境とご相談のうえで実施してください。

```
Missing value auth-url required for auth plugin password
```

パスワード等が環境変数に定義されていないのが原因のため、Horizon から環境変数設定用ファイルをダウンロードして読み込めばよいです。

- 参考
	- [Open Stack Neutron環境構築 その2:OpenStack のインストール](https://metonymical.hatenablog.com/entry/2019/05/29/201242)
	- [Missing value auth-url required for auth plugin password](https://stackoverflow.com/questions/42844649/missing-value-auth-url-required-for-auth-plugin-password)


## Instantiate VNF でインスタンス化されない

### openstack vnflcm instantiate \<ID> でコンフリクト

```
$ journalctl -xe -u devstack@tacker -f

...

tacker-server[1172]: 2022-07-07 09:21:45.496 DEBUG tacker.wsgi [-] (1172) accepted ('10.100.2.220', 46796) from (pid=1172) server /usr/local/lib/python3.8/dist-packages/eventlet/wsgi.py:1004
tacker-server[1172]: 2022-07-07 09:21:45.586 INFO tacker.wsgi [req-a6ea67eb-dd53-4c34-9e5e-e9ee72c8f024 admin admin] POST http://10.100.2.220:9890/vnflcm/v1/vnf_instances/da63cb64-45d2-4c25-a692-b14221fd7459/instantiate
tacker-server[1172]: 2022-07-07 09:21:45.591 DEBUG tacker.db.vnfm.vnfm_db [req-a6ea67eb-dd53-4c34-9e5e-e9ee72c8f024 admin admin] vnf_db <tacker.db.vnfm.vnfm_db.VNF[object at 7f03727e9d00] {tenant_id='7ef18f601b824be897934f6793130760', id='da63cb64-45d2-4c25-a692-b14221fd7459', created_at=datetime.datetime(2022, 7, 7, 7, 28, 8), updated_at=datetime.datetime(2022, 7, 7, 8, 0, 53), deleted_at=datetime.datetime(1, 1, 1, 0, 0), vnfd_id='b1bb0ce7-ebca-4fa7-95ed-4840d70a1177', name='vnf-da63cb64-45d2-4c25-a692-b14221fd7459', description=None, instance_id=None, mgmt_ip_address=None, status='ERROR', vim_id='03179d72-ac26-4ac2-bdd4-43cc2672dea8', placement_attr={'regions': ['RegionOne']}, error_reason=None}> from (pid=1172) _make_vnf_dict /opt/stack/tacker/tacker/db/vnfm/vnfm_db.py:227
tacker-server[1172]: 2022-07-07 09:21:45.593 DEBUG tacker.db.vnfm.vnfm_db [req-a6ea67eb-dd53-4c34-9e5e-e9ee72c8f024 admin admin] vnf_db attributes [<tacker.db.vnfm.vnfm_db.VNFAttribute[object at 7f037274bb20] {id='6ca4bb5d-9e21-4558-9291-bc10dc75f42e', vnf_id='da63cb64-45d2-4c25-a692-b14221fd7459', key='placement_attr', value="{'regions': ['RegionOne']}"}>] from (pid=1172) _make_vnf_dict /opt/stack/tacker/tacker/db/vnfm/vnfm_db.py:228
tacker-server[1172]: 2022-07-07 09:21:45.604 INFO tacker.wsgi [req-a6ea67eb-dd53-4c34-9e5e-e9ee72c8f024 admin admin] http://10.100.2.220:9890/vnflcm/v1/vnf_instances/da63cb64-45d2-4c25-a692-b14221fd7459/instantiate returned with HTTP 409
tacker-server[1172]: 2022-07-07 09:21:45.604 DEBUG tacker.wsgi [req-a6ea67eb-dd53-4c34-9e5e-e9ee72c8f024 admin admin] Returning 409 to user: Vnf da63cb64-45d2-4c25-a692-b14221fd7459 in status ERROR. Error point 0. Cannot instantiate while the vnf is in this state with this error point. from (pid=1172) __call__ /opt/stack/tacker/tacker/wsgi.py:1057Jul 07 tacker-server[1172]: 2022-07-07 09:21:45.605 INFO tacker.wsgi [req-a6ea67eb-dd53-4c34-9e5e-e9ee72c8f024 admin admin] 10.100.2.220 - - [07/Jul/2022 09:21:45] "POST /vnflcm/v1/vnf_instances/da63cb64-45d2-4c25-a692-b14221fd7459/instantiate HTTP/1.1" 409 423 0.107623
```

`http://10.100.2.220:9890/vnflcm/v1/vnf_instances/da63cb64-45d2-4c25-a692-b14221fd7459/instantiate returned with HTTP 409` のように HTTP 409 番 = コンフリクトのエラーが発生していることがわかります。

`Vnf da63cb64-45d2-4c25-a692-b14221fd7459 in status ERROR. Error point 0. Cannot instantiate while the vnf is in this state with this error point.` とかもそれにあたります。

コンフリクトエラーが発生した原因は 2 回 `openstack vnflcm instantiate da63cb64-45d2-4c25-a692-b14221fd7459 ./sample_param_file.json` を実行したためでした。

VNF のライフサイクル的に FAILED_TEMP になってしまっているものに対して再度 create や instantiate はできません。

```
$ openstack vnflcm op list
+--------------------------------------+-----------------+--------------------------------------+-------------+
| ID                                   | Operation State | VNF Instance ID                      | Operation   |
+--------------------------------------+-----------------+--------------------------------------+-------------+
| 0209ce3a-6942-4297-a1af-da8eb7638458 | FAILED_TEMP     | da63cb64-45d2-4c25-a692-b14221fd7459 | INSTANTIATE |
| 4a94a123-4648-418d-8bd0-f536b7a445f0 | FAILED          | da63cb64-45d2-4c25-a692-b14221fd7459 | INSTANTIATE |
+--------------------------------------+-----------------+--------------------------------------+-------------+       
```

そのため、再度実行したい場合は retry か rollback、もしくは一度 FAILED 状態に持って行って終了させる必要があります。

```
# retry の場合
openstack vnflcm op retry 0209ce3a-6942-4297-a1af-da8eb7638458                                                        Retry request for LCM operation 0209ce3a-6942-4297-a1af-da8eb7638458 has been accepted 

# fail の場合
openstack vnflcm op fail 0209ce3a-6942-4297-a1af-da8eb7638458
```

終了後に改めて create や instantiate を実行します。

### Instantiate VNF でインスタンス化されない 

Tacker はリクエストを tacker-server で受信したのちに tacker-conductor に渡します。
そのため、単に Tacker のエラーが発生したとしても server 側と conductor 側の 2 つに切り分けすることができます。
今回は server 側の journalctl を確認した際には リクエストを受け付けた HTTP の 200 番台のステータスコードが確認できましたが、インスタンス化されず、FAILED_TEMP 状態に遷移していました。

そのため、conductor 側のエラーを確認しました。

#### Nuetron に QoS が許可されていない

```
$ journalctl -xe -u devstack@tacker-conductor.service --no-pager

...

tacker-conductor[1171]: 2022-07-08 01:32:40.794 ERROR tacker.vnflcm.vnflcm_driver [req-ff3085db-17c6-43f2-8f00-8a183eadaa2a admin admin] Unable to instantiate vnf instance da63cb64-45d2-4c25-a692-b14221fd7459 due to error : ERROR: HEAT-E99001 Service neutron is not available for resource type OS::Neutron::QoSPolicy, reason: Required extension qos in neutron service is not available.: tacker.extensions.vnfm.HeatClientException: ERROR: HEAT-E99001 Service neutron is not available for resource type OS::Neutron::QoSPolicy, reason: Required extension qos in neutron service is not available.
tacker-conductor[1171]: 2022-07-08 01:32:40.795 ERROR root [req-ff3085db-17c6-43f2-8f00-8a183eadaa2a admin admin] Original exception being dropped: ['Traceback (most recent call last):\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/heat_client.py", line 67, in create\n    return self.stacks.create(**fields)\n', '  File "/usr/local/lib/python3.8/dist-packages/heatclient/v1/stacks.py", line 170, in create\n    resp = self.client.post(\'/stacks\',\n', '  File "/usr/local/lib/python3.8/dist-packages/keystoneauth1/adapter.py", line 401, in post\n    return self.request(url, \'POST\', **kwargs)\n', '  File "/usr/local/lib/python3.8/dist-packages/heatclient/common/http.py", line 323, in request\n    raise exc.from_response(resp)\n', 'heatclient.exc.HTTPBadRequest: ERROR: HEAT-E99001 Service neutron is not available for resource type OS::Neutron::QoSPolicy, reason: Required extension qos in neutron service is not available.\n', '\nDuring handling of the above exception, another exception occurred:\n\n', 'Traceback (most recent call last):\n', '  File "/opt/stack/tacker/tacker/vnflcm/vnflcm_driver.py", line 371, in _instantiate_vnf\n    instance_id = self._vnf_manager.invoke(\n', '  File "/opt/stack/tacker/tacker/common/driver_manager.py", line 71, in invoke\n    return getattr(driver, method_name)(**kwargs)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/openstack.py", line 1139, in instantiate_vnf\n    instance_id = self.create(plugin, context, vnfd_dict,\n', '  File "/opt/stack/tacker/tacker/common/log.py", line 35, in wrapper\n    return method(*args, **kwargs)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/openstack.py", line 317, in create\n    stack = self._create_stack(heatclient, tth.vnf, tth.fields)\n', '  File "/opt/stack/tacker/tacker/common/log.py", line 35, in wrapper\n    return method(*args, **kwargs)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/openstack.py", line 585, in _create_stack\n    stack = heatclient.create(fields)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/heat_client.py", line 70, in create\n    raise vnfm.HeatClientException(msg=value)\n', 'tacker.extensions.vnfm.HeatClientException: ERROR: HEAT-E99001 Service neutron is not available for resource type OS::Neutron::QoSPolicy, reason: Required extension qos in neutron service is not available.\n']: tacker.common.exceptions.VnfInstantiationFailed: Vnf instantiation failed for vnf da63cb64-45d2-4c25-a692-b14221fd7459, error: ERROR: HEAT-E99001 Service neutron is not available for resource type OS::Neutron::QoSPolicy, reason: Required extension qos in neutron service is not available.
tacker-conductor[1171]: 2022-07-08 01:32:40.796 DEBUG tacker.common.log [req-ff3085db-17c6-43f2-8f00-8a183eadaa2a admin admin] tacker.conductor.conductor_server.Conductor method _change_vnf_status called with arguments (<tacker.context.Context object at 0x7fb5d4b24df0>, 'da63cb64-45d2-4c25-a692-b14221fd7459', ('ACTIVE', 'INACTIVE', 'ERROR', 'PENDING_INSTANTIATE', 'PENDING_CREATE', 'PENDING_UPDATE', 'PENDING_DELETE', 'PENDING_SCALE_IN', 'PENDING_SCALE_OUT', 'PENDING_HEAL', 'PENDING_TERMINATE', 'PENDING_CHANGE_EXT_CONN'), 'ERROR') {} from (pid=1171) wrapper /opt/stack/tacker/tacker/common/log.py:33
tacker-conductor[1171]: 2022-07-08 01:32:40.800 DEBUG tacker.conductor.conductor_server [req-ff3085db-17c6-43f2-8f00-8a183eadaa2a admin admin] Change status of vnf da63cb64-45d2-4c25-a692-b14221fd7459 from PENDING_CREATE to ERROR from (pid=1171) _change_vnf_status /opt/stack/tacker/tacker/conductor/conductor_server.py:643 
```

`Required extension qos in neutron service is not available` と出ているため、Neutron が QoS を扱うための拡張プラグインの設定が足りていないことがわかります。

- 参考: [Getting Started with ETSI NFV-SOL Tacker Trouble Shooting](https://docs.openstack.org/tacker/xena/install/etsi_getting_started.html#trouble-shooting)

そのため、参考サイトを参照して拡張設定を追加します。

```
$ diff /etc/neutron/neutron.conf{.default,}
2c2,3
< service_plugins = ovn-router,networking_sfc.services.flowclassifier.plugin.FlowClassifierPlugin,networking_sfc.services.sfc.plugin.SfcPlugin
---
> #service_plugins = ovn-router,networking_sfc.services.flowclassifier.plugin.FlowClassifierPlugin,networking_sfc.services.sfc.plugin.SfcPlugin
> service_plugins = ovn-router,networking_sfc.services.flowclassifier.plugin.FlowClassifierPlugin,networking_sfc.services.sfc.plugin.SfcPlugin,neutron.services.qos.qos_plugin.QoSPlugin,qos
```

#### CP1 の設定がおかしい

状況として、[VNF のインスタンス化] にて作成した sample_param_file.json ファイルの中身が最小限構成の `flavourID` の値のみが設定されているものを利用していました。

```
tacker-conductor[1171]: 2022-07-08 01:45:18.164 ERROR tacker.vnflcm.vnflcm_driver [req-453dde80-aad5-446a-be2c-cbee4e58120f admin admin] Unable to instantiate vnf instance da63cb64-45d2-4c25-a692-b14221fd7459 due to error : ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.: tacker.extensions.vnfm.HeatClientException: ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.                                                                                                 
tacker-conductor[1171]: 2022-07-08 01:45:18.165 ERROR root [req-453dde80-aad5-446a-be2c-cbee4e58120f admin admin] Original exception being dropped: ['Traceback (most recent call last):\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/heat_client.py", line 67, in create\n    return self.stacks.create(**fields)\n', '  File "/usr/local/lib/python3.8/dist-packages/heatclient/v1/stacks.py", line 170, in create\n    resp = self.client.post(\'/stacks\',\n', '  File "/usr/local/lib/python3.8/dist-packages/keystoneauth1/adapter.py", line 401, in post\n    return self.request(url, \'POST\', **kwargs)\n', '  File "/usr/local/lib/python3.8/dist-packages/heatclient/common/http.py", line 323, in request\n    raise exc.from_response(resp)\n', "heatclient.exc.HTTPBadRequest: ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.\n", '\nDuring handling of the above exception, another exception occurred:\n\n', 'Traceback (most recent call last):\n', '  File "/opt/stack/tacker/tacker/vnflcm/vnflcm_driver.py", line 371, in _instantiate_vnf\n    instance_id = self._vnf_manager.invoke(\n', '  File "/opt/stack/tacker/tacker/common/driver_manager.py", line 71, in invoke\n    return getattr(driver, method_name)(**kwargs)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/openstack.py", line 1139, in instantiate_vnf\n    instance_id = self.create(plugin, context, vnfd_dict,\n', '  File "/opt/stack/tacker/tacker/common/log.py", line 35, in wrapper\n    return method(*args, **kwargs)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/openstack.py", line 317, in create\n    stack = self._create_stack(heatclient, tth.vnf, tth.fields)\n', '  File "/opt/stack/tacker/tacker/common/log.py", line 35, in wrapper\n    return method(*args, **kwargs)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/openstack.py", line 585, in _create_stack\n    stack = heatclient.create(fields)\n', '  File "/opt/stack/tacker/tacker/vnfm/infra_drivers/openstack/heat_client.py", line 70, in create\n    raise vnfm.HeatClientException(msg=value)\n', "tacker.extensions.vnfm.HeatClientException: ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.\n"]: tacker.common.exceptions.VnfInstantiationFailed: Vnf instantiation failed for vnf da63cb64-45d2-4c25-a692-b14221fd7459, error: ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.      
tacker-conductor[1171]: 2022-07-08 01:45:18.166 DEBUG tacker.common.log [req-453dde80-aad5-446a-be2c-cbee4e58120f admin admin] tacker.conductor.conductor_server.Conductor method _change_vnf_status called with arguments (<tacker.context.Context object at 0x7fb5d4cf6d00>, 'da63cb64-45d2-4c25-a692-b14221fd7459', ('ACTIVE', 'INACTIVE', 'ERROR', 'PENDING_INSTANTIATE', 'PENDING_CREATE', 'PENDING_UPDATE', 'PENDING_DELETE', 'PENDING_SCALE_IN', 'PENDING_SCALE_OUT', 'PENDING_HEAL', 'PENDING_TERMINATE', 'PENDING_CHANGE_EXT_CONN'), 'ERROR') {} from (pid=1171) wrapper /opt/stack/tacker/tacker/common/log.py:33                                  
tacker-conductor[1171]: 2022-07-08 01:45:18.168 DEBUG tacker.conductor.conductor_server [req-453dde80-aad5-446a-be2c-cbee4e58120f admin admin] Change status of vnf da63cb64-45d2-4c25-a692-b14221fd7459 from PENDING_CREATE to ERROR from (pid=1171) _change_vnf_status /opt/stack/tacker/tacker/conductor/conductor_server.py:643
```

上記のエラーから

```
ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.: tacker.extensions.vnfm.HeatClientException: ERROR: Property error: : resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.
```

と出ていることがわかります。
NFV は VNF, NFVI, MANO という 3 領域に分割され、仮想ネットワーク機器の管理をしています。

Tacker に与えられる (もしくは データベースから取り出した) ネットワークの情報が足りてないことから次のどちらかが原因として考えられます。

- 作成して渡した property に間違いが存在している
- Tacker そのものに不具合が発生しており、データベースから値が取り出せていない

ただし、後者の場合、ネットワークの情報だけが取り出せていないということになるため、前者の可能性が高いと考えられます。

今回は配置するネットワーク機器を TOSCA で YAML ファイルとして準備し、パッケージとしてアップロードしていました。
`resources.CP1.properties.network: : Multiple network matches found for name '', use an ID to be more specific.` なので、与える定義ファイルが間違っていそうでした。

自身で作成して渡している情報は 2 つあり、VNF パッケージとインスタンス化リクエストのパラメータを定義するファイルです。
この 2 つのファイルは補完関係にあります。

- VNF パッケージ

CP1 に関連する設定箇所を見に行くと 必要な情報である virtual_link の設定が足りていないことがわかります。

-  インスタンス化リクエストのパラメータを定義するファイル

このファイルで flavourID のみを指定して際に作成される VM はすべてパッケージに定義されている値を利用して作成されるものとなります。
これはつまり、常に同じ VM ができるということです。

オプションのパラメータを定義したファイルに変更することでパッケージの情報の上書きや補完をして VM 作成してくれるようになります。
今回は、パッケージの情報が足りてないものをアップロードしたうえにインスタンス化リクエストのパラメータを定義するファイルで最小限構成のものを利用したことで、必要な情報が抜け落ちインスタンス化することができていませんでした。

そのため、対応として sample_param_file.json ファイルの中身を最小限の構成からネットワークの情報などを記載したものに変更し、再度インスタンス化することでインスタンス化できました。

# まとめ

今回は実際に OpenStack を VIM として登録し、VNF としてデプロイしました。
手順内で出てくる 〇〇ID は環境変数として定義しておき、後から使用するといいなと思ったため、次手順から実施してみようと思ってます。

ここまでお読みいただき、ありがとうございました。