Most Networking Quality of Service (QoS) features are implemented solely by OpenStack Neutron and they are already documented in the QoS configuration chapter of the Networking Guide. Some more complex QoS features necessarily involve the scheduling of a cloud server, therefore their implementation is shared between OpenStack Nova, Neutron and Placement. As of the OpenStack Stein release the Guaranteed Minimum Bandwidth feature is like the latter.
This Networking Guide chapter does not aim to replace Nova or Placement documentation in any way, but it still hopes to give an overall OpenStack-level guide to understanding and configuring a deployment to use the Guaranteed Minimum Bandwidth feature.
A guarantee of minimum available bandwidth can be enforced on two levels:
In short the enforcement has two levels:
Since the data plane enforcement is already documented in the QoS chapter, here we only document the placement-level enforcement.
minimum-bandwidth
rule must be passed
when booting a server (openstack server create
). Passing a network
with a minimum-bandwidth rule at boot is not supported because of
technical reasons (in this case the port is created too late for
Neutron to affect scheduling).minimum_bandwidth
rule, or changing the min_kbps
field of a
minimum_bandwidth
rule) is only possible while the policy is not in
effect. That is ports of the QoS policy are not yet used by Nova. Requests
to change guarantees of in-use policies are rejected.minimum_bandwidth
QoS rule, but no resource allocation in Placement)
are rejected now in a backward-incompatible way.Placement must support microversion 1.29. This was first released in Rocky.
Nova must support microversion 2.72. This was first released in Stein.
Not all Nova virt drivers are supported, please refer to the Virt Driver Support section of the Nova Admin Guide.
Neutron must support the following API extensions:
agent-resources-synced
port-resource-request
qos-bw-minimum-ingress
These were all first released in Stein.
In release Stein the following agent-based ML2 mechanism drivers are supported:
openvswitch
) vnic_types: normal
, direct
sriovnicswitch
) vnic_types: direct
, macvtap
The placement
service plugin synchronizes the agents’ resource
provider information from neutron-server to Placement.
Since neutron-server talks to Placement you need to configure how neutron-server should find Placement and authenticate to it.
/etc/neutron/neutron.conf
(on controller nodes):
[DEFAULT]
service_plugins = placement,...
auth_strategy = keystone
[placement]
auth_type = password
auth_url = https://controller/identity
password = secret
project_domain_name = Default
project_name = service
user_domain_name = Default
username = placement
If a vnic_type is supported by default by multiple ML2 mechanism
drivers (e.g. vnic_type=direct
by both openvswitch
and
sriovnicswitch
) and multiple agents’ resources are also meant to be
tracked by Placement, then the admin must decide which driver to take
ports of that vnic_type by blacklisting the vnic_type for the unwanted
drivers. Use ovs_driver.vnic_type_blacklist
in this
case. Valid values are all the supported_vnic_types
of the
respective mechanism drivers.
/etc/neutron/plugins/ml2/ml2_conf.ini
(on controller nodes):
[ovs_driver]
vnic_type_blacklist = direct
[sriov_driver]
#vnic_type_blacklist = direct
Set the agent configuration as the authentic source of
the resources available. Set it on a per-bridge basis by
ovs.resource_provider_bandwidths
.
The format is: bridge:egress:ingress,...
You may set only one direction and omit the other.
Note
egress
/ ingress
is meant from the perspective of a cloud server.
That is egress
= cloud server upload, ingress
= download.
Egress and ingress available bandwidth values are in kilobit/sec (kbps)
.
If desired, resource provider inventory fields can be tweaked on a
per-agent basis by setting
ovs.resource_provider_inventory_defaults
.
Valid values are all the
optional parameters of the update resource provider inventory call.
/etc/neutron/plugins/ml2/ovs_agent.ini
(on compute and network nodes):
[ovs]
bridge_mappings = physnet0:br-physnet0,...
resource_provider_bandwidths = br-physnet0:10000000:10000000,...
#resource_provider_inventory_defaults = step_size:1000,...
The configuration of neutron-sriov-agent is analog to that of neutron-openvswitch-agent. However look out for:
sriov_nic.resource_provider_bandwidths
./etc/neutron/plugins/ml2/sriov_agent.ini
(on compute nodes):
[sriov_nic]
physical_device_mappings = physnet0:ens5,physnet0:ens6,...
resource_provider_bandwidths = ens5:40000000:40000000,ens6:40000000:40000000,...
#resource_provider_inventory_defaults = step_size:1000,...
The flow of information is different for available and used resources.
The authentic source of available resources is neutron agent configuration -
where the resources actually exist, as described in the agent configuration
sections above. This information is propagated in the following chain:
neutron-l2-agent -> neutron-server -> Placement
.
From neutron agent to server the information is included in the
configurations
field of the agent heartbeat message sent on the message
queue periodically.
# as admin
$ openstack network agent list --agent-type open-vswitch --host devstack0
+--------------------------------------+--------------------+-----------+-------------------+-------+-------+---------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+--------------------+-----------+-------------------+-------+-------+---------------------------+
| 5e57b85f-b017-419a-8745-9c406e149f9e | Open vSwitch agent | devstack0 | None | :-) | UP | neutron-openvswitch-agent |
+--------------------------------------+--------------------+-----------+-------------------+-------+-------+---------------------------+
# output shortened and pretty printed
# note: 'configurations' on the wire, but 'configuration' in the cli
$ openstack network agent show -f value -c configuration 5e57b85f-b017-419a-8745-9c406e149f9e
{'bridge_mappings': {'physnet0': 'br-physnet0'},
'resource_provider_bandwidths': {'br-physnet0': {'egress': 10000000,
'ingress': 10000000}},
'resource_provider_inventory_defaults': {'allocation_ratio': 1.0,
'min_unit': 1,
'reserved': 0,
'step_size': 1},
...
}
Re-reading the resource related subset of configuration on SIGHUP
is not
implemented. The agent must be restarted to pick up and send changed
configuration.
Neutron-server propagates the information further to Placement for the resources of each agent via Placement’s HTTP REST API. To avoid overloading Placement this synchronization generally does not happen on every received heartbeat message. Instead the re-synchronization of the resources of one agent is triggered by:
openstack network
agent list
). Please note that deleting an agent record and letting the
next heartbeat to re-create it can be used to trigger synchronization
without restarting an agent.start_flag
being present in the
heartbeat message).Both of these can be used by an admin to force a re-sync if needed.
The success of a synchronization attempt from neutron-server to Placement is
persisted into the relevant agent’s resources_synced
attribute. For
example:
# as admin
$ openstack network agent show -f value -c resources_synced 5e57b85f-b017-419a-8745-9c406e149f9e
True
resources_synced
may take the value True, False and None:
In case resources_synced
is not True for an agent, neutron-server
does try to re-sync on receiving every heartbeat message from that
agent. Therefore it should be able to recover from transient errors
of Neutron-Placement communication (e.g. Placement being started later
than Neutron).
It is important to note that the restart of neutron-server does not trigger any kind of re-sync to Placement (to avoid an update storm).
As mentioned before, the information flow for resources requested and (if proper) allocated is different. It involves a conversation between Nova, Neutron and Placement.
resource_request
attribute of that port.binding:profile.allocation
sub-attribute of that port.For details please see slides 13-15 of a (pre-release) demo that was presented on the Berlin Summit in November 2018.
Physnets and QoS policies (together with their rules) are usually pre-created by a cloud admin:
# as admin
$ openstack network create net0 \
--provider-network-type vlan \
--provider-physical-network physnet0 \
--provider-segment 100
$ 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-bandwidth \
--min-kbps 1000000 \
--egress
$ openstack network qos rule create policy0 \
--type minimum-bandwidth \
--min-kbps 1000000 \
--ingress
Then a normal user can use the pre-created policy to create ports and boot servers with those ports:
# 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
# alternatively an SR-IOV port, unused in this example
$ openstack port create port-direct-qos \
--network net0 \
--vnic-type direct \
--qos-policy policy0
$ openstack server create server0 \
--flavor cirros256 \
--image cirros-0.4.0-x86_64-disk \
--port port-normal-qos
Since Placement carries a global view of a cloud deployment’s resources (what is available, what is used) it may in some conditions get out of sync with reality.
One important case is when the data-plane-only Minimum Guaranteed Bandwidth feature was used before Stein (first released in Newton). Since before Stein guarantees were not enforced during server placement the available resources may have become overallocated without notice. In this case Placement’s view and the reality of resource usage should be made consistent during/after an upgrade to Stein.
Another case stems from OpenStack not having distributed transactions to allocate resources provided by multiple OpenStack components (here Nova and Neutron). There are known race conditions in which Placement’s view may get out of sync with reality. The design knowingly minimizes the race condition windows, but there are known problems:
resource_request
but before the port is bound its state before the modification will be
applied.Note
Deleting a bound port has no known use case. Please consider detaching
the interface first by openstack server remove port
instead.
Incorrect allocations may be fixed by:
placement
service plugin enabled in neutron-server?resource_provider_bandwidths
configured for the relevant neutron
agent?resource_provider_bandwidths
aligned with bridge_mappings
or
physical_device_mappings
?resource_provider_bandwidths
reaching neutron-server?# as admin
$ openstack network agent show ... | grep configurations
Please find an example in section Propagation of resource information.
# as admin
$ openstack network agent show ... | grep resources_synced
Please find an example in section Propagation of resource information.
$ 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 |
| 4a8a819d-61f9-5822-8c5c-3e9c7cb942d6 | devstack0:NIC Switch agent | 0 | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd |
| 1c7e83f0-108d-5c35-ada7-7ebebbe43aad | devstack0:NIC Switch agent:ens5 | 2 | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | 4a8a819d-61f9-5822-8c5c-3e9c7cb942d6 |
| 89ca1421-5117-5348-acab-6d0e2054239c | devstack0:Open vSwitch agent | 0 | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd |
| f9c9ce07-679d-5d72-ac5f-31720811629a | devstack0:Open vSwitch agent:br-physnet0 | 2 | 3b36d91e-bf60-460f-b1f8-3322dee5cdfd | 89ca1421-5117-5348-acab-6d0e2054239c |
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
# as admin
$ openstack --os-placement-api-version 1.17 trait list | awk '/CUSTOM_/ { print $2 }' | sort
CUSTOM_PHYSNET_PHYSNET0
CUSTOM_VNIC_TYPE_DIRECT
CUSTOM_VNIC_TYPE_DIRECT_PHYSICAL
CUSTOM_VNIC_TYPE_MACVTAP
CUSTOM_VNIC_TYPE_NORMAL
# 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
minimum-bandwidth
rule?resource_request
?# as admin
$ openstack port show port-normal-qos | grep resource_request
# as admin
$ openstack --os-placement-api-version 1.17 resource provider allocation show SERVER-UUID
# as admin
$ openstack --os-placement-api-version 1.17 resource provider show --allocations RP-UUID
# as admin
$ openstack port show port-normal-qos | grep binding.profile.*allocation
resource_request
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.