如何使用 Ansible Driver 的 Mgmt Driver

概述

1. Ansible Mgmt Driver 介绍

管理驱动程序使用户能够在 VNF 生命周期管理操作之前和/或之后配置其 VNF。用户可以通过实现自己的管理驱动程序来自定义管理驱动程序的逻辑,这些自定义由 NFV-SOL001 v2.6.1 中的“接口”定义指定。

在当前的社区代码中,没有使用 Ansible 进行 VNF 配置的 Mgmt Driver。Ansible 是一种通用的配置管理工具,如果支持,将使更多用户受益。

本用户指南旨在向用户提供使用 Ansible 作为 Mgmt Driver 所需的信息和步骤。

+------------------------------------------+
| Tacker                                   |
| +--------------------------------------+ |
| |     Tacker-Server                    | |
| +--------------------------------------+ |
|                                          |
| +--------------------------------------+ |
| |   Tacker-Conductor                   | |
| |                                      | |
| | +----------------------------------+ | |
| | |         OpenStack Driver         | | |
| | +----------------------------------+ | |
| | +----------------------------------+ | |
| | | Ansible Driver                   | | |
| | |                                  | | |
| | |  +------------------+            | | |
| | |  |  Config Parser   |            | | |     1. Get VDU Resources
| | |  +--------|---------+            ------------------------------------
| | |           |                      | | |                              |
| | |           |2. VDU/Config/Command | | |                              |
| | |           |   Order Processing   | | |                              |
| | |           |                      | | |                              |
| | |  +--------V---------+            | | |                              |
| | |  |     Executor     |            | | |                 +------------|-------------+
| | |  +--------|---------+            | | |                 | Heat       |             |
| | +-----------|----------------------+ | |                 | +----------v-----------+ |
| +-------------|------------------------+ |                 | |    OpenStack Heat    | |
|               |                          |                 | +----------------------+ |
+---------------|--------------------------+                 +------------|-------------+
                |                                                         |
                |3. Execute Playbook                                      |
                |                                                         |
                |                                                         |
   +------------V-------------+                                           |
   |VNF                       |                                           |
   |     +--------------+     |                                           |
   |     |     VDU1     |     |                                           |
   |     +--------------+     |                                           |
   |                          <--------------------------------------------
   |     +--------------+     |
   |     |     VDU2     |     |
   |     +--------------+     |
   +--------------------------+

2. 用例

  • 动态管理地址:IP 地址通过 DHCP 生成。

  • 静态管理地址:指定静态 IP 地址。

1. 动态管理地址的 VDU 配置

helloworld3_df_default.yaml 中,dhcp_enabled 值应为 true

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
  - helloworld3_types.yaml
topology_template:
...
    internalNW_1:
      type: tosca.nodes.nfv.VnfVirtualLink
      properties:
      ...
          virtual_link_protocol_data:
            - associated_layer_protocol: ipv4
              l2_protocol_data:
                network_type: vlan
              l3_protocol_data:
                ip_version: ipv4
                cidr: '192.168.0.0/24'
                dhcp_enabled: true

2. 静态管理地址的 VDU 配置

helloworld3_df_default.yaml 中,不应存在 dhcp_enabled

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
  - helloworld3_types.yaml
topology_template:
...
    internalNW_1:
      type: tosca.nodes.nfv.VnfVirtualLink
      properties:
      ...
          virtual_link_protocol_data:
            - associated_layer_protocol: ipv4
              l3_protocol_data:
                ip_version: ipv4
                cidr: '192.168.0.0/24'

BaseHOT 文件将从请求体获取 IP 地址。这是通过定义管理 IP 参数并在资源的属性下获取其值来实现的。

parameters:
  nfv:
    type: json

  mgmt_ip_vm0_0:
    type: string
    label: Management Network IPv4 Address
    description: Management Network IPv4 Address
  mgmt_ip_vm1_0:
    type: string
    label: Management Network IPv4 Address
    description: Management Network IPv4 Address

resources:
  VDU1:
    type: OS::Heat::AutoScalingGroup
    properties:
      min_size: 1
      max_size: 3
      desired_capacity: 1
      resource:
        type: VDU1.yaml
        properties:
          flavor: { get_param: [ nfv, VDU, VDU1, flavor ] }
          image: { get_param: [ nfv, VDU, VirtualStorage, image ] }
          name: vdu1
          testnet: { get_resource: internalNW_1 }
          mgmt_ip_a: { get_param: mgmt_ip_vm0_0 }
          mgmt_ip_b: { get_param: mgmt_ip_vm1_0 }

上面的示例显示了 BaseHOT 文件使用 mgmt_ip_vm0_0mgmt_ip_vm1_0 参数从请求体获取静态 IP 地址,并分别将其分配给 mgmt_ip_amgmt_ip_b

嵌套的 BaseHot 文件将使用在 BaseHOT 文件中获取的值来设置资源的管理 IP 地址。

parameters:
  flavor:
    type: string
  image:
    type: string
  name:
    type: string
  testnet:
    type: string
  mgmt_ip_a:
    type: string
    label: Management Network IPv4 Address
    description: Management Network IPv4 Address
  mgmt_ip_b:
    type: string
    label: Management Network IPv4 Address
    description: Management Network IPv4 Address

resources:
  VDU1:
    type: OS::Nova::Server
    properties:
      ...
  CP1:
    type: OS::Neutron::Port
    properties:
      network: { get_param: testnet }
      fixed_ips:
      - ip_address: { get_param:  mgmt_ip_a }

  CP2:
    type: OS::Neutron::Port
    properties:
      network: { get_param: testnet }
      fixed_ips:
      - ip_address: { get_param:  mgmt_ip_b }
  ...

上面的示例显示了 BaseHOT 的嵌套文件,其中从 BaseHOT 文件获取的 IP 地址值被分配给端口。

Instantiation 请求参数的 additionalParams 下设置静态 IP 地址。

{
    "flavourId": "default",
    ...
    "additionalParams": {
        "lcm-operation-user-data": "./UserData/lcm_user_data.py",
        "lcm-operation-user-data-class": "SampleUserData",
        "mgmt_ip_vm0_0": "10.1.1.20",
        "mgmt_ip_vm1_0": "10.1.1.24"
    }
}

排序选项

1. VDU 顺序

VDU 的顺序基于 config.yaml 文件中 config 之后的 order 关键字。

示例

vdus:
  VDU1:
    config:
      order: 1
      vm_app_config:
        ...

  VDU2:
    config:
      order: 0
      vm_app_config:
        ...

在上面的示例中,由于 order 的值,VDU2VDU1 之前处理。

注意

如果它们具有相同的顺序,则将随机执行它们。

2. 命令顺序

如果您在一个配置中要执行多个命令,则命令顺序是必要的。

示例

vdus:
  VDU1:
    config:
      order: 1
      vm_app_config:
        type: ansible
        instantiation:
          - path: _VAR_vnf_package_path/Scripts/default/sample_start-1.yaml
            params:
              ansible_password: password
            order: 1
          - path: _VAR_vnf_package_path/Scripts/default/sample_start-2.yaml
            params:
              ansible_password: password
            order: 2
          - path: _VAR_vnf_package_path/Scripts/default/sample_start-3.yaml
            params:
              ansible_password: password
            order: 0
在上面的示例中,命令执行的顺序如下
  • Scripts/default/sample_start-3.yaml

  • Scripts/default/sample_start-1.yaml

  • Scripts/default/sample_start-2.yaml

这是由于每个命令的 order 值。

Ansible Driver 用法

如果 Ansible 尚未安装,请参阅 Ansible 安装指南

1. 复制 Ansible 文件夹

首先,将存储在 tacker/samples/mgmt_driver/ansible 中的示例脚本复制到 tacker/tacker/vnfm/mgmt_drivers 目录。

$ cp -pfr /opt/stack/tacker/samples/mgmt_driver/ansible /opt/stack/tacker/tacker/vnfm/mgmt_drivers/

环境配置

1. 设置 setup.cfg

您需要在 tacker 的操作环境中注册 ansible_driver

$ vi /opt/stack/tacker/setup.cfg
...
tacker.tacker.mgmt.drivers =
noop = tacker.vnfm.mgmt_drivers.noop:VnfMgmtNoop
vnflcm_noop = tacker.vnfm.mgmt_drivers.vnflcm_noop:VnflcmMgmtNoop
ansible_driver = tacker.vnfm.mgmt_drivers.ansible.ansible:DeviceMgmtAnsible

2. 设置 tacker.conf

然后找到 tacker.conf 中的 vnflcm_mgmt_driver 字段。将步骤 2 中定义的 ansible_driver 添加到其中,并用逗号分隔。

$ vi /etc/tacker/tacker.conf
...
[tacker]
...
vnflcm_mgmt_driver = vnflcm_noop,ansible_driver
...

这是高级配置的示例(可选)。

要允许用户选择默认版本以外的 Ansible 版本,请在 venv_path 中定义虚拟环境路径和标识符的映射。

要强制执行特定的 Ansible 执行选项,请在 env_vars 中定义环境变量和值。在这里,您可以使用标记来替换它们为特定值。

$ vi /etc/tacker/tacker.conf
...
[ansible]
venv_path = ansible-2.9:/opt/my-envs/2.9
venv_path = ansible-2.10:/opt/my-envs/2.10
venv_path = ansible-2.11:/opt/my-envs/2.11
env_vars = ANSIBLE_CALLBACK_PLUGINS:/opt/callback_plugins
env_vars = ANSIBLE_STDOUT_CALLBACK:custom_callback_plugin_for_tacker
env_vars = ANSIBLE_LOG_PATH:/var/log/tacker/ansible_driver/{tenant_id}_{vnflcm_id}_{lcm_name}_{vdu_name}.log
...
env_vars 中可用的标记

标记

含义

示例转换

{tenant_id}

调用 playbook 的租户 ID

0000000000000000000000000000000

{vnflcm_id}

调用 playbook 的 VNFLCM ID

00000000-0000-0000-0000-000000000000

{lcm_name}

LCM 操作名称

instantiate, termination, healing, scale-in, scale-out

{timestamp}

Playbook 执行时间(Unix 时间戳)

1721128301

{date}

Playbook 执行日期(yyyy-MM-dd)

2024-06-22

{vdu_name}

虚拟部署单元名称

VDU_1

3. 更新 tacker.egg-info

在上述两个步骤之后,配置尚未生效。您还需要执行 setup.py 脚本以重新生成 tacker.egg-info 目录的内容。

$ cd /opt/stack/tacker/
$ python setup.py build
running build
running build_py
running egg_info
writing requirements to tacker.egg-info/requires.txt
writing tacker.egg-info/PKG-INFO
writing top-level names to tacker.egg-info/top_level.txt
writing dependency_links to tacker.egg-info/dependency_links.txt
writing entry points to tacker.egg-info/entry_points.txt
writing pbr to tacker.egg-info/pbr.json
[pbr] Processing SOURCES.txt
[pbr] In git context, generating filelist from git
warning: no files found matching 'AUTHORS'
warning: no files found matching 'ChangeLog'
warning: no previously-included files matching '*.pyc' found anywhere in distribution
writing manifest file 'tacker.egg-info/SOURCES.txt'

然后,您可以重新启动 tackertacker-conductor 的服务后,使用 Mgmt Driver 部署 Ansible Driver。

$ sudo systemctl stop devstack@tacker
$ sudo systemctl restart devstack@tacker-conductor
$ sudo systemctl start devstack@tacker

VNF 包创建

1. VNF 包结构

VNF 包的示例结构如下所示。

注意

您也可以在 tacker 的 samples/mgmt_driver/ansible/ansible_vnf_package/ 目录中找到它们。

目录结构

  • TOSCA-Metadata/TOSCA.meta

  • Definitions/

  • Files/images/

  • ScriptANSIBLE/

  • Scripts/

  • BaseHOT/

  • UserData/

!----TOSCA-Metadata
        !---- TOSCA.meta
!----Definitions
        !---- etsi_nfv_sol001_common_types.yaml
        !---- etsi_nfv_sol001_vnfd_types.yaml
        !---- helloworld3_top.vnfd.yaml
        !---- helloworld3_types.yaml
        !---- helloworld3_df_default.yaml
!----Files
        !---- images
                !---- cirros-0.5.2-x86_64-disk.img
!----ScriptANSIBLE
        !---- config.yaml
!----Scripts
        !---- default
                !---- sample.yaml
!----BaseHOT
        !---- default
                !---- nested
                        !---- VDU1.yaml
                !---- VNF-hot.yaml
!----UserData
        !---- __init__.py
        !---- lcm_user_data.py

2. ScriptANSIBLE

此目录包含运行 Ansible 脚本的设置。这包括每个 LCM 运行的 Ansible Playbook 的路径,以及应根据每个 VDU 执行的顺序等。必须在此目录中包含 config.yaml 文件(如目录结构所示)。此文件是驱动程序解析的文件。

config.yaml 文件中的 configurable_properties 是一个强制参数。它可以用于定义可以在 VNF 配置期间使用的键值对。 key 的格式必须以 _VAR_ 开头。因此,当在 vm_app_config 中使用 key 时,它将被设置的值替换。

configurable_properties:
  _VAR_password: 'password'

vdus:
 VDU1:
   config:
     order: 1
     vm_app_config:
       type: ansible
       instantiation:
         - path: _VAR_vnf_package_path/Scripts/default/sample_start-1.yaml
           params:
             ansible_password: _VAR_password
           order: 0
           ansible_version: ansible-2.11 # Optional

上面的示例显示,我们有一个键 _VAR_password 和一个值 password。它将替换 vm_app_config 中使用的 _VAR_password

要指定默认版本以外的 Ansible 版本,请设置 ansible_version。请注意,要使用此选项,您必须首先安装多个 Ansible 版本,并在 tacker.conf 中定义虚拟环境路径和标识符的映射(请参阅 2. 设置 tacker.conf)。

注意

变量 _VAR_vnf_package_path/ 是 Ansible Playbook 路径的强制参数。此值在运行时期间被实际的 vnf 包路径替换。

3. Scripts

此目录包含要在每个 LCM 上运行的用户定义的 Ansible Playbook。Playbook 根据 ScriptANSIBLE 下的 config.yaml 定义执行。示例 Ansible Driver 利用 Ansible 运行 Playbook。

# This playbook prints a simple debug message
- name: Echo
  hosts: all
  remote_user: root

  tasks:
  - name: Creates a file
    remote_user: some_user
    become: yes
    become_method: sudo
    file:
      path:  "/tmp/sample.txt"
      state: touch

4. BaseHOT

Base HOT 文件是一种 Native 云编排模板,HOT 在这里通常用于不同 VNF 中的 LCM 操作。用户负责准备此文件,并且必须使其与放置在 Definitions/ 目录中的 VNFD 一致。

以下是在这些文件中需要检查的内容
  • resources 下,名称中不应有 _group

heat_template_version: 2013-05-23
description: 'default deployment flavour for Sample VNF'

parameters:
  nfv:
    type: json

resources:
  VDU1:
    type: OS::Heat::AutoScalingGroup

所有 yaml 文件都必须具有 outputs 部分。这对于生成 mgmt_ip 地址是必要的。 outputs 部分的格式如下

mgmt_ip-<VDU_NAME>:
  value:
    get_attr:
      - <VDU_CP>
      - fixed_ips
      - 0
      - ip_address

示例 Ansible Driver LCM

1. VNF 包创建/上传

在实例化 VNF 之前,必须创建一个 VNF 包的 zip 文件并上传它。

请参阅第 创建和上传 VNF 包 部分中的步骤。

注意

请不要忘记在创建 zip 文件时包含以下文件夹

  • Files/

  • ScriptANSIBLE/

  • Scripts/

请从 samples/tests/etc/samples/etsi/nfv/common/Files/ 获取 Files 文件夹的内容。

2. VNF 创建/实例化

请参阅第 创建和实例化 VNF 部分中的步骤。

注意

请在 tacker-conductor.log 中查看 Ansible Playbook Play 结果。

3. VNF 修复

请参阅第 VNF 修复 部分中的步骤。

注意

请在 tacker-conductor.log 中查看 Ansible Playbook Play 结果。

4. VNF 扩展

请参阅第 VNF 扩展 部分中的步骤。

注意

请在 tacker-conductor.log 中查看 Ansible Playbook Play 结果。

5. VNF 终止/删除

请参阅第 终止和删除 部分中的步骤。

注意

请在 tacker-conductor.log 中查看 Ansible Playbook Play 结果。