服务质量 (QoS):保证最小包速率

与带宽可能成为网络接口的限制因素类似,包处理能力往往是像 OVS 这样的软件交换解决方案的限制因素。同时,某些应用程序不仅依赖于保证的带宽,还依赖于保证的包速率才能正常工作。OpenStack 已经通过最小带宽 QoS 策略规则支持带宽保证,这在 服务质量 (QoS):保证最小带宽 中有详细描述。建议先阅读保证最小带宽指南,但这不是强制要求。

服务质量 (QoS):保证最小带宽 指南一样,本章并不旨在取代 Nova 或 Placement 文档,而是对该功能进行简要概述并解释如何配置它。

与保证带宽类似,我们可以区分两种级别的强制执行,以保证包处理能力约束

  • Placement:在放置(调度)虚拟机及其端口时避免过度订阅。

  • 数据平面:在软件交换机上强制执行保证。

注意

在撰写本指南时,仅支持 Placement 强制执行。有关受支持的强制执行类型和后端类型的详细列表,请参阅 网络指南的 QoS 配置章节

该解决方案需要区分两种不同的部署场景

  1. 包处理功能在计算主机 CPU 上实现,因此从入站和出站方向处理的包由同一组 CPU 核心处理。这是非硬件卸载 OVS 部署的情况。在这种情况下,OVS 代表单个包处理资源池,该资源池用单个资源类 NET_PACKET_RATE_KILOPACKET_PER_SEC 表示。

  2. 包处理功能在专用硬件中实现,其中传入和传出的包由独立的硬件资源处理。这是硬件卸载 OVS 的情况。在这种情况下,单个 OVS 具有两个独立的资源池,一个用于传入的包,一个用于传出的包。因此,需要用两个不同的资源类 NET_PACKET_RATE_EGR_KILOPACKET_PER_SECNET_PACKET_RATE_IGR_KILOPACKET_PER_SEC 来表示这些资源池。

限制

由于保证最小包速率和保证最小带宽功能有很多共同之处,因此它们也共享某些限制。

  • 启动服务器时(openstack server create)必须传递一个带有 minimum-packet-rate 规则的预创建端口。由于技术原因,在启动时传递带有最小包速率规则的网络不受支持(在这种情况下,端口创建得太晚,Neutron 无法影响调度)。

  • 仅当策略未生效时,才能更改 QoS 策略的保证(添加/删除 minimum_packet_rate 规则,或更改 min_kpps 字段的 minimum_packet_rate 规则)。也就是说,QoS 策略的端口尚未被 Nova 绑定。拒绝更改正在使用的策略的保证请求。

  • 从 Yoga 版本开始,更改带有新 minimum_packet_rate 规则的端口的 QoS 策略会更改 Placement allocations。如果虚拟机使用没有 QoS 策略和 minimum_packet_rate 规则的端口启动,则端口更新成功,但 Placement 分配不会更改。如果端口在 QoS 策略更新之前没有在 Placement 中分配记录,则情况也是如此。但是,如果虚拟机使用带有 QoS 策略和 minimum_packet_rate 规则的端口启动,则更新是可能的,并且 Placement 中的分配也会更改。

注意

如果可以更新端口以删除 QoS 策略,则将其更新为具有 minimum_packet_rate 规则的 QoS 策略将不会导致 placement allocation 记录。在这种情况下,仅会发生数据平面强制执行。

注意

仍然无法更改附加到绑定到虚拟机的端口的 QoS 策略的 minimum_packet_rate 规则。

  • 当 QoS 与 trunk 一起使用时,Placement 强制执行仅应用于 trunk 的父端口。子端口将不会有 Placement 分配。作为解决方法,父端口 QoS 策略应考虑子端口的需求并请求足够的最小包速率资源以适应 trunk 中的每个端口。

Placement 先决条件

Placement 必须支持 微版本 1.36。这最早在 Train 中发布。

Nova 先决条件

Nova 必须支持 微版本 2.72 的顶部,此外,Nova Xena 版本需要支持新的 port-resource-request-groups Neutron API 扩展。

并非所有 Nova virt 驱动程序都受支持,请参阅 Nova 管理指南的 Virt 驱动程序支持 部分。

Neutron 先决条件

Neutron 必须支持以下 API 扩展

  • qos-pps-minimum

  • port-resource-request-groups

这些最早在 Yoga 中发布。

Neutron DB 清理

Neutron 端口的 resource_request 字段用于表达端口的资源需求。此信息是从附加到端口的 QoS 策略规则计算得出的。最初,只有最小带宽规则用作请求资源的来源。 resource_request 的格式如下

{
    "required": [<CUSTOM_PHYSNET_ traits>, <CUSTOM_VNIC_TYPE traits>],
    "resources":
    {
        <NET_BW_[E|I]GR_KILOBIT_PER_SEC resource class name>:
            <requested bandwidth amount from the QoS policy>
    }
},

这种结构允许描述单个资源和特征组,这在当时已经足够了。但是,随着 QoS 最小包速率规则的引入,端口现在可以有多个请求资源的来源和特征。因此,resource_request 字段的格式无法表达这样的请求,因此必须更改。

为了解决这个问题,Neutron Yoga 版本中添加了 port-resource-request-groups 扩展。它支持新的 resource_request 字段格式,允许从同一 RP 子树请求多个资源和特征组。新格式如下

{
    "request_groups":
    [
        {
            "id": <min-pps-group-uuid>
            "required": [<CUSTOM_VNIC_TYPE traits>],
            "resources":
            {
                NET_PACKET_RATE_[E|I]GR_KILOPACKET_PER_SEC:
                    <amount requested via the QoS policy>
            }
        },
        {
            "id": <min-bw-group-uuid>
            "required": [<CUSTOM_PHYSNET_ traits>,
                         <CUSTOM_VNIC_TYPE traits>],
            "resources":
            {
                <NET_BW_[E|I]GR_KILOBIT_PER_SEC resource class name>:
                    <requested bandwidth amount from the QoS policy>
            }
        }
    ],
    "same_subtree":
    [
        <min-pps-group-uuid>,
        <min-bw-group-uuid>
    ]
}

resource_request 字段新结构的主要缺点是缺乏向后兼容性。如果 Neutron DB 的 ml2_port_bindings 表包含在引入 port-resource-request-groups 扩展之前创建的端口绑定,则可能导致问题。由于 port-resource-request-groups 扩展在 Yoga 版本中默认启用,因此在将 Neutron 升级到 Yoga 之前,必须执行 DB 清理。

DB 清理将确保 ml2_port_bindings 表的每一行都使用新格式。可以在 DB 清理之前运行升级检查,以查看 DB 中是否有任何需要清理的行。

$ neutron-status upgrade check
# If 'Port Binding profile sanity check' fails, DB sanitization is needed
$ neutron-sanitize-port-binding-profile-allocation --config-file /etc/neutron/neutron.conf

支持的驱动程序和代理

在 Yoga 版本中,以下基于代理的 ML2 机制驱动程序受支持

  • Open vSwitch (openvswitch) vnic_types:normaldirect

neutron-server 配置

QoS 最小包速率规则需要与 QoS 最小带宽规则在 neutron-server 中完全相同的配置。有关更多详细信息,请参阅 服务质量 (QoS):保证最小带宽指南neutron-server config 部分。

neutron-openvswitch-agent 配置

将代理配置设置为可用资源的真实来源。根据 OVS 部署类型,可以使用以下方式配置包处理能力

无论使用无方向或有方向的包处理模式,配置始终应用于整个 OVS 实例。

注意

egress / ingress 是指从 VM 的角度来看的。也就是说,egress = 云服务器上传,ingress = 下载。

可用出口和入口包速率值以 kilo packet/sec (kpps) 为单位。

无方向和有方向模式是互斥选项。一次只能使用一个。

超管名称是可选的,仅在罕见情况下才需要设置。有关更多信息,请参阅 Neutron 代理文档。

如果需要,可以通过设置 ovs.resource_provider_packet_processing_inventory_defaults 来调整每个代理的基础资源提供程序库存字段。有效值是所有 更新资源提供程序库存调用的可选参数

/etc/neutron/plugins/ml2/ovs_agent.ini(在计算和网络节点上)

[ovs]
resource_provider_packet_processing_with_direction = :10000000:10000000,...
#resource_provider_packet_processing_inventory_defaults = step_size:1000,...

资源信息传播

资源信息传播在 服务质量 (QoS):保证最小带宽指南 中有详细说明。

示例用法

网络和 QoS 策略(及其规则)通常由云管理员预先创建

# as admin

$ openstack network create net0

$ openstack subnet create subnet0 \
    --network net0 \
    --subnet-range 10.0.4.0/24

$ openstack network qos policy create policy0

$ openstack network qos rule create policy0 \
    --type minimum-packet-rate \
    --min-kpps 1000000 \
    --egress

$ openstack network qos rule create policy0 \
    --type minimum-packet-rate \
    --min-kpps 1000000 \
    --ingress

然后,普通用户可以使用预创建的策略来创建端口并使用这些端口启动服务器

# as an unprivileged user

# an ordinary soft-switched port: ``--vnic-type normal`` is the default
$ openstack port create port-normal-qos \
    --network net0 \
    --qos-policy policy0

$ openstack server create server0 \
    --os-compute-api-version 2.72 \
    --flavor cirros256 \
    --image cirros-0.5.2-x86_64-disk \
    --port port-normal-qos

关于分配的修复

由于 Placement 具有云部署资源的全局视图(可用资源、已用资源),因此在某些情况下,它可能会与现实不同步。

一个重要的情况源于 OpenStack 没有分布式事务来分配由多个 OpenStack 组件(此处为 Nova 和 Neutron)提供的资源。存在已知的竞争条件,Placement 的视图可能会与现实不同步。设计有意识地将竞争条件窗口降至最低,但已知存在问题

  • 如果在 Nova 读取端口的 resource_request 之后修改了 QoS 策略,但在端口绑定其状态之前,将应用修改前的状态。

  • 如果删除了带有资源分配的已绑定端口。分配会泄漏。https://bugs.launchpad.net/nova/+bug/1820588

注意

删除已绑定的端口没有已知的用例。请考虑先通过 openstack server remove port 分离接口。

可以通过以下方式修复不正确的分配

调试

  • Nova 运行的是否至少是 Xena 版本,Neutron 运行的是否至少是 Yoga 版本?

  • 是否可用 qos-pps-minimumport-resource-request-groups 扩展?

$ openstack extension show qos-pps-minimum
$ openstack extension show port-resource-request-groups
  • Neutron-server 中是否启用了 placement 服务插件?

  • 相关的 neutron agent 是否配置了 resource_provider_packet_processing_with_directionresource_provider_packet_processing_without_direction

  • 更改配置文件后,是否重启了 agent?

  • resource_provider_packet_processing_with_directionresource_provider_packet_processing_without_direction 是否已到达 neutron-server?

# as admin
$ openstack network agent show ... -c configuration -f json

请在 资源信息传播 部分查找示例。

  • neutron-server 是否已成功同步到 Placement?

# as admin
$ openstack network agent show ... | grep resources_synced

请在 资源信息传播 部分查找示例。

  • 资源提供者树是否正确?根节点是否为计算主机?下一层是否为 agent?

$ openstack --os-placement-api-version 1.17 resource provider list
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
| uuid                                 | name                                     | generation | root_provider_uuid                   | parent_provider_uuid                 |
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
| 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | devstack0                                |          2 | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | None                                 |
| 89ca1421-5117-5348-acab-6d0e2054239c | devstack0:Open vSwitch agent             |          0 | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd |
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
  • Placement 是否具有预期的 traits?

# as admin
$ openstack --os-placement-api-version 1.17 trait list | awk '/CUSTOM_/ { print $2 }' | sort
CUSTOM_VNIC_TYPE_NORMAL
CUSTOM_VNIC_TYPE_SMART_NIC
CUSTOM_VNIC_TYPE_VDPA
  • OVS agent 资源提供者是否具有正确的 trait 关联和库存?

# as admin
$ openstack --os-placement-api-version 1.17 resource provider trait list <RP-UUID>
$ openstack --os-placement-api-version 1.17 resource provider inventory list <RP-UUID>
  • QoS 策略是否具有 minimum-packet-rate 规则?

  • 端口是否具有正确的策略?

  • 端口是否具有 resource_request

# as admin
$ openstack port show port-normal-qos | grep resource_request
  • 服务器启动时是否使用了端口(而不是网络)?

  • nova 是否已在 Placement 中为服务器分配资源?

# as admin
$ openstack --os-placement-api-version 1.17 resource provider allocation show <SERVER-UUID>
  • 分配是否在预期的 OVS agent 资源提供者上?

# as admin
$ openstack --os-placement-api-version 1.17 resource provider show --allocations <RP-UUID>
  • Placement 是否能够在调度期间为 nova 生成分配候选列表?

  • nova 是否成功调度了服务器?

  • nova 是否告知 neutron 分配了哪个 OVS agent 资源提供者以满足数据包速率请求?

# as admin
$ openstack port show port-normal-qos | grep binding.profile.*allocation
  • neutron 是否成功绑定了端口?