Open vSwitch: 高可用性使用 DVR

此架构示例通过分布式虚拟路由器 (DVR) 高可用性机制增强了自助服务部署示例,该机制为特定场景下的计算节点(而非网络节点)之间的自助服务和提供商网络提供连接。对于具有浮动 IPv4 地址的实例,自助服务和提供商网络之间的路由完全位于计算节点上,以消除网络节点上的单点故障和性能问题。对于使用相同分布式虚拟路由器的自助服务网络上的具有固定或浮动 IPv4 地址的实例,路由也完全位于计算节点上。但是,具有固定 IP 地址的实例仍然依赖于网络节点来提供自助服务和提供商网络之间的路由和 SNAT 服务。

考虑此高可用性机制的以下属性,以确定其在您的环境中的实用性

  • 仅当实例位于具有浮动 IPv4 地址的自助服务网络上时,才通过实例所在的计算节点为实例提供连接。仅具有 IPv6 地址或同时具有 IPv4 和 IPv6 地址的自助服务网络上的实例依赖于网络节点来提供 IPv6 连接。

  • 每个计算节点上的路由器实例消耗提供商网络上包含网关的一个 IPv4 地址。

先决条件

使用以下组件修改计算节点

  • 安装 OpenStack Networking 第 3 层代理。

注意

考虑添加至少一个额外的网络节点,以为具有固定 IP 地址的实例提供高可用性。有关更多信息,请参阅 使用 VRRP 的分布式虚拟路由

架构

High-availability using Open vSwitch with DVR - overview

下图显示了一个自助服务网络和一个未标记(扁平)网络的组件和连接。在这种特定情况下,实例位于网络的 DHCP 代理所在的同一计算节点上。如果 DHCP 代理位于另一个计算节点上,则后者仅包含一个带有 OVS 集成桥端口的 DHCP 命名空间。

High-availability using Open vSwitch with DVR - components and connectivity - one network

示例配置

使用以下示例配置作为模板,以向现有的支持自助服务网络的运行环境添加使用 DVR 的高可用性支持。

控制器节点

  1. neutron.conf 文件中

    • 默认情况下为所有路由器启用分布式路由。

      [DEFAULT]
      router_distributed = True
      

注意

对于大型云,如果您的部署正在运行带有 DHCP 的 DVR,我们建议您设置 host_dvr_for_dhcp=False 以实现更高的第 3 层代理路由器处理性能。当此值设置为 False 时,DNS 功能将无法通过 DHCP 命名空间(dnsmasq)提供,但是必须配置不同的名称服务器,例如通过在子网的 dns_nameservers 中指定一个值。

  1. 重新启动以下服务

    • 服务器

网络节点

  1. openvswitch_agent.ini 文件中,启用分布式路由。

    [agent]
    enable_distributed_routing = True
    
  2. l3_agent.ini 文件中,配置第 3 层代理以提供 SNAT 服务。

    [DEFAULT]
    agent_mode = dvr_snat
    

注意

agent_mode = dvr_snat 不受计算节点支持。有关讨论,请参阅: bug #1934666

  1. 重新启动以下服务

    • Open vSwitch 代理

    • 第 3 层代理

计算节点

  1. 安装 Networking 服务第 3 层代理。

  2. openswitch_agent.ini 文件中,启用分布式路由。

    [agent]
    enable_distributed_routing = True
    
  3. l3_agent.ini 文件中,配置第 3 层代理。

    [DEFAULT]
    agent_mode = dvr
    
  4. 重新启动以下服务

    • Open vSwitch 代理

    • 第 3 层代理

验证服务操作

  1. 获取管理项目凭据。

  2. 验证代理的存在和操作。

    $ openstack network agent list
    +--------------------------------------+--------------------+----------+-------------------+-------+-------+---------------------------+
    | ID                                   | Agent Type         | Host     | Availability Zone | Alive | State | Binary                    |
    +--------------------------------------+--------------------+----------+-------------------+-------+-------+---------------------------+
    | 05d980f2-a4fc-4815-91e7-a7f7e118c0db | L3 agent           | compute1 | nova              | True  | UP    | neutron-l3-agent          |
    | 1236bbcb-e0ba-48a9-80fc-81202ca4fa51 | Metadata agent     | compute2 | None              | True  | UP    | neutron-metadata-agent    |
    | 2a2e9a90-51b8-4163-a7d6-3e199ba2374b | L3 agent           | compute2 | nova              | True  | UP    | neutron-l3-agent          |
    | 457d6898-b373-4bb3-b41f-59345dcfb5c5 | Open vSwitch agent | compute2 | None              | True  | UP    | neutron-openvswitch-agent |
    | 71f15e84-bc47-4c2a-b9fb-317840b2d753 | DHCP agent         | compute2 | nova              | True  | UP    | neutron-dhcp-agent        |
    | 8805b962-de95-4e40-bdc2-7a0add7521e8 | L3 agent           | network1 | nova              | True  | UP    | neutron-l3-agent          |
    | a33cac5a-0266-48f6-9cac-4cef4f8b0358 | Open vSwitch agent | network1 | None              | True  | UP    | neutron-openvswitch-agent |
    | a6c69690-e7f7-4e56-9831-1282753e5007 | Metadata agent     | compute1 | None              | True  | UP    | neutron-metadata-agent    |
    | af11f22f-a9f4-404f-9fd8-cd7ad55c0f68 | DHCP agent         | compute1 | nova              | True  | UP    | neutron-dhcp-agent        |
    | bcfc977b-ec0e-4ba9-be62-9489b4b0e6f1 | Open vSwitch agent | compute1 | None              | True  | UP    | neutron-openvswitch-agent |
    +--------------------------------------+--------------------+----------+-------------------+-------+-------+---------------------------+
    

创建初始网络

与自助服务部署示例类似,此配置支持多个 VXLAN 自助服务网络。启用高可用性后,所有其他路由器都使用分布式路由。以下过程创建一个额外的自助服务网络和路由器。Networking 服务还支持将分布式路由添加到现有的路由器。

  1. 获取常规(非管理)项目凭据。

  2. 创建一个自助服务网络。

    $ openstack network create selfservice2
    +-------------------------+--------------+
    | Field                   | Value        |
    +-------------------------+--------------+
    | admin_state_up          | UP           |
    | mtu                     | 1450         |
    | name                    | selfservice2 |
    | port_security_enabled   | True         |
    | revision_number         | 1            |
    | router:external         | Internal     |
    | shared                  | False        |
    | status                  | ACTIVE       |
    | tags                    | []           |
    +-------------------------+--------------+
    
  3. 在自助服务网络上创建一个 IPv4 子网。

    $ openstack subnet create --subnet-range 192.0.2.0/24 \
      --network selfservice2 --dns-nameserver 8.8.4.4 selfservice2-v4
    +-------------------+---------------------------+
    | Field             | Value                     |
    +-------------------+---------------------------+
    | allocation_pools  | 192.0.2.2-192.0.2.254     |
    | cidr              | 192.0.2.0/24              |
    | dns_nameservers   | 8.8.4.4                   |
    | enable_dhcp       | True                      |
    | gateway_ip        | 192.0.2.1                 |
    | ip_version        | 4                         |
    | name              | selfservice2-v4           |
    | revision_number   | 1                         |
    | tags              | []                        |
    +-------------------+---------------------------+
    
  4. 在自助服务网络上创建一个 IPv6 子网。

    $ openstack subnet create --subnet-range fd00:192:0:2::/64 --ip-version 6 \
      --ipv6-ra-mode slaac --ipv6-address-mode slaac --network selfservice2 \
      --dns-nameserver 2001:4860:4860::8844 selfservice2-v6
    +-------------------+------------------------------------------------------+
    | Field             | Value                                                |
    +-------------------+------------------------------------------------------+
    | allocation_pools  | fd00:192:0:2::2-fd00:192:0:2:ffff:ffff:ffff:ffff     |
    | cidr              | fd00:192:0:2::/64                                    |
    | dns_nameservers   | 2001:4860:4860::8844                                 |
    | enable_dhcp       | True                                                 |
    | gateway_ip        | fd00:192:0:2::1                                      |
    | ip_version        | 6                                                    |
    | ipv6_address_mode | slaac                                                |
    | ipv6_ra_mode      | slaac                                                |
    | name              | selfservice2-v6                                      |
    | revision_number   | 1                                                    |
    | tags              | []                                                   |
    +-------------------+------------------------------------------------------+
    
  5. 创建一个路由器。

    $ openstack router create router2
    +-----------------------+---------+
    | Field                 | Value   |
    +-----------------------+---------+
    | admin_state_up        | UP      |
    | name                  | router2 |
    | revision_number       | 1       |
    | status                | ACTIVE  |
    | tags                  | []      |
    +-----------------------+---------+
    
  6. 将 IPv4 和 IPv6 子网作为接口添加到路由器。

    $ openstack router add subnet router2 selfservice2-v4
    $ openstack router add subnet router2 selfservice2-v6
    

    注意

    这些命令不提供任何输出。

  7. 将提供商网络作为路由器的网关添加。

    $ openstack router set router2 --external-gateway provider1
    

验证网络操作

  1. 获取管理项目凭据。

  2. 验证路由器上的分布式路由。

    $ openstack router show router2
    +-------------------------+---------+
    | Field                   | Value   |
    +-------------------------+---------+
    | admin_state_up          | UP      |
    | distributed             | True    |
    | ha                      | False   |
    | name                    | router2 |
    | revision_number         | 1       |
    | status                  | ACTIVE  |
    +-------------------------+---------+
    
  3. 在每个计算节点上,验证是否创建了具有相同 ID 的 qrouter 命名空间。

    计算节点 1

    # ip netns
    qrouter-78d2f628-137c-4f26-a257-25fc20f203c1
    

    计算节点 2

    # ip netns
    qrouter-78d2f628-137c-4f26-a257-25fc20f203c1
    
  4. 在网络节点上,验证是否创建了具有相同 ID 的 snatqrouter 命名空间。

    # ip netns
    snat-78d2f628-137c-4f26-a257-25fc20f203c1
    qrouter-78d2f628-137c-4f26-a257-25fc20f203c1
    

    注意

    由于在启用分布式路由之前创建,因此来自 Open vSwitch: 自助服务网络 的路由器 1 的命名空间也应出现在网络节点 1 上。

  5. 启动一个具有附加自助服务网络接口的实例。例如,使用 flavor ID 1 的 CirrOS 镜像。

    $ openstack server create --flavor 1 --image cirros --nic net-id=NETWORK_ID selfservice-instance2
    

    NETWORK_ID 替换为附加自助服务网络的 ID。

  6. 确定实例的 IPv4 和 IPv6 地址。

    $ openstack server list
    +--------------------------------------+-----------------------+--------+----------------------------------------------------------+--------+---------+
    | ID                                   | Name                  | Status | Networks                                                 | Image  | Flavor  |
    +--------------------------------------+-----------------------+--------+----------------------------------------------------------+--------+---------+
    | bde64b00-77ae-41b9-b19a-cd8e378d9f8b | selfservice-instance2 | ACTIVE | selfservice2=fd00:192:0:2:f816:3eff:fe71:e93e, 192.0.2.4 | cirros | m1.tiny |
    +--------------------------------------+-----------------------+--------+----------------------------------------------------------+--------+---------+
    
  7. 在提供商网络上创建一个浮动 IPv4 地址。

    $ openstack floating ip create provider1
    +-------------------+--------------------------------------+
    | Field             | Value                                |
    +-------------------+--------------------------------------+
    | fixed_ip          | None                                 |
    | id                | 0174056a-fa56-4403-b1ea-b5151a31191f |
    | instance_id       | None                                 |
    | ip                | 203.0.113.17                         |
    | pool              | provider1                            |
    | revision_number   | 1                                    |
    | tags              | []                                   |
    +-------------------+--------------------------------------+
    
  8. 将浮动 IPv4 地址与实例关联。

    $ openstack server add floating ip selfservice-instance2 203.0.113.17
    

    注意

    此命令不会产生任何输出。

  9. 在包含该实例的计算节点上,验证是否创建了与提供商网络具有相同 ID 的 fip 命名空间。

    # ip netns
    fip-4bfa3075-b4b2-4f7d-b88e-df1113942d43
    

网络流量流

以下部分描述了几个常见场景中网络流量的流程。南北流量网络流量在实例与外部网络(如 Internet)之间传输。东西流量网络流量在相同或不同网络的实例之间传输。在所有场景中,物理网络基础设施处理提供商网络和外部网络(如 Internet)之间的交换和路由。每个案例都引用以下一个或多个组件

  • 提供商网络 (VLAN)

    • VLAN ID 101(已标记)

  • 自助服务网络 1 (VXLAN)

    • VXLAN ID (VNI) 101

  • 自助服务网络 2 (VXLAN)

    • VXLAN ID (VNI) 102

  • 自助服务路由器

    • 提供商网络上的网关

    • 自助服务网络 1 上的接口

    • 自助服务网络 2 上的接口

  • 实例 1

  • 实例 2

本节仅包含从分布式虚拟路由中受益或与常规操作不同的流量场景。对于其他流量场景,请参阅 网络流量流程

南北场景 1:具有固定 IP 地址的实例

南北场景 1:具有固定 IP 地址的实例 类似,只是网络节点上的路由器命名空间变为 SNAT 命名空间。网络节点仍然包含路由器命名空间,但在这种情况下它没有用途。

High-availability using Open vSwitch with DVR - network traffic flow - north/south scenario 1

南北场景 2:具有浮动 IPv4 地址的实例

对于使用分布式路由器上的自助服务网络的具有浮动 IPv4 地址的实例,包含该实例的计算节点对从实例到外部网络(如 Internet)的南北流量执行 SNAT,对从外部网络到实例的南北流量执行 DNAT。浮动 IP 地址和 NAT 不适用于 IPv6。因此,网络节点在此场景中路由 IPv6 流量。从实例到外部网络(如 Internet)的南北流量。

  • 实例 1 位于计算节点 1 上并使用自助服务网络 1。

  • Internet 上的一个主机发送一个数据包到该实例。

以下步骤涉及计算节点

  1. 物理网络基础设施 (1) 将数据包转发到提供商物理网络接口 (2)。

  2. 提供商物理网络接口将数据包转发到 OVS 提供商桥提供商网络端口 (3)。

  3. OVS 提供商桥交换实际 VLAN 标记 101 与内部 VLAN 标记。

  4. OVS 提供商桥 phy-br-provider 端口 (4) 将数据包转发到 OVS 集成桥 int-br-provider 端口 (5)。

  5. OVS 集成桥的提供商网络端口 (6) 删除内部 VLAN 标记并将数据包转发到提供商网络接口 (7) 在浮动 IP 命名空间中。此接口响应对实例浮动 IPv4 地址的任何 ARP 请求。

  6. 浮动 IP 命名空间使用 DVR 内部网络上的两个 IP 地址将数据包路由 (8) 到分布式路由器命名空间 (9)。此命名空间包含实例的浮动 IPv4 地址。

  7. 路由器对数据包执行 DNAT,这会将目标 IP 地址更改为自助服务网络上的实例 IP 地址,通过自助服务网络接口 (10)。

  8. 路由器将数据包转发到 OVS 集成桥的自助服务网络端口 (11)。

  9. OVS 集成桥向数据包添加内部 VLAN 标记。

  10. OVS 集成桥删除数据包中的内部 VLAN 标记。

  11. OVS 集成桥安全组端口 (12) 通过 veth 对将数据包转发到安全组桥 OVS 端口 (13)。

  12. 安全组桥上的安全组规则 (14) 处理数据包的防火墙和连接跟踪。

  13. 安全组桥实例端口 (15) 通过 veth 对将数据包转发到实例接口 (16)。

High-availability using Open vSwitch with DVR - network traffic flow - north/south scenario 2

注意

出站流量以相反的步骤执行,除了 SNAT 会将数据包的源 IPv4 地址更改为浮动 IPv4 地址。

东西场景 1:位于同一路由器上的不同网络上的实例

具有固定 IPv4/IPv6 地址或浮动 IPv4 地址的实例位于同一计算节点上通过计算节点上的路由器进行通信。位于不同计算节点上的实例通过每个计算节点上的路由器实例进行通信。

注意

此场景将实例放置在不同的计算节点上,以显示最复杂的情况。

以下步骤涉及计算节点 1

  1. 实例接口 (1) 通过 veth 对将数据包转发到安全组桥实例端口 (2)。

  2. 安全组桥上的安全组规则 (3) 处理数据包的防火墙和连接跟踪。

  3. 安全组桥 OVS 端口 (4) 通过 veth 对将数据包转发到 OVS 集成桥安全组端口 (5)。

  4. OVS 集成桥向数据包添加内部 VLAN 标记。

  5. OVS 集成桥的自助服务网络 1 端口 (6) 删除内部 VLAN 标记并将数据包转发到分布式路由器命名空间中的自助服务网络 1 接口 (6)。

  6. 分布式路由器命名空间将数据包路由到自助服务网络 2。

  7. 分布式路由器命名空间中的自助服务网络 2 接口 (8) 将数据包转发到 OVS 集成桥的自助服务网络 2 端口 (9)。

  8. OVS 集成桥向数据包添加内部 VLAN 标记。

  9. OVS 集成桥交换内部 VLAN 标记与内部隧道 ID。

  10. OVS 集成桥 patch-tun 端口 (10) 将数据包转发到 OVS 隧道桥 patch-int 端口 (11)。

  11. OVS 隧道桥 (12) 使用 VNI 101 封装数据包。

  12. 覆盖网络的底层物理接口 (13) 通过覆盖网络 (14) 将数据包转发到计算节点 2。

以下步骤涉及计算节点 2

  1. 覆盖网络的底层物理接口 (15) 将数据包转发到 OVS 隧道桥 (16)。

  2. OVS 隧道桥解封装数据包并向其添加内部隧道 ID。

  3. OVS 隧道桥交换内部隧道 ID 与内部 VLAN 标记。

  4. OVS 隧道桥 patch-int 补丁端口 (17) 将数据包转发到 OVS 集成桥 patch-tun 补丁端口 (18)。

  5. OVS 集成桥删除数据包中的内部 VLAN 标记。

  6. OVS 集成桥安全组端口 (19) 通过 veth 对将数据包转发到安全组桥 OVS 端口 (20)。

  7. 安全组桥上的安全组规则 (21) 处理数据包的防火墙和连接跟踪。

  8. 安全组桥实例端口 (22) 通过 veth 对将数据包转发到实例 2 接口 (23)。

注意

在发送数据包的实例所在的计算节点上进行自助服务网络之间的路由。在此场景中,路由发生在计算节点 1 上,用于从实例 1 到实例 2 的数据包,以及在计算节点 2 上,用于从实例 2 到实例 1 的数据包。

High-availability using Open vSwitch with DVR - network traffic flow - east/west scenario 2