ETSI NFV-SOL CNF (容器化 VNF) 部署

本节介绍如何使用 Kubernetes VIM 在 Tacker v2 API 中部署 ETSI NFV-SOL 容器化 VNF。

注意

本文档的内容已确认使用以下 VNF 包有效。

有关支持的 Kubernetes 版本的信息,请参阅 Tacker 架构

概述

下图显示了 CNF 部署的概述。

  1. 请求创建 VNF

    用户通过上传 VNF 包并请求 create VNF,使用 tacker-client 向 tacker-server 请求创建 VNF。VNF 包应包含 CNF 定义,除了 VNFD 之外。有关 CNF 定义VNFD 的详细说明,请参阅 2. 创建 Kubernetes 对象文件5. 创建 VNFD

  2. 请求实例化 VNF

    用户通过请求 instantiate VNF 并提供实例化参数,向 tacker-server 请求实例化创建的 VNF。

  3. 调用 Kubernetes API

    收到 tacker-client 的请求后,tacker-server 会将其重定向到 tacker-conductor。在 tacker-conductor 中,请求会根据实例化参数的内容再次重定向到适当的 infra-driver(在本例中为 Kubernetes infra-driver)。然后,Kubernetes infra-driver 调用 Kubernetes API 以创建 Pod 作为 VNF。

  4. 创建 Pod

    Kubernetes Master 根据 API 调用创建 Pod。

../../../../_images/deployment.svg

准备 Kubernetes VIM

1. 创建配置文件

在将 Kubernetes VIM 注册到 tacker 之前,我们应该创建配置文件。以下 vim-k8s.yaml 文件提供注册 Kubernetes VIM 的必要信息。此示例指定了可以从 Kubernetes Master-node 获取的 bearer_tokenssl_ca_cert 参数的值。有关获取“bearer_token”和“ssl_ca_cert”的具体方法,请参阅 Kubernetes VIM 安装

$ cat vim-k8s.yaml
auth_url: "https://192.168.56.10:6443"
bearer_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IkdVazBPakx4Q2NsUjJjNHhsZFdaaXJMSHVQMUo4NkdMS0toamlSaENiVFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tazhzdmltIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhNTIzYzFhMi1jYmU5LTQ1Y2YtYTc5YS00ZDA4MDYwZDE3NmEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZWZhdWx0In0.BpKAAQLjXMIpJIjqQDsGtyh1a-Ij8e-YOVRv0md_iOGXd1KLR-qreM6xA-Ni8WFILzq3phaZU6npET8PlfhQ6csF5u20OT2SoZ7iAotHXpCcYkRdrUd2oO5KxSFTkOhasaN1pQ3pZyaFYUZbwwmLK3I31rG4Br2VbZQ7Qu8wFOXUK-syBGF48vIPZ5JQ3K00KNxpuEcGybMK5LtdSKZ25Ozp_I2oqm3KBZMPMfWwaUnvuRnyly13tsiXudPt_9H78AxLubMo3rcvECJU2y_zZLiavcZKXAz-UmHulxtz_XZ80hMu-XOpYWEYrOB0Lt0hB59ZoY1y3OvJElTfPyrwWw"
ssl_ca_cert: "-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIIa76wZDxLNAowDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE
AxMKa3ViZXJuZXRlczAeFw0yMzExMDYwMDA3MzBaFw0zMzExMDMwMDEyMzBaMBUx
EzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDd0LBXGxVexr09mVFNSXWQq3TN66IIcXCBAMbIWI4EiQ8Y0zI4hSwADdK2
ltYSdWw7wq3/YTFHK8/YTY7Jvd9/k3UJrqkZ6kBtL20pJUPXNJVLE/hRzsqEnHHv
cfqYZTHvTY4g7qNcMOcfl/oDUGUMfpQT2gs6xoNl0WX/1+QeQbadx1kWaD2Ii45F
d8TR+c4wccxNaLArk3ok4h1PNeAwra4mRmBHQQ2wFjkTYGl4+ss3v1yoUJkrQjXL
RgzLufeXaz8eRTi36HkjudGKfS3OnUeke3uBN7usW58FFJ8TdKOhuoguRm53kj6+
TwXtZCOPzn4gNxq6xJE1Xj2hwFfpAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRdmQ4r63pXBHIO8ODqxROE7x+aizAV
BgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQBeQ/9+bzRe
qbA02MfYnN3vycGhDObcAoiDIMIutojFTpx4hGZjqVgTRpLH5ReddwR4kkxn3NRg
weCVkNkhzyGze64nb11qZG71olaOQRMYzyN2hYfmbq7MXSvmJQQYIr1OewaRk+xl
TyG1XRXoD2IEaHEvG0+pQJlDerd5Z6S1fkPaKZtcRbM/E6y5VXMV6hegN4MwHZSI
Ll1uEBTxUzzTm3dnl1KL8GDg05ajoYcyL3X/0aWsb/MFhtIlXe2CMxu5qUkLBhzy
fCfX4cZpI5KFxMgdmAEoaGbNy7iqsGrLFtEmub2gdEBIVNr7vgOk4OeQ9Uodj6K7
jK97z+cupc5G
-----END CERTIFICATE-----"
project_name: "admin"
type: "kubernetes"

除了使用 bearer_token 进行 Kubernetes 身份验证外,还支持 OpenID Connect Tokens。以下示例指定了 oidc_token_urlclient_idclient_secretusernamepassword,而不是用于 OpenID 令牌身份验证的 bearer_token

在使用 OpenID 令牌身份验证之前,需要进行其他设置。请参阅 Kubernetes VIM OpenID 令牌身份验证使用指南,以及如何获取 oidc_token_urlclient_idclient_secretusernamepasswordssl_ca_cert 参数的文档。

Kubernetes 和 OpenID 提供商的 SSL 证书在 ssl_ca_cert 中连接。

$ cat vim-k8s.yaml
auth_url: "https://192.168.33.100:6443"
project_name: "default"
oidc_token_url: "https://192.168.33.100:8443/realms/oidc/protocol/openid-connect/token"
client_id: "tacker"
client_secret: "A93HfOUpySm6BjPug9PJdJumjEGUJMhc"
username: "end-user"
password: "end-user"
ssl_ca_cert: "-----BEGIN CERTIFICATE-----
MIICwjCCAaqgAwIBAgIBADANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwdrdWJl
LWNhMB4XDTIwMDgyNjA5MzIzMVoXDTMwMDgyNDA5MzIzMVowEjEQMA4GA1UEAxMH
a3ViZS1jYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxkeE16lPAd
pfJj5GJMvZJFcX/CD6EB/LUoKwGmqVoOUQPd3b/NGy+qm+3bO9EU73epUPsVaWk2
Lr+Z1ua7u+iib/OMsfsSXMZ5OEPgd8ilrTGhXOH8jDkif9w1NtooJxYSRcHEwxVo
+aXdIJhqKdw16NVP/elS9KODFdRZDfQ6vU5oHSg3gO49kgv7CaxFdkF7QEHbchsJ
0S1nWMPAlUhA5b8IAx0+ecPlMYUGyGQIQgjgtHgeawJebH3PWy32UqfPhkLPzxsy
TSxk6akiXJTg6mYelscuxPLSe9UqNvHRIUoad3VnkF3+0CJ1z0qvfWIrzX3w92/p
YsDBZiP6vi8CAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB/wQFMAMB
Af8wDQYJKoZIhvcNAQELBQADggEBAIbv2ulEcQi019jKz4REy7ZyH8+ExIUBBuIz
InAkfxNNxV83GkdyA9amk+LDoF/IFLMltAMM4b033ZKO5RPrHoDKO+xCA0yegYqU
BViaUiEXIvi/CcDpT9uh2aNO8wX5T/B0WCLfWFyiK+rr9qcosFYxWSdU0kFeg+Ln
YAaeFY65ZWpCCyljGpr2Vv11MAq1Tws8rEs3rg601SdKhBmkgcTAcCzHWBXR1P8K
rfzd6h01HhIomWzM9xrP2/2KlYRvExDLpp9qwOdMSanrszPDuMs52okXgfWnEqlB
2ZrqgOcTmyFzFh9h2dj1DJWvCvExybRmzWK1e8JMzTb40MEApyY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIC7TCCAdWgAwIBAgIUQK2k5uNvlRLx43LI/t3a2/A/3iQwDQYJKoZIhvcNAQEL
BQAwFTETMBEGA1UEAxMKa3ViZXJuZXRlczAeFw0yMjA4MDQwNjIwNTFaFw0yMzA4
MDQwNjIwNTFaMBMxETAPBgNVBAMMCEtleWNsb2FrMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAni7HWLn2IpUImGO1sbBf/XuqATkXSeIIRuQuFymwYPoX
BP7RowzrbfF9KUwdIKlz9IXjqb1hplumiqNy1Sc7MmrTY9Fj87MNAMlnCIvyWkjE
XVXWxGef49mqc85P2K1iuAsr2R7sDrv7SC0ch+lHclOjGDmCjKOk8qF3kD1LATWg
zf42aXb4nNF9kyIOPEbI+jX4PWhAQpEz5nIG+xIRjTHGfacjpeg0+XOK21wLAuQB
fqebJ6GxX4OzB37ZtLLgrKyBYWaWuYkWbexVRM3wEvQu8ENkvhV017iPuPHSxNWx
Y8z072XMs9j8XRQD65EVqObXyizotPRJF4slEJ9qMQIDAQABozcwNTAJBgNVHRME
AjAAMAsGA1UdDwQEAwIF4DAbBgNVHREEFDAShwR/AAABhwTAqAIhhwQKCgCMMA0G
CSqGSIb3DQEBCwUAA4IBAQBebjmNHd8sJXjvPQc3uY/3KSDpk9AYfYzhUZvcvLNg
z0llFqXHaFlMqHTsz1tOH4Ns4PDKKoRT0JIKC1FkvjzqgL+X2jWFS0NRoNyd3W3B
yHLEL7MdQqDR+tZX02EGfaGXjuy8GHIU4J2hXhohmpn6ntfiRONfY8jaEjIecPFS
IwZWXNhsDESa1zuDe0PatES/Ati8bAUpN2rb/7rsE/AeM5GXpQfOKV0XxdIeBZ82
Vf5cUDWPipvq2Q9KS+yrTvEObGtA6gKhQ4bpz3MieU3N8AtQpEKtROH7mJWMHyl2
roD1k8KeJlfvR/XcVTGFcgIdNLfKIdd99Xfi4gSaIKuw
-----END CERTIFICATE-----"
type: "kubernetes"

2. 注册 Kubernetes VIM

我们可以通过运行以下命令将 Kubernetes VIM 注册到 tacker

$ openstack vim register --config-file CONFIG_FILE KUBERNETES_VIM_NAME --fit-width

第 1 章中的配置文件需要通过参数 –config-file 输入。执行成功后,将显示 VIM 信息。例如,id。我们还可以使用用户名和密码等身份验证方法来注册 Kubernetes VIM。有关详细信息,请参阅第 1 章中的超链接。

$ openstack vim register --config-file vim-k8s.yaml test-vim-k8s --fit-width --is-default
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field          | Value                                                                                                                                                                                                                                     |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| auth_cred      | {                                                                                                                                                                                                                                         |
|                |     "bearer_token": "***",                                                                                                                                                                                                                |
|                |     "ssl_ca_cert": "b'gAAAAABlVGfZpWGEYn2hjBEVpkFOTZ4lt8xtMagfzpmoaHNXMzCwKX8Sd8eDCBnwXnsN-whaBvcOu0qb9DCyo2BjqR8fBmtxhbOVDNUofPtbebkgmVFnwFUyacZxLBk-                                                                                    |
|                | l8AHqQnQOK5wkIUWabsCYhZcA7r800jH9ZysLHRmW5pTRAc_n6CtSvgXoShqzL0L1AlxA5omgac2gXkrulBvJDpnKJhXSCnYkWsJyWtDTDnwTTt8IZvuec_Rh9C0b4bAFLNCmwSw2KRtJTepQcsHtL9vXRZOcS2WJcgg3J_DxNGIcxAUacAcTc8CX7MB5c_DSMOD5lrLPk93Sr-                           |
|                | 0XzODPib4ar4C8Kzs4fiYki6BWnwWHbcmZMtXClnTZIu3iLhKDG_GNAp9dhMrRUNFX3I8HRfWzMmp7EComQGkkE0vlJ8LRavWPRspKTx92ubwkatYrfKlyVoS2uBsc8jBum94hsquERInVSoUrKwlnyNfn7ecSr2W_1M4LWo2GU8joEYBBUM6oHomV_Sl0yIdXpEofd-                                  |
|                | kYWWP0PO7CY9KgNrJU7Iqyn4ZgKBWhH6qfL-xEmGndgE2Xt4ZKPKdWWquXXhXtz7fz51LmpQwGvZR4-qFYa9B6XEC0odvQVW0xzZl36C6nTREP4TuOodos3iMUy89iKDzk52JgLUDkU-k-MtROzdA0BwNqlLKzwslOFuaXe7P1Khf7oS7TjgG1vMdr9t_K2dacMdNhJEtwb-                              |
|                | lTlFr6JEAbsd852EM45rUegG3_PKqxv5XgKczCrcAsJhTRW-RhxyWk_bpSS1skJGUJdMEhEvQss0ilZfnOw3TunKZXk66c-2LG9EG4e49B15nUQ6H6V-8G-POSBg0qpDVeaniIxmKSiExrQEzrh7lfR-                                                                                  |
|                | avvGst02FuqEzsg82hojgpMbDSW643JYjGRgcSFrcFvydsYVNCPg8BJatGnXd4tqPeniDXJOOIg5qgj3_ful7PeMY08mjHfPHaiaI3xLszmJGLP1pCz-IPliaogi77ZNegvU7Z5_FtQE56J9pWF2NUZRyP92OveEKfTpQbPSLSiLUofxTq7oYoWVZfZnEOaewV0z8A-                                   |
|                | b7VrG267kgWS7mboQb0sIeegpzQgA3HMX0wG8FCuBxqvmxyIWUf7M1rPa6QcTfv8ZBFCs5lbxjs8tNw86pCKELa1FfuIwuVu9yGPHDrAoUWH_Lq93SAl9VYEJbvVo05OxA8kxLU3qFxLP0A6DBGxoOhIDznrY5WzMLJ6K53PI1D8-ESYhhIukSHlgClcopMk0ywsF1URyF8HO4TaIf4N0-                    |
|                | HJFq95pZArLlmtBr6WmXXrpkDuH-ASGVnObTMLp7oQuJY1kQNmktlstuo54MW5FiLvL0pod2Og0k46_UofpA3mkYGM2dE6DtajACPpOQl7DR7NFFtY-9MGzvf8s3OiOWkq7I3mZnag2fYfMERcly5_a0ipIGoTcQkNCmIn9seC8x-                                                             |
|                | 3odxGHUwIilhr7mnuXNKvHzuVvmXrYiBVnzgwuajZ37VYKY4y9K90BeIWPEF63vZRwlXuRoDTP9WGwbojv2PJkPHHn8Tg=='",                                                                                                                                        |
|                |     "auth_url": "https://192.168.56.10:6443",                                                                                                                                                                                             |
|                |     "username": "None",                                                                                                                                                                                                                   |
|                |     "key_type": "barbican_key",                                                                                                                                                                                                           |
|                |     "secret_uuid": "***"                                                                                                                                                                                                                  |
|                | }                                                                                                                                                                                                                                         |
| auth_url       | https://192.168.56.10:6443                                                                                                                                                                                                                |
| created_at     | 2023-11-15 06:40:25.544685                                                                                                                                                                                                                |
| description    |                                                                                                                                                                                                                                           |
| extra          |                                                                                                                                                                                                                                           |
| id             | 290ae639-5b47-42b6-b1b0-c1623f6d856a                                                                                                                                                                                                      |
| is_default     | True                                                                                                                                                                                                                                      |
| name           | test-vim-k8s                                                                                                                                                                                                                              |
| placement_attr | {                                                                                                                                                                                                                                         |
|                |     "regions": [                                                                                                                                                                                                                          |
|                |         "default",                                                                                                                                                                                                                        |
|                |         "kube-node-lease",                                                                                                                                                                                                                |
|                |         "kube-public",                                                                                                                                                                                                                    |
|                |         "kube-system"                                                                                                                                                                                                                     |
|                |     ]                                                                                                                                                                                                                                     |
|                | }                                                                                                                                                                                                                                         |
| project_id     | ebbc6cf1a03d49918c8e408535d87268                                                                                                                                                                                                          |
| status         | ACTIVE                                                                                                                                                                                                                                    |
| type           | kubernetes                                                                                                                                                                                                                                |
| updated_at     | None                                                                                                                                                                                                                                      |
| vim_project    | {                                                                                                                                                                                                                                         |
|                |     "name": "admin"                                                                                                                                                                                                                       |
|                | }                                                                                                                                                                                                                                         |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

我们还可以通过 openstack vim list 命令检查 VIM 的状态是否为 ACTIVE。

$ openstack vim list
+--------------------------------------+--------------+----------------------------------+------------+------------+--------+
| ID                                   | Name         | Tenant_id                        | Type       | Is Default | Status |
+--------------------------------------+--------------+----------------------------------+------------+------------+--------+
| 290ae639-5b47-42b6-b1b0-c1623f6d856a | test-vim-k8s | ebbc6cf1a03d49918c8e408535d87268 | kubernetes | True       | ACTIVE |
+--------------------------------------+--------------+----------------------------------+------------+------------+--------+

准备 VNF 包

例如,您可以按如下方式创建 VNF 包。 在本文档中,TACKER_ROOT 是服务器上 tacker 仓库的根目录。

$ cd TACKER_ROOT/samples/tests/functional/sol_kubernetes_v2/test_instantiate_cnf_resources
$ python3 pkggen.py
$ ll
...
drwxr-xr-x  6 stack stack  4096 Nov  5 23:46 contents/
-rw-r--r--  1 stack stack  3921 Nov  5 23:46 pkggen.py
-rw-rw-r--  1 stack stack 28783 Nov 15 07:15 test_instantiate_cnf_resources.zip
...

注意

此工具需要一些 Tacker 模块,因此需要在安装了 Tacker 的环境中运行它,例如使用 devstack 的 python 虚拟环境。如果已在 python 虚拟环境中安装了 Tacker,请在使用该工具之前激活它,如下所示。

$ source /opt/stack/data/venv/bin/activate
(venv) $ python3 pkggen.py

完成上述操作后,您将拥有示例 VNF 包 test_instantiate_cnf_resources.zip

注意

如果存在与正在生成的 zip 文件同名的文件,该工具将失败。 再次运行该工具以生成 zip 文件时,请删除或重命名旧的 zip 文件。

您也可以按照以下步骤手动创建 VNF 包。

1. 创建 VNF 包的目录

TOSCA YAML CSAR 文件是使用 ZIP 文件格式的归档文件,其结构符合 TOSCA Simple Profile YAML v1.2 规范。以下是构建 VNF 包 CSAR 目录的示例

$ mkdir -p deployment/{TOSCA-Metadata,Definitions,Files/kubernetes}

2. 创建 Kubernetes 对象文件

CSAR VNF 包应具有一个对象文件,该文件定义要部署的 Kubernetes 资源。文件名应具有“.yaml”扩展名。根据不同 yaml 文件的内容,可以创建不同的 Kubernetes api 资源。

注意

请参阅 Kubernetes API 资源,以获取每个资源的示例 yaml 文件。

以下是 deployment 资源的简单示例。

$ cat ./deployment/Files/kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vdu1
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "200Mi"
          requests:
            memory: "100Mi"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          protocol: TCP
  strategy:
    type: RollingUpdate

注意

metadata.name 文件应与部署 flavor 定义文件中的相应 VDU 的 properties.name 相同。在本过程的示例中,metadata.name 与 sample_cnf_df_simple.yaml 文件中的 topology_template.node_templates.VDU1.properties.name 相同。

3. 创建 TOSCA.meta 文件

TOSCA.meta 文件包含 TOSCA.meta 文件、CSAR、Definitions 文件和 artifact 文件的版本信息。TOSCA.meta 文件需要 artifact 文件的名称、content-Type、加密方法和哈希值。

$ cat ./deployment/TOSCA-Metadata/TOSCA.meta
TOSCA-Meta-File-Version: 1.0
Created-by: dummy_user
CSAR-Version: 1.1
Entry-Definitions: Definitions/sample_cnf_top.vnfd.yaml

Name: Files/kubernetes/deployment.yaml
Content-Type: test-data
Algorithm: SHA-256
Hash: 36cab1efa2e3e0fb983816010450dbccf491ae905ba4012778a351cc73b420a7

4. 下载 ETSI 定义文件

下载官方文档。ETSI GS NFV-SOL 001 [i.4] 规定了基于 TOSCA 规范的 VNFD 的结构和格式。

$ cd deployment/Definitions
$ wget https://forge.etsi.org/rep/nfv/SOL001/raw/v2.6.1/etsi_nfv_sol001_common_types.yaml
$ wget https://forge.etsi.org/rep/nfv/SOL001/raw/v2.6.1/etsi_nfv_sol001_vnfd_types.yaml

5. 创建 VNFD

如何创建由多个部署 flavor 组成的 VNFD 在基于 ETSI NFV-SOL001 的 VNF 描述符 (VNFD) 中有描述,请参阅 基于 ETSI NFV-SOL001 的 VNF 描述符 (VNFD)

VNFD 不会包含任何 Kubernetes 资源信息,例如 VDU、连接点、虚拟链路,因为 CNF 的所有必需组件都将在 Kubernetes 资源文件中指定。

以下是包含 VNF 定义的 VNFD 文件的示例。

$ cat sample_cnf_top.vnfd.yaml
tosca_definitions_version: tosca_simple_yaml_1_2

description: Sample VNF

imports:
  - etsi_nfv_sol001_common_types.yaml
  - etsi_nfv_sol001_vnfd_types.yaml
  - sample_cnf_types.yaml
  - sample_cnf_df_simple.yaml

topology_template:
  inputs:
    selected_flavour:
      type: string
      description: VNF deployment flavour selected by the consumer. It is provided in the API

  node_templates:
    VNF:
      type: company.provider.VNF
      properties:
        flavour_id: { get_input: selected_flavour }
        descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d7000000
        provider: Company
        product_name: Sample VNF
        software_version: '1.0'
        descriptor_version: '1.0'
        vnfm_info:
          - Tacker
      requirements:
        #- virtual_link_external # mapped in lower-level templates
        #- virtual_link_internal # mapped in lower-level templates

sample_cnf_types.yaml 文件定义了 VNF 的参数类型和默认值。

$ cat sample_cnf_types.yaml
tosca_definitions_version: tosca_simple_yaml_1_2

description: VNF type definition

imports:
  - etsi_nfv_sol001_common_types.yaml
  - etsi_nfv_sol001_vnfd_types.yaml

node_types:
  company.provider.VNF:
    derived_from: tosca.nodes.nfv.VNF
    properties:
      descriptor_id:
        type: string
        constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d7000000 ] ]
        default: b1bb0ce7-ebca-4fa7-95ed-4840d7000000
      descriptor_version:
        type: string
        constraints: [ valid_values: [ '1.0' ] ]
        default: '1.0'
      provider:
        type: string
        constraints: [ valid_values: [ 'Company' ] ]
        default: 'Company'
      product_name:
        type: string
        constraints: [ valid_values: [ 'Sample VNF' ] ]
        default: 'Sample VNF'
      software_version:
        type: string
        constraints: [ valid_values: [ '1.0' ] ]
        default: '1.0'
      vnfm_info:
        type: list
        entry_schema:
          type: string
          constraints: [ valid_values: [ Tacker ] ]
        default: [ Tacker ]
      flavour_id:
        type: string
        constraints: [ valid_values: [ simple,complex ] ]
        default: simple
      flavour_description:
        type: string
        default: ""
    requirements:
      - virtual_link_external:
          capability: tosca.capabilities.nfv.VirtualLinkable
      - virtual_link_internal:
          capability: tosca.capabilities.nfv.VirtualLinkable
    interfaces:
      Vnflcm:
        type: tosca.interfaces.nfv.Vnflcm

sample_cnf_df_simple.yaml 定义了 VNF 输入的参数类型。

$ cat sample_cnf_df_simple.yaml
tosca_definitions_version: tosca_simple_yaml_1_2

description: Simple deployment flavour for Sample VNF

imports:
  - etsi_nfv_sol001_common_types.yaml
  - etsi_nfv_sol001_vnfd_types.yaml
  - sample_cnf_types.yaml

topology_template:
  inputs:
    descriptor_id:
      type: string
    descriptor_version:
      type: string
    provider:
      type: string
    product_name:
      type: string
    software_version:
      type: string
    vnfm_info:
      type: list
      entry_schema:
        type: string
    flavour_id:
      type: string
    flavour_description:
      type: string

  substitution_mappings:
    node_type: company.provider.VNF
    properties:
      flavour_id: simple
    requirements:
      virtual_link_external: []

  node_templates:
    VNF:
      type: company.provider.VNF
      properties:
        flavour_description: A simple flavour

    VDU1:
      type: tosca.nodes.nfv.Vdu.Compute
      properties:
        name: vdu1
        description: VDU1 compute node
        vdu_profile:
          min_number_of_instances: 1
          max_number_of_instances: 3

  policies:
    - scaling_aspects:
        type: tosca.policies.nfv.ScalingAspects
        properties:
          aspects:
            vdu1_aspect:
              name: vdu1_aspect
              description: vdu1 scaling aspect
              max_scale_level: 2
              step_deltas:
                - delta_1

    - VDU1_initial_delta:
        type: tosca.policies.nfv.VduInitialDelta
        properties:
          initial_delta:
            number_of_instances: 2
        targets: [ VDU1 ]

    - VDU1_scaling_aspect_deltas:
        type: tosca.policies.nfv.VduScalingAspectDeltas
        properties:
          aspect: vdu1_aspect
          deltas:
            delta_1:
              number_of_instances: 1
        targets: [ VDU1 ]

    - instantiation_levels:
        type: tosca.policies.nfv.InstantiationLevels
        properties:
          levels:
            instantiation_level_1:
              description: Smallest size
              scale_info:
                vdu1_aspect:
                  scale_level: 1
            instantiation_level_2:
              description: Largest size
              scale_info:
                vdu1_aspect:
                  scale_level: 2
          default_level: instantiation_level_1

    - VDU1_instantiation_levels:
        type: tosca.policies.nfv.VduInstantiationLevels
        properties:
          levels:
            instantiation_level_1:
              number_of_instances: 2
            instantiation_level_2:
              number_of_instances: 3
        targets: [ VDU1 ]

注意

VDU1.properties.name 应与在 Kubernetes 对象文件中定义的 metadata.name 相同。因此,VDU1.properties.name 应遵循 Kubernetes 资源名称的命名规则。有关命名规则的详细信息,请参阅 Kubernetes 文档 DNS 子域名

6. 压缩 VNF 包

CSAR 包应压缩为 ZIP 文件进行上传。以下命令是压缩 VNF 包的示例

$ cd -
$ cd ./deployment
$ zip deployment.zip -r Definitions/ Files/ TOSCA-Metadata/
adding: Definitions/ (stored 0%)
adding: Definitions/sample_cnf_top.vnfd.yaml (deflated 54%)
adding: Definitions/sample_cnf_df_simple.yaml (deflated 76%)
adding: Definitions/etsi_nfv_sol001_vnfd_types.yaml (deflated 83%)
adding: Definitions/etsi_nfv_sol001_common_types.yaml (deflated 76%)
adding: Definitions/sample_cnf_types.yaml (deflated 70%)
adding: Files/ (stored 0%)
adding: Files/kubernetes/ (stored 0%)
adding: Files/kubernetes/deployment.yaml (deflated 50%)
adding: TOSCA-Metadata/ (stored 0%)
adding: TOSCA-Metadata/TOSCA.meta (deflated 23%)
$ ls deployment
deployment.zip    Definitions    Files    TOSCA-Metadata

创建并上传 VNF 包

我们需要在 tacker 中创建一个空的 VNF 包对象,并上传之前章节中创建的压缩 VNF 包。

1. 创建 VNF 包

可以使用命令 openstack vnf package create 创建一个空的 vnf 包。成功创建 VNF 包后,将返回一些信息,包括 ID、链接、Onboarding 状态、Operational 状态和 Usage 状态。当 Onboarding 状态为 CREATED,Operational 状态为 DISABLED,Usage 状态为 NOT_IN_USE 时,表示创建成功。

$ openstack vnf package create
+-------------------+-------------------------------------------------------------------------------------------------+
| Field             | Value                                                                                           |
+-------------------+-------------------------------------------------------------------------------------------------+
| ID                | ea4d29b3-bf2c-437c-a4a2-69b37208d21a                                                            |
| Links             | {                                                                                               |
|                   |     "self": {                                                                                   |
|                   |         "href": "/vnfpkgm/v1/vnf_packages/ea4d29b3-bf2c-437c-a4a2-69b37208d21a"                 |
|                   |     },                                                                                          |
|                   |     "packageContent": {                                                                         |
|                   |         "href": "/vnfpkgm/v1/vnf_packages/ea4d29b3-bf2c-437c-a4a2-69b37208d21a/package_content" |
|                   |     }                                                                                           |
|                   | }                                                                                               |
| Onboarding State  | CREATED                                                                                         |
| Operational State | DISABLED                                                                                        |
| Usage State       | NOT_IN_USE                                                                                      |
| User Defined Data | {}                                                                                              |
+-------------------+-------------------------------------------------------------------------------------------------+

2. 上传 VNF 包

通过运行以下命令将上述创建的 VNF 包上传到 VNF 包:openstack vnf package upload --path <vnf 包路径> <vnf 包 ID>。以下是上传 VNF 包的示例

$ openstack vnf package upload --path deployment.zip VNF_PACKAGE_ID
Upload request for VNF package ea4d29b3-bf2c-437c-a4a2-69b37208d21a has been accepted.

3. 检查 VNF 包状态

通过 openstack vnf package list 命令检查 VNF 包状态。找到 id 与创建的 vnf 包 id 相同的项目,当 Onboarding 状态为 ONBOARDED、Operational 状态为 ENABLED、Usage 状态为 NOT_IN_USE 时,表示 VNF 包已成功上传。

$ openstack vnf package list
+--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
| Id                                   | Vnf Product Name | Onboarding State | Usage State | Operational State | Links                                                                                           |
+--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
| ea4d29b3-bf2c-437c-a4a2-69b37208d21a | Sample VNF       | ONBOARDED        | NOT_IN_USE  | ENABLED           | {                                                                                               |
|                                      |                  |                  |             |                   |     "self": {                                                                                   |
|                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/ea4d29b3-bf2c-437c-a4a2-69b37208d21a"                 |
|                                      |                  |                  |             |                   |     },                                                                                          |
|                                      |                  |                  |             |                   |     "packageContent": {                                                                         |
|                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/ea4d29b3-bf2c-437c-a4a2-69b37208d21a/package_content" |
|                                      |                  |                  |             |                   |     }                                                                                           |
|                                      |                  |                  |             |                   | }                                                                                               |
+--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+

创建 VNF

1. 获取 VNFD ID

可以通过 openstack vnf package show <VNF 包 ID> 命令找到上传的 vnf 包的 VNFD ID。以下是检查 VNFD-ID 值的示例

$ openstack vnf package show VNF_PACKAGE_ID
+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| Field                | Value                                                                                                                                           |
+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| Additional Artifacts | [                                                                                                                                               |
|                      |     {                                                                                                                                           |
|                      |         "artifactPath": "Files/kubernetes/deployment.yaml",                                                                                     |
|                      |         "checksum": {                                                                                                                           |
|                      |             "algorithm": "SHA-256",                                                                                                             |
|                      |             "hash": "36cab1efa2e3e0fb983816010450dbccf491ae905ba4012778a351cc73b420a7"                                                          |
|                      |         },                                                                                                                                      |
|                      |         "metadata": {}                                                                                                                          |
|                      |     }                                                                                                                                           |
|                      | ]                                                                                                                                               |
| Checksum             | {                                                                                                                                               |
|                      |     "hash": "3ab4ea9ee8c125b52dd1fd1cb656a17668173b18a9f1d7fe18146e310e940851cddc2a07a9d081cf8a2a239b4d3b8025d4d328951b87e535d3f8fc788f15d6ea", |
|                      |     "algorithm": "sha512"                                                                                                                       |
|                      | }                                                                                                                                               |
| ID                   | ea4d29b3-bf2c-437c-a4a2-69b37208d21a                                                                                                            |
| Links                | {                                                                                                                                               |
|                      |     "self": {                                                                                                                                   |
|                      |         "href": "/vnfpkgm/v1/vnf_packages/ea4d29b3-bf2c-437c-a4a2-69b37208d21a"                                                                 |
|                      |     },                                                                                                                                          |
|                      |     "packageContent": {                                                                                                                         |
|                      |         "href": "/vnfpkgm/v1/vnf_packages/ea4d29b3-bf2c-437c-a4a2-69b37208d21a/package_content"                                                 |
|                      |     }                                                                                                                                           |
|                      | }                                                                                                                                               |
| Onboarding State     | ONBOARDED                                                                                                                                       |
| Operational State    | ENABLED                                                                                                                                         |
| Software Images      |                                                                                                                                                 |
| Usage State          | NOT_IN_USE                                                                                                                                      |
| User Defined Data    | {}                                                                                                                                              |
| VNF Product Name     | Sample VNF                                                                                                                                      |
| VNF Provider         | Company                                                                                                                                         |
| VNF Software Version | 1.0                                                                                                                                             |
| VNFD ID              | b1bb0ce7-ebca-4fa7-95ed-4840d7000000                                                                                                            |
| VNFD Version         | 1.0                                                                                                                                             |
+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+

2. 执行创建 VNF 命令

我们可以通过运行 openstack vnflcm create <VNFD ID> 创建 VNF。执行该命令后,生成的 ID 是 VNF 实例 ID

$ openstack vnflcm create VNFD_ID --os-tacker-api-version 2
+-----------------------------+------------------------------------------------------------------------------------------------------------------+
| Field                       | Value                                                                                                            |
+-----------------------------+------------------------------------------------------------------------------------------------------------------+
| ID                          | 431b94b5-d7ba-4d1c-aa26-ecec65d7ee53                                                                             |
| Instantiation State         | NOT_INSTANTIATED                                                                                                 |
| Links                       | {                                                                                                                |
|                             |     "self": {                                                                                                    |
|                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/431b94b5-d7ba-4d1c-aa26-ecec65d7ee53"             |
|                             |     },                                                                                                           |
|                             |     "instantiate": {                                                                                             |
|                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/431b94b5-d7ba-4d1c-aa26-ecec65d7ee53/instantiate" |
|                             |     }                                                                                                            |
|                             | }                                                                                                                |
| VNF Configurable Properties |                                                                                                                  |
| VNF Instance Description    |                                                                                                                  |
| VNF Instance Name           |                                                                                                                  |
| VNF Product Name            | Sample VNF                                                                                                       |
| VNF Provider                | Company                                                                                                          |
| VNF Software Version        | 1.0                                                                                                              |
| VNFD ID                     | b1bb0ce7-ebca-4fa7-95ed-4840d7000000                                                                             |
| VNFD Version                | 1.0                                                                                                              |
+-----------------------------+------------------------------------------------------------------------------------------------------------------+

实例化 VNF

1. 设置请求参数文件中的值

获取目标 VIM 的 ID。

$ openstack vim list
+--------------------------------------+--------------+----------------------------------+------------+------------+--------+
| ID                                   | Name         | Tenant_id                        | Type       | Is Default | Status |
+--------------------------------------+--------------+----------------------------------+------------+------------+--------+
| 290ae639-5b47-42b6-b1b0-c1623f6d856a | test-vim-k8s | ebbc6cf1a03d49918c8e408535d87268 | kubernetes | True       | ACTIVE |
+--------------------------------------+--------------+----------------------------------+------------+------------+--------+

实例化容器化 VNF 时,应提供包含 Kubernetes 资源定义文件路径和 Kubernetes VIM 信息的 json 文件。以下是 json 文件的示例

additionalParams 包含 Kubernetes 资源定义文件的路径,请注意 lcm-kubernetes-def-files 应该是一个列表。用户还可以指定资源需要部署的 namespace

注意

VNF 实例化的 namespace 由以下优先级确定:

  1. 如果在实例化请求的 additionalParams 中指定了 namespace,则使用指定的 namespace

  2. 如果未通过第 1 步中描述的方法指定 namespace,则使用在 2. 创建 Kubernetes 对象文件 中定义的 metadata 下的 namespace

  3. 如果未通过第 2 步中描述的方法指定 namespace,则使用默认命名空间,即 default

警告

如果通过第 2 节中描述的方法在 manifest 中指定了多个命名空间,则 VNF 实例化将失败。

vimConnectionInfo 包含可以自主定义的 id 值、vimId 和 vimType。

$ cat ./instance_kubernetes.json
{
  "flavourId": "simple",
  "vimConnectionInfo": {
    "vim1": {
      "vimId": "290ae639-5b47-42b6-b1b0-c1623f6d856a",
      "vimType": "ETSINFV.KUBERNETES.V_1"
    }
  },
  "additionalParams": {
    "lcm-kubernetes-def-files": [
      "Files/kubernetes/deployment.yaml"
    ]
  }
}

注意

此操作可以指定 VNF 实例的 vimConnectionInfo。即使此操作指定与一个 VNF 实例关联的多个 vimConnectionInfo,也只会使用其中一个用于生命周期管理操作。

注意

资源按照 lcm-kubernetes-def-files 列表的顺序创建。因此,要求用户以正确的顺序指定 lcm-kubernetes-def-files 列表。

2. 执行实例化命令

执行以下 CLI 命令来实例化 VNF 实例。

$ openstack vnflcm instantiate VNF_INSTANCE_ID \
  instance_kubernetes.json --os-tacker-api-version 2
Instantiate request for VNF Instance 431b94b5-d7ba-4d1c-aa26-ecec65d7ee53 has been accepted.

VNF_INSTANCE_ID 是执行 create 命令后生成的 ID。可以在 2. 执行创建 VNF 命令 章中找到它。

3. 检查实例化状态

我们可以通过运行以下命令检查实例化状态。当实例化状态为 INSTANTIATED 时,表示实例化成功。

$ openstack vnflcm show VNF_INSTANCE_ID \
  -c 'Instantiation State' --os-tacker-api-version 2
+---------------------+--------------+
| Field               | Value        |
+---------------------+--------------+
| Instantiation State | INSTANTIATED |
+---------------------+--------------+

4. 检查 Kubernetes 中的部署

要测试容器化 VNF 是否正在目标 Kubernetes VIM 环境中运行,我们可以通过运行以下命令进行检查。当 READY 为 2/2 时,表示部署创建成功。

$ kubectl get deploy
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
vdu1   2/2     2            2           7m35s

如果要在默认命名空间中检查资源是否部署,可以在命令行中追加 -A

$ kubectl get deploy -A
NAMESPACE     NAME               READY   UP-TO-DATE   AVAILABLE   AGE
default       vdu1               2/2     2            2           8m46s
kube-system   coredns            2/2     2            2           28h

注意

如果在实例化期间为命名空间指定了除 default 之外的其他值,则部署的资源将在相应的命名空间中实例化。

终止 VNF

1. 执行终止命令

执行以下 CLI 命令以终止 VNF 实例。

$ openstack vnflcm terminate VNF_INSTANCE_ID --os-tacker-api-version 2
Terminate request for VNF Instance '431b94b5-d7ba-4d1c-aa26-ecec65d7ee53' has been accepted.

2. 检查实例化状态

我们可以通过运行以下命令检查实例化状态。当实例化状态为 NOT_INSTANTIATED 时,表示终止成功。

$ openstack vnflcm show VNF_INSTANCE_ID \
  -c 'Instantiation State' --os-tacker-api-version 2
+---------------------+------------------+
| Field               | Value            |
+---------------------+------------------+
| Instantiation State | NOT_INSTANTIATED |
+---------------------+------------------+

删除 VNF 标识符

1. 执行删除命令

执行以下 CLI 命令以删除 VNF 实例。

$ openstack vnflcm delete VNF_INSTANCE_ID --os-tacker-api-version 2
Vnf instance '431b94b5-d7ba-4d1c-aa26-ecec65d7ee53' is deleted successfully

2. 检查状态

执行以下 CLI 命令并确认 VNF 实例删除成功。

  • 确认 VNF 包的“Usage State”为“NOT_IN_USE”。

  • 确认未找到 VNF 实例。

$ openstack vnf package show VNF_PACKAGE_ID -c 'Usage State'
+-------------+------------+
| Field       | Value      |
+-------------+------------+
| Usage State | NOT_IN_USE |
+-------------+------------+
$ openstack vnflcm show VNF_INSTANCE_ID --os-tacker-api-version 2
VnfInstance 431b94b5-d7ba-4d1c-aa26-ecec65d7ee53 not found.