QoS 规则类型 每秒包数

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

Neutron 支持端口和 L3 IP 的带宽速率限制。但每秒包数 (packet per second) 限制不可用,尽管这是一种常见的测量指标。

因此,本规范描述了添加新的 QoS 规则类型每秒包数 (pps)。

问题描述

每秒包数是一种非常通用的网络性能指标。与带宽一样,它通常用于评估设备的包转发性能。

对于云提供商来说,限制 VM NIC 的每秒包数 (pps) 既常见又至关重要。在物理计算主机中传输大量 VM 数据包会消耗 CPU 和物理 NIC I/O 性能。对于小数据包,即使带宽较低,pps 仍然可能很高。如果没有限制,这可能成为云内部的攻击点,而某些 VM 可能会被入侵。

对于像 ovs 和 ovn 这样的 L2 驱动程序,当用户从 VM 发送小数据包(通常为 64B 小包)到其他设备时,CPU 使用率可能会极高,即使该设备具有较低的 QoS 带宽限制。然后,您的主机服务和其他用户的 VM 将面临更高的故障点。

为了保证网络质量,系统资源消耗根据用户的 VM 规格确定。通过 pps 限制,VM 将不会消耗更多的 CPU,即使带宽较小。

提议的变更

为 QoS 服务插件添加新的 API 扩展,以允许对包速率限制(每秒包数)规则进行 CURD 操作。

注意

我们不会详细说明 L2/L3 后端的实际限制,本规范仅显示我们如何添加新的 QoS 规则类型。

服务器端变更

Neutron 将添加一个新的 API 扩展,其中包含新的资源 PacketRateLimitRule

qos_apidef.SUB_RESOURCE_ATTRIBUTE_MAP = {
    'packet_rate_limit_rules': {
        'parent': qos_apidef._PARENT,
        'parameters': {
            qos_apidef._QOS_RULE_COMMON_FIELDS,
            'max_kpps': {
                'allow_post': True, 'allow_put': True,
                'convert_to': converters.convert_to_int,
                'is_visible': True,
                'is_filter': True,
                'is_sort_key': True,
                'validate': {
                    'type:range': [0, db_const.DB_INTEGER_MAX_VALUE]}
            },
            'max_burst_kpps': {
                    'allow_post': True, 'allow_put': True,
                    'is_visible': True, 'default': 0,
                    'is_filter': True,
                    'is_sort_key': True,
                    'convert_to': converters.convert_to_int,
                    'validate': {
                        'type:range': [0, db_const.DB_INTEGER_MAX_VALUE]}
            },
            'direction': {
                'allow_post': True,
                'allow_put': True,
                'is_visible': True,
                'is_filter': True,
                'is_sort_key': True,
                'default': constants.EGRESS_DIRECTION,
                'validate': {
                    'type:values': constants.VALID_DIRECTIONS}
            }
        }
    }
}

注意

速率和突发量的单位为千(1000)包每秒,因此值范围将为 1 kpps 到 2147 gpps。

潜在的 Agent 端增强

以下每个功能都将是一个独立且庞大的提案,我们不会在此处描述详细信息。

  • 通过 iptables 规则将 pps 规则应用于 Agent 端的 L3 IP [1]

  • 通过 ovs meter 将 pps 规则应用于 VM 端口 [2] [3] [4]

  • 通过 iptables 规则将 pps 规则应用于路由器端口(网关端口、路由器接口)。

  • 通过 ovs meter 将 pps 规则应用于 L3 IP 和端口到 OVN 相关设备。

用户用例

在 L2/L3 后端具备限制 pps 的实际能力后,用户可以在以下场景中使用 pps 规则

  • 使用 L3 agent 的浮动 IP 的“pps”规则

  • 使用 OVN L3 agent 的浮动 IP 的“pps”规则

  • 使用 L3 agent 的网关 IP 的“pps”规则

  • 使用 OVN L3 agent 的网关 IP 的“pps”规则

  • ML2 OVS VM 端口的“pps”规则

  • ML2 OVN VM 端口的“pps”规则

  • 路由器网关或接口端口的“pps”规则

数据模型影响

添加表 qos_packet_rate_limit_rules

op.create_table(
    'qos_packet_rate_limit_rules',
    sa.Column('id', sa.String(36), nullable=False,
              index=True),
    sa.Column('qos_policy_id', sa.String(36),
              nullable=False, index=True),
    sa.Column('max_kpps', sa.Integer()),
    sa.Column('max_burst_kpps', sa.Integer()),
    sa.Column('direction', sa.Enum(constants.EGRESS_DIRECTION,
                                   constants.INGRESS_DIRECTION,
                                   name="directions"),
              nullable=False,
              server_default=constants.EGRESS_DIRECTION),
    sa.PrimaryKeyConstraint('id'),
    sa.ForeignKeyConstraint(['qos_policy_id'], ['qos_policies.id'],
                            ondelete='CASCADE')
)

添加 DB 模型 QosPacketRateLimitRule

class QosPacketRateLimitRule(model_base.HasId, model_base.BASEV2):
    __tablename__ = 'qos_packet_rate_limit_rules'
    qos_policy_id = sa.Column(sa.String(36),
                              sa.ForeignKey('qos_policies.id',
                                            ondelete='CASCADE'),
                              nullable=False)
    max_kpps = sa.Column(sa.Integer)
    max_burst_kpps = sa.Column(sa.Integer)
    revises_on_change = ('qos_policy',)
    qos_policy = sa.orm.relationship(QosPolicy, load_on_pending=True)
    direction = sa.Column(sa.Enum(constants.EGRESS_DIRECTION,
                                  constants.INGRESS_DIRECTION,
                                  name="directions"),
                          default=constants.EGRESS_DIRECTION,
                          server_default=constants.EGRESS_DIRECTION,
                          nullable=False)
    __table_args__ = (
        sa.UniqueConstraint(
            qos_policy_id, direction,
            name="qos_packet_rate_limit_rules0qos_policy_id0direction"),
        model_base.BASEV2.__table_args__
    )

使用 OVO 对象

@base.NeutronObjectRegistry.register
class QosPacketRateLimitRule(QosRule):

    db_model = qos_db_model.QosPacketRateLimitRule

    fields = {
        'max_kpps': obj_fields.IntegerField(nullable=True),
        'max_burst_kpps': obj_fields.IntegerField(nullable=True),
        'direction': common_types.FlowDirectionEnumField(
            default=constants.EGRESS_DIRECTION)
    }

    duplicates_compare_fields = ['direction']

    rule_type = constants.RULE_TYPE_PACKET_RATE_LIMIT

REST API 影响

GET: 列出 QoS 策略的包速率限制规则

  • /v2.0/qos/policies/{policy_id}/packet_rate_limit_rules

响应

{
  "packet_rate_limit_rules": [
      {
          "id": "5f126d84-551a-4dcf-bb01-0e9c0df0c793",
          "max_kpps": 10000,
          "max_burst_kpps": 0,
          "direction": "egress"
      }
  ]
}

POST: 创建包速率限制规则

  • /v2.0/qos/policies/{policy_id}/packet_rate_limit_rules

请求

{
  "packet_rate_limit_rule": {
      "max_kpps": "10000"
  }
}

响应

{
  "packet_rate_limit_rule": {
      "id": "5f126d84-551a-4dcf-bb01-0e9c0df0c793",
      "max_kpps": 10000,
      "max_burst_kpps": 0,
      "direction": "egress"
  }
}

GET: 显示包速率限制规则详细信息

  • /v2.0/qos/policies/{policy_id}/packet_rate_limit_rules/{rule_id}

响应

{
  "packet_rate_limit_rule": {
      "id": "5f126d84-551a-4dcf-bb01-0e9c0df0c793",
      "max_kpps": 10000,
      "max_burst_kpps": 0,
      "direction": "egress"
  }
}

PUT: 更新包速率限制规则

  • /v2.0/qos/policies/{policy_id}/packet_rate_limit_rules/{rule_id}

请求

{
  "packet_rate_limit_rule": {
      "max_kpps": 10000
  }
}

响应

{
  "packet_rate_limit_rule": {
      "id": "5f126d84-551a-4dcf-bb01-0e9c0df0c794",
      "max_kpps": "10000"
  }
}

DELETE: 删除包速率限制规则

  • /v2.0/qos/policies/{policy_id}/packet_rate_limit_rules/{rule_id}

此外,Neutron 将允许将新的 PacketRateLimitRule 附加到 QoS 策略。

Neutron 基本工作流程

  1. 用户创建 QoS 策略

  2. 在此 QoS 策略中创建具有多个方向的包速率限制规则

  3. 将此 QoS 策略附加到端口

  4. (不可用)相关的 L2 驱动程序应用 PPS 限制驱动程序规则到端口

  5. 将此 QoS 策略附加到 L3 IP(浮动 IP 或网关 IP)。

  6. (不可用)相关的 L3 驱动程序应用 PPS 限制驱动程序规则到 IP

实现

负责人

工作项

  • 为 neutron 服务器添加 API 扩展和 DB 模型。

  • 测试。

  • 文档。

依赖项

测试

单元测试用例以验证 DB 规则是否已创建/更新/删除。

参考资料