浮动 IP 速率限制

RFE: https://bugs.launchpad.net/neutron/+bug/1596611

浮动 IP 带宽现在是不受限制的。但是,对于云部署,网卡和数据中心的出口可能存在限制。因此需要浮动 IP 速率限制。

本规范描述了如何添加一个内置扩展来限制浮动 IP 带宽。

问题描述

Neutron 现在拥有带宽不受限制的浮动 IP,因此有几个理由为浮动 IP 添加速率限制:

  • a) 目前,neutron QoS 的实现只影响 neutron 端口,更详细地说,带宽限制是基于 neutron 端口的,所以所有 VM 流量都将受到该限制,包括 L3 流量。L3 需要基于 IP 的实现。

    1. 南北向流量始终依赖于基础设施网络容量。

  • c) 对于浮动 IP 流量,云部署可能没有足够的带宽同时满足所有租户的总带宽需求。因此,用户网络流量的服务水平协议 (SLA) 无法得到保证。例如,如果 VM 网卡被赋予高 QoS 值,那么为了满足每个租户的需求,数据中心网络将承受重载,从而可能无法处理额外的请求,不仅影响租户网络从南北向的带宽,还会影响东西向流量。

  • d) 集中式网络节点中的 SNAT 流量也无法满足所有租户的带宽需求。因为网卡的带宽是有限的。

提议的变更

概述

我们希望限制浮动 IP 的带宽。同时,东西向流量不应受到影响。

一些约定

  • 允许将 QoS 策略绑定到浮动 IP。

  • 每个浮动 IP 应该只有一个 QoS 策略。

  • L3 代理需要一个 QoS 扩展来处理 L3 IP 相关的 QoS 规则。

  • QoS 策略参数可为空。浮动 IP 可以不分配 QoS 策略。

变更如何工作

  • Linux TC (流量控制) [1] 将用于实现此功能。对于出站流量,将使用 HTB [2] qdisc 来限制浮动 IP 的出站带宽。

提出的解决方案

服务器端变更

  • 用于 QoS 属性 (qos_policy_id) 的新浮动 IP 扩展。

  • 添加浮动 IP 和 QoS 策略之间的新关系表 QoSFIPPolicyBinding

  • L3 插件将在路由器同步 RPC 期间返回浮动 IP 列表及其绑定的 QoS 策略。

L3 代理侧的 TC 规则

在哪里安装 TC 规则

  • 对于 HA/传统路由器,浮动 IP 的规则将安装到网络节点的 qrouter 命名空间中,流量控制设备将是 qg-device。

  • 对于 DVR 路由器,它位于计算节点的 qrouter 命名空间中,但浮动 IP 流量控制设备将是 rfp-device(qrouter-namespace 到 fip-namespace 对之一)。

对于所有 IP,在相应的命名空间中,出口和入口 qdisc 规则基本相同。{qdisc_id} 将用于创建 IP 的 tc 过滤器。一些提示:

  • 请记住,以下所有命令都将在一个命名空间中执行。

  • [a-device] 表示命名空间中的 qg-device 或 rfp-device。

  • {egress/ingress_qdisc_id} 是 qdisc 句柄 ID。

创建 qdisc 命令

# egress
tc qdisc add dev [a-device] root htb

# ingress
tc qdisc add dev [a-device] ingress

实际 qdisc 规则

$ tc qdisc show dev [a-device]
# egress
qdisc htb {egress_qdisc_id} root refcnt 2 r2q 10 default 0 direct_packets_stat 400

# ingress
qdisc ingress {ingress_qdisc_id} parent ffff:fff1 ----------------

然后我们可以使用 {ingress_qdisc_id} 和 {egress_qdisc_id} 来创建 L3 IP 过滤器。假设我们有一个 L3 IP 172.16.6.161,它有一个 QoS 策略,规则为 {qos_rate_value: 1000Kbit, qos_burst_value: 1Mb}。入口和出口 tc 过滤器创建命令将是:

# ingress
$ tc filter add dev [a-device] parent {ingress_qdisc_id} protocol ip prio 1 \
  u32 match ip dst 172.16.6.161 police \
  rate 1000Kbit burst 1Mb drop flowid :1

# egress
$ tc filter add dev [a-device] parent {egress_qdisc_id} protocol ip prio 1 \
  u32 match ip src 172.16.6.161 police \
  rate 1000Kbit burst 1Mb drop flowid :1

实际过滤规则

# ingress
$ tc -s -d -p filter show dev [a-device] parent {ingress_qdisc_id}
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP dst 172.16.6.161/32 (success 0 )
 police 0x67 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
...

# egress
$ tc -s -d -p filter show dev [a-device] parent {egress_qdisc_id}
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP src 172.16.6.161/32 (success 0 )
 police 0x68 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
...

Neutron 基本工作流程

浮动 IP

    1. 用户创建一个浮动 IP。

    1. 浮动 IP 与端口关联。

    1. 为浮动 IP 创建/查找 QoS 策略和规则。

    1. 将 QoS 策略绑定到浮动 IP(浮动 IP 更新 API)。

    1. L3 代理处理路由器及其浮动 IP。

    1. L3 代理将 TC 规则设置到 qrouter-namespace 相关设备。

此后,浮动 IP 将受到带宽限制。

L3 代理侧 TC 规则示例

假设我们有一个传统路由器:cf6951cb-b050-4543-9742-c63a4989edae,网关 IP:172.16.6.167,1Mbps,浮动 IP:172.16.10.69,1Mbps,那么在其调度的网络节点中,您可以获得以下规则:

# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    inet 127.0.0.1/8 scope host lo
140: qr-4aba9b05-36: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN
    inet 192.168.233.1/24 brd 192.168.233.255 scope global qr-4aba9b05-36
141: qr-aef0d42d-f9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN
    inet 192.168.232.1/24 brd 192.168.232.255 scope global qr-aef0d42d-f9
143: qg-c99a5832-7f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UNKNOWN
    inet 172.16.6.167/16 brd 172.16.255.255 scope global qg-c99a5832-7f
    inet 172.16.10.69/32 brd 172.16.10.69 scope global qg-c99a5832-7f
       valid_lft forever preferred_lft forever

# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae tc qdisc show dev qg-c99a5832-7f
qdisc htb 801b: root refcnt 2 r2q 10 default 0 direct_packets_stat 400
qdisc ingress ffff: parent ffff:fff1 ----------------

# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae tc -s -d -p filter show dev qg-c99a5832-7f parent 801b:
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP src 172.16.6.167/32 (success 0 )
 police 0xa74 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
filter protocol ip pref 1 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP src 172.16.10.69/32 (success 0 )
 police 0xa76 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae tc -s -d -p filter show dev qg-c99a5832-7f parent ffff:
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP dst 172.16.6.167/32 (success 0 )
 police 0xa73 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
filter protocol ip pref 1 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP dst 172.16.10.69/32 (success 0 )
 police 0xa75 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

以及计算节点中带有浮动 IP 172.16.6.161 1Mbps 的 DVR 路由器 0580788c-c919-447c-aea1-87d415aa173a

# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    inet 127.0.0.1/8 scope host lo
24: rfp-0580788c-c: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc htb state UP qlen 1000
    inet 169.254.106.114/31 scope global rfp-0580788c-c
    inet 172.16.6.161/32 brd 172.16.6.161 scope global rfp-0580788c-c
102: qr-43185e93-af: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN
    inet 192.168.199.1/24 brd 192.168.199.255 scope global qr-43185e93-af
104: qr-51635a61-46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN
    inet 192.168.198.1/24 brd 192.168.198.255 scope global qr-51635a61-46

# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a tc qdisc show dev rfp-0580788c-c
qdisc htb 801e: root refcnt 2 r2q 10 default 0 direct_packets_stat 5
qdisc ingress ffff: parent ffff:fff1 ----------------

# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a tc -s -d -p filter show dev rfp-0580788c-c parent 801e:
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP src 172.16.6.161/32 (success 0 )
 police 0x68 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a tc -s -d -p filter show dev rfp-0580788c-c parent ffff:
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP dst 172.16.6.161/32 (success 0 )
 police 0x67 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
ref 1 bind 1

 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

IPv6 影响

只有 IPv4 才有浮动 IP 的概念。

数据模型影响

对于浮动 IP:将创建一个新表 QoSFIPPolicyBinding,以表示浮动 IP 和 QoS 策略之间的一对一关联,每个策略在入口和出口方向都有规则。

REST API 影响

新的浮动 IP API 扩展

floatingip: {
       ...
       'qos_policy_id': {'allow_post': True, 'allow_put': True,
                         'validate': {'type:uuid_or_none': None},
                         'is_visible': True,
                         'default': None},}

新的浮动 IP 创建、删除和更新元素命令,包含 QoS 属性

openstack floating ip create --qos-policy policy_id <network>
openstack floating ip set --qos-policy policy_id floating_ip_id
openstack floating ip unset --qos-policy floating_ip_id

实现

负责人

工作项

  • 创建模型表和 API 扩展。

  • 用于浮动 IP 速率限制的新 TC 命令包装器。

  • L3 代理扩展用于 QoS 规则安装。

  • CLI 支持。

  • 测试。

  • 文档。

依赖项

测试

功能

浮动 IP 的带宽应适当限制。添加新的全栈和 Tempest 场景来测试入口和出口的带宽。

参考资料