- 本作品采用知识共享署名 3.0 未移植许可协议进行授权。
许可。
http://creativecommons.org/licenses/by/3.0/legalcode
Introspection LLDP 报告¶
链路层发现协议 (LLDP) 数据包由网络交换机根据 IEEE Std 802.1AB-2016 的规定,周期性地从每个交换机端口发送。该协议用于通告交换机端口的功能和配置。LLDP 数据包由运行在每个节点上的 Ironic Python Agent (IPA) 收集,并按照 IPA 更改以添加 LLDP 支持 的规定,以与接收时相同的类型、长度、值 (TLV) 格式存储在 Ironic Inspector 数据库中的每个接口中。LLDP 数据包含交换机端口 VLAN 分配、MTU 大小、链路聚合配置等,提供了一组丰富的网络信息,可用于从 Ironic 节点的角度规划和排查部署问题。
本提案是针对额外的 Ironic Inspector 钩子,用于解析原始 LLDP TLV 并将结果存储回 Swift 作为接口数据的一部分。处理后的 LLDP 数据可以直接访问或通过客户端 CLI 显示。本提案包括 python-ironic-inspector-client CLI 命令,用于显示处理后的 LLDP 数据。数据应以允许用户快速查看网络交换机端口配置并检测节点内部和节点之间的不匹配的格式显示。例如,应该能够轻松查看特定 VLAN 是否配置在每个节点的 eth0 接口上,或者检测连接到所有节点的交换机端口是否都配置为支持巨型帧。
问题描述¶
网络交换机配置问题可能是 Openstack 部署中出现问题的主要来源,并且难以检测和诊断。可能有很多网络交换机端口连接到多个裸机节点,并且交换机端口配置可能与部署参数不匹配。进行 Openstack 部署的用户可能无法访问网络交换机以查看端口配置,或者可能不熟悉特定的交换机用户界面。
交换机端口配置与 Openstack 部署节点接口设置之间的一些潜在不匹配是
VLAN 配置
配置网络的未标记 VLAN ID
MTU 大小
链路聚合(又称 bonding)配置
提议的变更¶
拟议更改的范围是解析由 Ironic Python Agent 通过 Ironic Inspector 插件 TLV 捕获的 LLDP 数据,如 IEEE Std 802.1AB-2016 中定义的,并以用户友好的格式显示数据。确定 Openstack 部署是否与交换机端口配置匹配超出了范围,但 CLI 命令可用于验证和确认部署配置。
将添加一个新的 Ironic Inspector 钩子(又称插件)来解析所有标准 LLDP 数据并将其存储在每个接口中。并非每个网络交换机都会发送规范中定义的所有 LLDP TLV。但是,似乎标准做法是支持该标准的交换机将实现基本的管理、IEEE Std 802.1Q-2014 和 IEEE Std 802.3-2012 可选 TLV。新的 Ironic Inspector 钩子必须支持以下强制性和可选 TLV
Chassis ID TLV(强制)
Port ID TLV(强制)
- 基本管理 TLV 集(可选)
Port Description TLV
System Name TLV
System Description TLV
System Capabilities TLV
Management Address TLV
- IEEE 802.1 组织特定 TLV 集(可选)
Port VLAN ID TLV
Port And Protocol VLAN ID TLV
VLAN Name TLV
Protocol Identity TLV
Management VID TLV
Link Aggregation TLV
- IEEE 802.3 组织特定 TLV 集(可选)
MAC/Phy Config/Status TLV(包括双工/速度/自动协商)
Link Aggregation TLV
Maximum Frame Size MTU
LLDP-MED TLV 集是为支持 IP 电话而开发的,因此与 LAN 环境无关。收到的 LLDP-MED TLV 可以由单独的处理钩子处理,该钩子将解析和存储解码的 TLV。可以堆叠处理钩子,以便可以运行标准 LLDP 处理钩子以及 LLDP-MED 钩子。开发 LLDP-MED 处理钩子超出了本次工作的范围。
一些网络交换机发送特定于供应商的 TLV。这些 TLV 的定义可能并非广泛可用或在不同版本之间保持一致。为了支持这些 TLV 的解析,可以将特定于供应商的钩子添加到其他 LLDP 钩子中,尽管特定于供应商的钩子超出了本次工作的范围。
可以在 inspector.conf 文件中启用钩子。默认情况下,这些 LLDP 插件将不会启用。有关 ironic-inspector 插件的背景信息,请参见:ironic-inspector 插件。
新的插件将驻留在 ironic-inspector 中。新的 CLI 命令将在 python-ironic-inspector-client 中。
备选方案¶
本拟议的实现使用 IPA 在内省期间捕获的数据,它不是像 lldpd 这样的实时 LLPD 监控工具。使用的数据可能超出生存时间 (TTL) 窗口,因此可能被认为无效。交换机所做的任何配置更改在用户再次运行内省之前将不会被检测到。
这种方法的的主要优点是 inspector 会缓存所有节点及其接口的数据。此实现最适合作为指向交换机和部署配置之间潜在不匹配的工具,而不是作为实时交换机配置的绝对真实来源。
数据模型影响¶
目前 Ironic Inspector 以原始类型/值格式将收到的 LLDP 数据存储在 Swift 中,用于每个接口。例如,下面是存储的 LLDP TLV 的子集,显示了 Chassis ID(类型 1)、Port ID(类型 2)、System Name(类型 5)和 VLAN(类型 127 和 802.1 的 OUI - 0x0080c2)。显示了两个 VLAN TLV,它们映射到 VLAN 100 和 101。
"lldp": [
[
1,
"0464649b32f300"
],
[
2,
"07373231"
[
5,
"737730312d646973742d31622d6231322e72647532"
],
[
127,
"0080c203006407766c616e313030"
],
[
127,
"0080c203006507766c616e313031"
],
...
拟议的 Ironic Inspector 处理钩子将解析此 LLDP 数据,并使用包含名称/值对的 lldp_processed 结构更新数据存储,每个接口一个。该新结构将存储在 all_interfaces 下。
请注意,在原始数据中,可能存在具有相同 TLV 类型/子类型的多个 TLV。在某些情况下,这是预期的,例如,为每个配置的 VLAN 都有单独的 VLAN TLV。在其他情况下,对于相同类型/子类型的多个 TLV 是意外的,可能是由于交换机两次发送相同的 TLV 或 IPA 以错误的顺序接收它们等原因。仍然需要处理意外情况。
根据 TLV 类型,钩子会将数据存储为名称/列表或名称/值绑定。名称/值将用于应只有一个值的 TLV,例如 chassis_id,而名称/列表用于可以包含具有相同类型/子类型的多个 TLV 的数据,例如 VLAN。存储在列表中的每个条目必须是唯一的,不能有重复的列表条目。system_capabilities 和 port_capabilites TLV 可以像 VLAN 一样作为列表处理。
对于映射到单个名称/值对的 TLV,即 chassis_id、port_id、autonegotiation_enabled 等,必须检查以确保不会处理重复的 TLV。换句话说,如果 chassis_id 的名称/值对已经存储,则不会覆盖它。
下面显示了处理后的示例内容。
all_interfaces": {"eth0":
{"ip": null, "mac": "a0:36:xx:xx:xx",
"lldp_processed": {
"switch_chassis_id": "64:64:9b:xx:xx:xx",
"switch_port_id": "734",
"switch_system_name": "sw01-bld2",
"switch_port_physical_capabilities" : ['100Base-TX hdx',
'100BASE-TX fdx',
'1000BASE-T fdx'],
"switch_port_mtu" : "9216",
"switch_port_link_aggregation_support": "True",
"switch_port_link_aggregation_enabled": "False",
"switch_port_autonegotiation_support" "True",
"switch_port_autonegotiation_enabled" "True",
"switch_port_vlans": [{"name": "vlan101", "id": 101},
{"name": "vlan102", "id": 102},
{"name": "vlan104", "id": 103}],
...
}
}
}
每个处理钩子会将额外的命名对添加到每个接口的 lldp_processed 中。这允许标准和特定于供应商的钩子运行,从而解释所有收到的 LLDP TLV。特定于供应商的插件仅处理与特定于供应商的 OUI 在组织特定 TLV(类型 127)中标识的供应商对应的 TLV。例如,Juniper 使用 OUI 0x009069。同样,LLDP-MED 插件仅处理具有 OUI 0x0012bb 的组织特定 TLV。这样,单个 TLV 不会被处理多次。但是,标准 LLDP 插件与供应商或 LLDP-MED 插件之间处理的名称冲突需要避免。因此,额外的插件(超出标准插件)将使用命名格式:<OUI>_<OUIsubtype>
其中“OUI”是对应于供应商 OUI 的字符串,“OUIsubtype”是特定于供应商的子类型,例如:
"juniper_chassis_id": "0123456789"
同样,LLDP-MED 插件的一些示例
"lldp_med_location_id": "5567892"
"lldp_med_device_type": "Network connectivity"
HTTP API 影响¶
无。
客户端 (CLI) 影响¶
为了显示 Ironic python agent 收集的 LLDP,建议在 openstack baremetal introspection 下添加一组新的命令,如下所示,并附有示例输出。
列出每个节点的接口,其中包含关键 LLDP 数据。
$ openstack baremetal introspection interface list
5f428939-698d-4942-b164-ff645a768e4a
接口 |
MAC |
交换机 VLAN ID |
交换机 Chassis |
交换机 Port |
eth0 |
b0… |
[101, 102, 103] |
64:64:9b:xx:xx:xx |
554 |
eth1 |
b0… |
[101, 102, 103] |
64:64:9b:xx:xx:xx |
734 |
eth2 |
b0… |
[101, 102, 103] |
64:64:9b:xx:xx:xx |
587 |
eth3 |
b0… |
[101, 102] |
64:64:9b:xx:xx:xx |
772 |
2. 显示接口的所有 LLDP 值。字段名称将直接来自存储在处理后的数据中的名称。
$ openstack baremetal introspection interface show
5f428939-698d-4942-b164-ff645a768e4a eth0
字段 |
值 |
node |
5f428939-698d-4942-b164-ff645a768e4a |
interface |
eth0 |
interface_mac_address |
b0:83:fe:xx:xx:xx |
switch_chassis_id |
64:64:9b:xx:xx:x |
switch_port_id |
554 |
switch_system_name |
sw01-dist-1b-b12.rdu2 |
switch_system_capabilities |
[‘Bridge’, ‘Router’] |
switch_port_description |
host2.lab.eng port 1 (Prov/Trunked VLANs) |
switch_port_autonegotiation_support |
True |
switch_port_autonegotiation_enabled |
True |
switch_port_physical_capabilities |
[‘100Base-TX hdx’, ‘100BASE-TX fdx’, ‘1000BASE-T fdx’] |
switch_port_mau_type |
未知 |
switch_port_link_aggregation_support |
True |
switch_port_link_aggregation_enabled |
False |
switch_port_link_aggregation_id |
0 |
switch_port_mtu |
9216 |
switch_port_untagged_vlan_id |
102 |
switch_port_vlans |
|
显示按特定 VLAN 过滤的接口数据
$ openstack baremetal introspection interface list
5f428939-698d-4942-b164-ff645a768e4a --vlan=103
接口 |
MAC |
交换机 VLAN ID |
交换机 Chassis |
交换机 Port |
eth0 |
b0… |
[101, 102, 103] |
64:64:9b:xx:xx:xx |
554 |
eth1 |
b0… |
[101, 102, 103] |
64:64:9b:xx:xx:xx |
734 |
eth2 |
b0… |
[101, 102, 103] |
64:64:9b:xx:xx:xx |
587 |
4. 显示使用存储在处理后的数据中显示的字段名称的每个节点/接口的提供的字段的值。
要显示节点上所有接口的交换机端口 MTU
$ openstack baremetal introspection interface list
5f428939-698d-4942-b164-ff645a768e4a --fields interface,
switch_port_mtu
接口 |
switch_port_mtu |
eth0 |
9216 |
eth1 |
9216 |
eth2 |
1514 |
eth3 |
1514 |
要显示节点的交换机端口链路聚合(又称 bonding)配置
$ openstack baremetal introspection interface list
22aadc81-e134-4ff0-ac53-229126e77f62 --fields interface,
switch_port_link_aggregation_enabled
接口 |
switch_port_link_aggregation_enabled |
eth0 |
False |
eth1 |
False |
eth2 |
True |
eth3 |
True |
要显示节点和接口的交换机端口本机 VLAN 配置
$ openstack baremetal introspection interface list --interface eth0
--fields interface, switch_port_untagged_vlan_id
接口 |
switch_port_untagged_vlan_id |
eth0 |
102 |
5. 要以 json 格式显示所有节点的完整 LLDP 处理报告,可以使用内置参数 --long(以显示所有字段)和 --format json(以 json 格式输出)运行 interface list 命令,例如
$ openstack baremetal introspection interface list
5f428939-698d-4942-b164-ff645a768e4a --long --format json
Ironic python agent 影响¶
LLDP 数据收集在 Newton 中可用,但必须通过内核标志 ipa-collect-lldp 启用。
性能和可扩展性影响¶
每次调用新的 lldp 命令时,Ironic Inspector 都会被查询以获取 LLDP 数据。由于数据已经过 Inspector 钩子的处理,因此无需进行额外的处理即可显示数据。
安全影响¶
这些命令不会显示任何敏感或专有数据。所有 LLDP 数据都作为未加密的 UDP 数据接收。
这些命令可能为部署的安全性审计提供好处,因为它们将能够确保没有系统附加到意外的 VLAN,从而降低意外暴露的可能性。
为了使交换机发送 LLDP 数据包,网络管理员必须在连接到节点接口的端口上启用 LLDP。Openstack CLI 上的用户将能够看到发送在 LLDP 数据包中的所有内容,包括 VLAN、管理 IP、交换机型号、端口号和固件版本。此信息可能潜在地用于组织对网络设备的攻击。因此,System Description TLV,其中可能包括交换机型号、版本和构建信息,将被处理但不显示;Management Address TLV 将以相同的方式处理。这将减少可用信息,同时仍然保留足够的数据用于网络相关验证。
部署者影响¶
如前所述,这些新命令可能有助于部署,因为它们可以帮助检测网络交换机配置与部署设置之间的不匹配,例如 VLAN、MTU、bonding、端口速度等。
默认情况下,新的插件将不会启用。部署者应在 baremetal 环境中在 inspector.conf 中设置标准 LLDP 钩子。
为了在 IPA 中启用数据收集,部署者应将内核标志设置为 ipa-collect-lldp=1。可以在 配置 PXE 中查看设置内核参数的示例。
开发者影响¶
当 CLI 实施时,供应商将能够开发特定于供应商的插件来处理供应商 LLDP TLV 并扩展功能。
实现¶
负责人¶
- 主要负责人:
工作项¶
添加处理钩子以解析标准 lldp 数据并写入数据存储。
将 OSC 命令与 python-ironic-inspector-client 集成。
添加单元测试。
使用多个供应商的网络交换机进行测试。
依赖项¶
列出所有内省状态的 API 会影响类似的命令,因此最好等到完成为止。https://review.opendev.org/#/c/344921/
测试¶
除了功能测试之外,如果可用裸机 CI,则进行一项测试以确保 LLDP 收集已启用并正常工作将会很有用,以及对规范中定义的标准 LLDP 插件进行测试。