QoS 改进了规则和端口类型的验证机制

https://bugs.launchpad.net/neutron/+bug/1586056

虽然 QoS 服务对可以由不同插件应用于端口数据包的规则进行了抽象建模,但目前它无法正确处理部署中存在的各种不同端口类型,或某些插件或技术的特定限制。

问题描述

管理员可能希望,而且很常见的是,混合使用 openvswitch 和 SR-IOV。虽然 SR-IOV 用于更高的吞吐量功能,但 ovs 用于处理正常的 VM 负载。

在 SR-IOV 中,我们首先发现的一个区别是,它无法限制双向带宽,而 OVS 和 Linuxbridge 可以。

策略兼容性

例如,DSCP 标记规则目前仅在 OVS 中实现,这意味着应用于 linuxbridge 或 sr-iov 绑定端口的 QoS 策略将无法完全实现。

规则兼容性

如果我们查看规则验证,我们计划使用新的参数扩展现有规则 [3],但在这种情况下,一些声明自己支持该规则的机制可能不支持特定的参数(方向、流量分类等)。对于非 ml2 插件,某些类型的端口可能也不支持特定的参数(基于端口的性质)。

提议的变更

我们建议在 API 级别对策略、规则参数、端口(qos-policy)和网络(qos-policy)进行验证更改。因此,当检测到冲突更改时,该冲突会立即报告给 API 调用者,并且操作将停止,并返回 409 HTTP 冲突错误

$ neutron qos-<type>-rule-update <pol-id> <rule-id> -<parameter> <value>
Error: you have a port (<port id>) of type (..) attached to that rule,
       which is unable to accept <parameter>=<value>.

在 ML2 的上下文中,机制驱动程序不仅会定义它们支持的规则类型,还会定义参数值,从

supported_qos_rule_types = [qos_consts.RULE_TYPE_BANDWIDTH_LIMIT,
                                qos_consts.RULE_TYPE_DSCP_MARK]

变为

supported_qos_rule_types = {
        qos_consts.RULE_TYPE_BANDWIDTH_LIMIT: {
                    "max_kbps": qos_consts.ANY_VALUE,
                    "max_burst_kbps": qos_consts.ANY_VALUE,
                    "parameter": ["value1", "value2"],
                    "parameter2": qos.Parameter2Validator }
        qos_consts.RULE_TYPE_DSCP_MARK: {
                    "dscp_mark": qos_consts.ANY_VALUE}
 }

对于无法通过简单列表处理的验证,将提供另一个验证器类以供子类化,该类需要验证以及完成验证的描述(为了确保我们拥有详细的描述,以便将来报告功能或向 API 用户提供更有意义的错误)。

不支持新“参数”的不同机制驱动程序将具有如下声明,其中“参数”未在字典中声明

supported_qos_rule_types = {
        qos_consts.RULE_TYPE_BANDWIDTH_LIMIT: {
                    "max_kbps": qos_consts.ANY_VALUE,
                    "max_burst_kbps": qos_consts.ANY_VALUE,
        qos_consts.RULE_TYPE_DSCP_MARK: {
                    "dscp_mark": qos_consts.ANY_VALUE}
 }

其中 Parameter2Validator 示例,通用的验证类如下所示

class ParameterValidator(object):

    @abc.abstractmethod
    def validate(self, value):
        pass


class Parameter2Validator(ParameterValidator):

    description = "Validates that parameter2 is higher than two"

    def validate(self, value):
        if value > 2:
            return
        raise Exception..(...)

更新现有的机制驱动程序以公开新的详细信息是必要的,但我们将提供一个支持旧形式的周期,并为现有的非树内机制驱动程序提供弃用通知。

将向 QoS 服务插件“通知”接口添加新函数

def validate_policy_for_port(self, context, policy, port):
  ...

def validate_policy_for_network(self, context, policy, network_id):
  ...

对于第二个函数,基础驱动程序提供默认实现,该实现将获取网络端口并迭代 validate_policy_for_port,但可以被实现覆盖。

这将负责验证策略/端口对,并在发生冲突时抛出详细的异常。

在 ML2 中,我们建议使用进程内回调来验证 NETWORK 和 PORT 对象的 BEFORE_CREATE/BEFORE_UPDATE。规则的修改将由 QoS 插件单独处理,该插件将使用实现提供的 validate_policy_for_port 函数。

参考资料

[1] https://bugs.launchpad.net/neutron/+bug/1586056 [2] https://review.openstack.org/#/c/319694/ [3] https://bugs.launchpad.net/neutron/+bug/1560961