中子-中子互连¶
Launchpad RFE: https://bugs.launchpad.net/neutron/+bug/1750368
问题描述¶
目前,为了实现两个或多个 OpenStack 云之间的连接(例如,在不同的 OpenStack 部署之间,或在 OpenStack 区域之间),有一些可用的选项,例如浮动 IP、VPNaaS(基于 IPSec)和 BGPVPN。
然而,这些选项中的任何一个都不适合解决以下所有属性都期望的情况
该解决方案的另一个设计要求是避免引入需要在所有涉及的 OpenStack 云上具有管理员权限的组件。
本规范的目标是提供一种解决方案,在两个或多个 OpenStack 部署或区域之间提供网络连接,同时满足这些要求。
用例¶
示例 1¶
用户 Foo 拥有 OpenStack 云 A 和 OpenStack 云 B 的凭据,OpenStack A 中的一个路由器 X,OpenStack B 中的一个路由器 Y,两者都使用私有 IPv4 地址空间中的不同子网。
用户 Foo 希望通过 API 消耗一项服务,该服务将建立路由器 A 和路由器 B 之间的 IP 连接。
示例 2¶
与示例 1 相同,但这次希望在 OpenStack A 中的网络 X 和 OpenStack B 中的网络 Y 之间建立 L2 连接。
示例 3¶
与示例 1 或 2 相同,但涉及 3 个 OpenStack 部署。
提议的变更¶
概述¶
该方案包括引入一个服务插件和一个相应的 API 扩展,涉及一个新的“interconnection”(互连)资源。Neutron 实例上的“interconnection”资源将引用一个本地资源(例如路由器 A)和一个远程资源(OpenStack B:路由器 B),并且语义是希望在两者之间建立连接。
此资源将是两种 API调用的组成部分
需要连接的用户与每个涉及的 Neutron 实例之间的调用;这些调用的作用是让所有 Neutron 实例都知道连接的需求
一个 Neutron 实例与另一个 Neutron 实例之间的 API 调用;这些调用的作用是
让每个 Neutron 实例验证本地定义的“interconnection”资源与在其他 Neutron 实例中创建的“interconnection”资源之间的一致性
在验证之后,让两个 Neutron 实例识别要使用的机制和每个互连的参数(取决于机制;可以是互连盒上的 VLAN 对,BGPVPN RT 标识符,VXLAN ID 等)
.-------------.
| tenant user |
'----+---+----'
| |
.--------------------------------' '--------------------.
| A1. create "interconnection" |
| between local net X, |
| and "Neutron B: net Y" |
| A2. create "interconnection"
| between local net Y,
| and "Neutron A: net X"
| |
| |
| |
| |
V B1. check symmetric inter. V
.-------------------------. (fail) .--------------------.
| +---------------------------> | |
| Neutron A | | Neutron B |
| | <---------------------------+ |
| | B2. check symmetric inter. | |
| | (ok!) | |
| | | |
| +---------------------------> | |
| | <---------------------------+ |
'-------------------------' B3. exchange info to build '--------------------'
net X interconnection net Y
| |
| |
--+ +--
| C. interconnection is built |
+-- - - - - - - - - - - - - - - --+
| |
| |
请注意,A1/A2/B1/B2 的顺序可以不同,但结果不变:至少其中一个 Neutron 实例最终会确认互连在双方都对称地定义了,并且互连设置阶段最终将在双方进行(参见 操作细节)。
当涉及两个以上的 OpenStack 部署或两个以上的 OpenStack 区域时,这些 API 调用将为每对区域/部署发生。
基本假设,信任模型¶
此提案中信任模型的基本假设是,请求连接的最终用户委托每个 OpenStack 部署仅提供请求的互连,即不在请求时创建资源之间的连接。
为了遵守此协议,每个 OpenStack 部署都需要,从定义上讲,与其他涉及这些互连的 OpenStack 部署建立信任关系;实际上,当收到来自另一个部署的包时,该包被标识为打算用于自己的本地网络 A(VLAN、VXLAN ID、MPLS 标签等),它需要信任该标识符是由 OpenStack 部署推送的,并且最终尊重这些规范的协议的机制。
另一个方面,显而易见但最好明确说明的是,用于互连的网络标识符的选择和定义,以及保持互连彼此隔离,不受此 API 使用者的控制。在本提案中,这些使用者既不能写入,甚至不能读取这些标识符。
请注意,只有步骤 A1/A2 中的 API 调用才需要租户用户对“interconnection”资源具有写访问权限(但不包括与要使用的网络机制相关的属性)。
步骤 B1/B2/B3 中的调用只需要对这些资源具有只读访问权限;这可以通过引入一个具有对所有“interconnection”资源具有只读访问权限的“interconnection”角色来实现,并且每个 OpenStack 部署都具有其他 OpenStack 部署中具有此角色的用户的凭据。
考虑到以上几点,Keystone 联合对于步骤 A1/A2 和步骤 B1/B2 的调用不是必需的。但是,为步骤 B1/B2 中使用的用户使用 Keystone 联合肯定会有用,并且可以避免需要在每个 Neutron 实例中管理用于彼此 OpenStack 的凭据。
互连机制¶
虽然这些规范试图对最终用于实现互连的网络技术保持不可知,但假设对于每个“interconnection”,都有两种 OpenStack 部署通用的技术。
提出的方法是一个简单的方法,其中每个 OpenStack 部署根据配置文件确定,在与给定的 OpenStack 部署建立互连时使用哪种技术。
请注意,只有在两个互连之间不同的参数才会保存在配置文件中。两个 Neutron 实例之间的 API 交换用于交换特定于每个互连的参数。
示例互连技术¶
可以考虑以下技术来实现互连
基于 BGP 的 VPN:已通过 Neutron BGPVPN 互连服务支持(参见 networking-bgpvpn),它允许创建 L2(使用 EVPN)或 L3 连接(使用 BGP/MPLS IP VPN)
使用 networking-l2gw 的 VXLAN 拼接(细节仍需调查)
VLAN 拼接(细节仍需调查)
预计第一个实现将至少提供对 BGPVPN 互连技术的支持,该技术已经在各种 Neutron 后端(Neutron 参考驱动程序、OpenDaylight、OpenContrail、Nuage Networks)中得到支持,因此将允许此 API 扩展在第一天就支持所有这些控制器,而无需进行任何额外的控制器驱动程序开发。
操作细节¶
当创建“interconnection”资源时,Neutron 实例将检查远程 Neutron 实例在互连中指定是否存在对称的互连,并且在变为真之前不会进一步进行。
此检查建立了端到端信任,即双方都请求了连接。
一旦 Neutron 实例确定互连是对称定义的,就会发生进一步的交换以确定用于实现互连的网络参数
刚刚确认对称性的 Neutron(例如 Neutron B)分配所需的网络标识符,并要求远程 Neutron 实例(A)刷新其状态
Neutron A 刷新其状态:再次检查对称性(现在成功),同时检索 B 分配的网络标识符,并要求 Neutron B 刷新
Neutron B 再次刷新,这次同时检索 A 分配的网络标识符
在上述过程中,“要求远程 Neutron 实例刷新其状态”是通过对 interconnection 上的特定 refresh 操作执行 PUT 来完成的。
互连生命周期¶
在上一节中,暗示一个 interconnection 在其生命周期中处于不同的状态,然后最终实现。当一个侧面的 interconnection 资源被删除时,另一侧也需要能够更新其自身的状态(仅用于清理或向最终用户提供适当的反馈)。
此外,Neutron 实例与另一个 Neutron 实例之间的交互需要在 API 调用处理路径之外发生,因为不希望本地 API调用的成功取决于与外部组件的操作的成功,而该外部组件可能在当时不可用。
出于所有这些原因,将引入一个状态机来处理互连资源生命周期,触发和定期操作将在 API 调用之外进行,以处理每个状态的操作。
将此状态暴露在 API 中将允许
最终用户了解他们离工作状态还有多近
每个 Neutron 实例可能识别远程状态与本地状态不一致
状态机摘要
- TO_VALIDATE
已创建互连资源,但尚未验证对称互连的存在
- VALIDATED
已验证对称互连的存在,并且已分配本地互连参数(仍未知远程参数)
- ACTIVE(活动)
已知本地参数和远程参数,已设置互连,应该可以工作
- TEARDOWN
已采取本地操作以删除此互连,正在采取操作以使远程状态同步
- (DELETED)
隐式状态,对应于资源不再存在
REST API 影响¶
该提案是引入一个 API 扩展 interconnection,暴露一个新的 interconnection 资源。
互连资源¶
新的 interconnection API 资源将在 interconnection API 前缀下引入,并具有以下属性
属性名称 |
类型 |
访问 |
注释 |
|---|---|---|---|
id |
uuid |
RO |
|
project_id |
uuid |
RO |
|
type |
enum |
RO |
|
state |
enum |
RO 将在资源生命周期中由 Neutron 更新 |
参见 互连生命周期 中的状态 |
name |
string |
RW |
|
local_resource_id |
uuid |
RO |
路由器或网络 UUID |
remote_resource_id |
uuid |
RO |
路由器或网络 UUID |
remote_keystone |
string |
RO |
远程 keystone 的 AUTH_URL |
remote_region |
string |
RO |
远程 keystone 中的区域 |
remote_interconnection_id |
uuid |
RO Neutron 将在资源生命周期中更新 |
远程互连的 uuid |
local_parameters |
字典 |
||
remote_parameters |
字典 |
此资源将与典型的 CRUD 操作一起使用
POST /v2.0/interconnection/interconnectionsGET /v2.0/interconnection/interconnectionsGET /v2.0/interconnection/interconnections/<uuid>PUT /v2.0/interconnection/interconnections/<uuid>DELETE /v2.0/interconnection/interconnections/<uuid>
此外,引入了一个额外的 REST 操作来触发对 interconnection 资源的 refresh 操作
PUT /v2.0/interconnection/interconnections/<uuid>/refresh
当触发此操作时,发出调用的 Neutron 实例将尝试检索(GET)远程 Neutron 实例上的 interconnection 资源,该资源与本地资源的 type 相同,本地资源的 local_resource_id 作为远程资源的 remote_resource_id,本地资源的 local_resource_id 作为远程资源的 remote_resource_id。根据当前本地状态以及查找此类资源是否成功或失败,本地状态机将转换。
示例¶
这显示了 Neutron-Neutron 互连的网络之间 API 交换示例。
API 调用 A1,从租户用户到 Neutron A
POST /v2.0/interconnection/interconnections
{'interconnection': {
'type': 'network_l3',
'local_resource_id': <uuid of network X>,
'remote_keystone': 'http//<keystone-B>/identity',
'remote_region': 'RegionOne',
'remote_resource_id': <uuid of network Y>
}}
Response: 200 OK
{'interconnection': {
'id': <uuid 1>,
...
}}
API 调用 B1,从 Neutron A 到 Neutron B
GET /v2.0/interconnection/interconnections?local_resource_id=<uuid of network Y>&remote_resource_id=<uuid of network X>
Response: 404 Not Found
API 调用 A2,从租户用户到 Neutron B
POST /v2.0/interconnection/interconnections
{'interconnection': {
'type': 'network_l3',
'local_resource_id': <uuid of network Y>,
'remote_keystone': 'http//<keystone-A>/identity',
'remote_region': 'RegionOne',
'remote_resource_id': <uuid of network X>
}}
Response: 200 OK
{'interconnection': {
'id': <uuid 2>,
...
}}
API 调用 B2,从 Neutron B 到 Neutron A
GET /v2.0/interconnection/interconnections/local_resource_id=<uuid of network X>&remote_resource_id=<uuid of network Y>
Response: 200 OK
{'interconnection': {
'id': <uuid 1>,
...,
'local_parameters': {}
}}
API 调用 B3’,从 Neutron B 到 Neutron A
PUT /v2.0/interconnection/interconnections/<uuid 1>/refresh
Response: 200 OK
API 调用 B3’’,从 Neutron A 到 Neutron B
GET /v2.0/interconnection/interconnections/local_resource_id=<uuid of network Y>&remote_resource_id=<uuid of network X>
Response: 200 OK
{'interconnection': {
'id': <uuid 2>,
...,
'local_parameters': {
'foo': '42'
}
}}
API 调用 B3’’’,从 Neutron A 到 Neutron B
PUT /v2.0/interconnection/interconnections/<uuid 2>/refresh
Response: 200 OK
API 调用 B3’’’’,从 Neutron B 到 Neutron A
GET /v2.0/interconnection/interconnections/<uuid 1>
Response: 200 OK
{'interconnection': {
'id': <uuid 1>,
...,
'remote_interconnection_id': <uuid 2>,
'remote_parameters': {
'foo': '42'
},
'local_parameters': {
'bar': '43'
}
}}
命令行客户端影响¶
python-neutronclient 将更新以引入一个 OSC 扩展来创建/删除/更新/删除 interconnection 资源。
客户端库影响¶
python-neutronclient 和 openstacksdk 需要更新以支持对 interconnection 资源进行创建/删除/更新/删除操作。
鸣谢¶
Przemyslaw Jasek 为探索导致此提案的想法做出了贡献,在 Orange 实习了六个月。
参考资料¶
OpenStack Summit Sydney,闪电演讲 https://openstack.org/videos/sydney-2017/neutron-neutron-interconnections