支持智能网卡的裸机 Neutron OVS Agent

https://bugs.launchpad.net/neutron/+bug/1785608

本文档描述了 Neutron OVS 机制驱动程序和 Neutron OVS agent 的提议更改,以启用在智能网卡上运行的通用、厂商无关的裸机网络服务,从而实现与虚拟化用例相当的裸机网络功能。

问题描述

目前 Ironic 支持通过 ML2 机制驱动程序为裸机服务器提供 Neutron 配置的网络连接,但现有支持主要基于通过厂商特定的机制驱动程序配置 TOR 交换机,功能有限。

提议的变更

市场上涌现出各种智能/高性能网卡。这些网卡通常集成了一个或多个通用 CPU 核心以及数据平面包处理加速功能,可以高效运行虚拟交换机(例如 OVS),同时保持与 SDN 层的现有接口。

该提案是扩展 Neutron OVS 机制驱动程序和 Neutron OVS Agent,将裸机主机的 Neutron 端口与智能网卡绑定。这将允许 Neutron OVS Agent 配置在智能网卡上运行的 OVS 的流水线,并利用流水线功能,例如:VXLAN、安全组和 ARP Responder。

本文档是对 Ironic 规范 [1] 的补充。

在此提案中,我们解决了两种用例

  1. Neutron OVS L2 代理在智能网卡上本地运行。

  2. Neutron OVS L2 代理远程运行,并管理所有裸机智能网卡的 OVS 桥接。

智能网卡模型的示例

+---------------------+
|      baremetal      |
| +-----------------+ |
| |  OS Server    | | |
| |               | | |
| |      +A       | | |
| +------|--------+ | |
|        |          | |
| +------|--------+ | |
| |  OS SmartNIC  | | |
| |    +-+B-+     | | |
| |    |OVS |     | | |
| |    +-+C-+     | | |
| +------|--------+ | |
+--------|------------+
         |

A - port on the baremetal host.
B - port that represents the baremetal port in the smart NIC.
C - port that represents to the physical port in the smart NIC.
  • Ironic 创建 Neutron 端口

    1. 使用名为 smart-nic 的新 vnic_type 创建 Neutron 端口。

    2. 添加具有以下属性的 local_link_information

    1. 智能网卡主机名 - 运行 Neutron OVS 代理的服务器/智能网卡的主机名。(必需)

    2. 智能网卡端口 ID - 需要连接到集成桥的端口名称。B 在上面的图中(必需)

    3. 智能网卡 SSH 公钥 - 智能网卡的 ssh 公钥(仅适用于远程)

    4. 智能网卡 OVSDB SSL 证书 - 智能网卡中 OVS 的 OVSDB SSL (仅当远程时才需要)

  • Neutron OVS ML2 机制驱动程序

    OVS ML2 将允许绑定 smart-nic vnic_type。创建新的 vnic_type 而不是使用 barmetal 类型的理由是,有许多机制驱动程序使用分层端口绑定来配置 TOR 交换机,我们希望允许这与智能网卡一起工作。例如 mechanism_drivers=cisco_nexus,openvswitch

    OVS ML2 机制驱动程序将根据从 ironic 传递的智能网卡配置确定 Neutron OVS Agent 是本地运行还是远程运行,如上所述。

    如果 Neutron OVS L2 agent 在智能网卡上本地运行,OVS 机制驱动程序将通过智能网卡主机名属性找到 Neutron OVS agent。对于远程情况,更改在此 neutron 规范 [2] 中捕获。

  • Neutron OVS Agent

    扩展 port_update rpc 方法如下

    def port_update(self, context, **kwargs):
      port = kwargs.get('port')
      # get the port data from cache
      port_data = self.plugin_rpc.remote_resource_cache. \
              get_resource_by_id(resources.PORT, port['id'])
      # if smart-nic port add it to updated_smart_nic_ports with
      # the required information for adding the port to OVSDB
      port_binding = port_data['bindings']
      if port_binding['vnic_type'] == 'smart-nic':
              ifname = smart_nic_port_data['port_binding']['profile'] \
                  ['local_link_information'][0]['port_id']
              mac = port_data['mac_address']
              node_uuid = port_data['device_id']
              port_binding['vif_type'] = vif_type
              self.updated_smart_nic_ports.append({
                              'mac': mac,
                              'node_uuid': node_uuid,
                              'iface_id': port['id'],
                              'iface_name': ifname,
                              'vif_type': vif_type})
      self.updated_ports.add(port['id'])
    

    当 Neutron 处理端口时,Neutron OVS agent 将通过 os-vif 中的 ovs 插件将智能网卡端口添加到 OVSDB。

    由于 RPC 不可靠,我们需要扩展完全同步以执行以下操作

    1. 当 sync 为 True 时,我们将检索此 agent 的所有智能网卡端口。这需要添加另一个 RPC 调用。

    2. 我们将比较从 Neutron 服务器检索到的智能网卡端口与集成桥上的现有智能网卡端口。

    3. 如果智能网卡端口仅在 Neutron 服务器上,我们将将其添加到 port_info 中的 added 列表中。

    4. 如果智能网卡端口仅在集成桥上,我们将将其添加到 port_info 中的 removed 列表中。

参考资料