Не всё трафику одинаково: QoS в OpenStack Neutron

Привет, Хабр! Мы уже разбирали OVN в связке с OpenStack и трассировку пакетов. А сегодня предлагаем почитать перевод документации про Quality of Service (QoS) в Neutron: что это, какие правила поддерживаются, как настроить и как работать с политиками.
Навигация по тексту
QoS (Quality of Service, управление качеством обслуживания) — механизм, который позволяет управлять определенными сетевыми параметрами: пропускной способностью, задержкой, джиттером. Это нужно для выполнения SLA между провайдером приложения и конечными пользователями.
Сетевые устройства — коммутаторы и маршрутизаторы — могут классифицировать и маркировать трафик, а также применять к нему политики приоритизации, ограничения скорости (policing) и сглаживания (shaping). Это особенно важно для чувствительных к задержкам приложений, таких как VoIP и видеостриминг.
В OpenStack QoS реализован как отдельный сервисный плагин. Он слабо связан с остальным кодом Neutron и подключается через ml2 extension driver.
Поддерживаемые типы правил QoS
Актуальный список типов правил определён в VALID_RULE_TYPES в constants.py:
-
bandwidth_limit — ограничение пропускной способности для сетей, портов или плавающих IP.
-
packet_rate_limit — ограничение частоты пакетов для определенных типов трафика.
-
dscp_marking — маркировка трафика значением DSCP.
-
minimum_bandwidth — гарантия минимальной полосы пропускания.
-
minimum_packet_rate — гарантия минимальной частоты пакетов.
Каждый QoS-драйвер указывает, какие типы правил он поддерживает, через свойство supported_rules. QoS driver manager пересчитывает этот список динамически.
Поддержка правил по бэкендам и направлениям трафика (с точки зрения ВМ):
|
Правило |
Open vSwitch |
SR-IOV |
OVN |
|
Bandwidth limit |
Egress / Ingress |
Egress ¹ |
Egress / Ingress |
|
Packet rate limit |
Egress / Ingress |
— |
— |
|
Minimum bandwidth |
Egress / Ingress ² |
Egress / Ingress ² |
Egress / Ingress ² |
|
Minimum packet rate |
— |
— |
— |
|
DSCP marking |
Egress |
— |
Egress |
¹ Параметр max burst не поддерживается утилитой ip.
² Placement-based enforcement работает в обоих направлениях, но поддержка dataplane зависит от бэкенда.
Для правила minimum bandwidth по бекендам и направлениям:
|
Тип принуждения |
Open vSwitch |
SR-IOV |
OVN |
|
Dataplane |
Egress ³ |
Egress ¹ |
Egress ⁴ |
|
Placement |
Egress/Ingress ² |
Egress/Ingress ² |
Egress/Ingress ⁴ |
¹ Начиная с Newton.
² Начиная с Stein.
³ Только для сетей без туннелирования (VLAN и flat).
⁴ Начиная с Zed.
SR-IOV агент не поддерживает dataplane enforcement для портов с direct-physical vnic_type, однако начиная с Yoga Placement enforcement для этого типа работает.
Для minimum packet rate поддержка через Placement появилась в Yoga (только для Open vSwitch, направление any/Egress/Ingress). Dataplane enforcement не реализован ни для одного из бэкендов.
Для ml2-плагина список поддерживаемых типов правил — это пересечение правил, поддерживаемых всеми активными mechanism driver’ами. Правило QoS всегда привязано к политике QoS. При создании или обновлении правила:
-
если политика не привязана ни к одному порту или сети — проверяется поддержка правила хотя бы одним активным mechanism driver;
-
если политика привязана — проверяется поддержка драйверами, управляющими конкретными портами.
Допустимые значения DSCP
Допустимые значения DSCP — чётные числа от 0 до 56, исключая 2–6, 42 и 50–54. Полный список:
0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 44, 46, 48, 56
QoS в L3-сервисах
QoS-политики применимы к плавающим IP-адресам (Floating IP) и к маршрутизаторам — в последнем случае политика действует на gateway-порт.
ML2/OVS
Поддерживаются только правила ограничения полосы:
Floating IP bandwidth limit — лимит применяется к каждому Floating IP независимо.
Gateway IP bandwidth limit — лимит действует на gateway-порт в namespace маршрутизатора (или SNAT namespace для DVR edge router). Ограничение применяется ко всему трафику через gateway IP; на Floating IP-трафик не распространяется.
ML2/OVN
Поддерживаются и rate limit, и DSCP. Оба типа политик применяются через QoS metering rules.
Floating IP — трафик матчится по gateway-порту и адресу Floating IP; порт может быть централизованным или распределенным.
Gateway port — трафик матчится по gateway chassis port.
Если к порту и к Floating IP/маршрутизатору одновременно привязаны политики, приоритеты работают так:
-
Rate limit: применяется минимальное из всех значений.
-
DSCP: маркировка Floating IP/маршрутизатора применяется на исходящий пакет.
Если политики привязаны и к маршрутизатору, и к Floating IP — приоритет всегда у политики Floating IP.
L3-сервисы, реализующие QoS-расширения
L3 router — ограничение полосы реализовано через Linux TC.
OVN L3 — через OVN QoS metering rules.
Поддержка bandwidth limiting: оба L3-сервиса поддерживают Egress и Ingress для Floating IP и Gateway IP.
DSCP marking поддерживается только в OVN L3 (только Egress) для Floating IP и Gateway IP.
Настройка
Предполагается стандартная архитектура, описанная в Networking architecture.
На контроллерных нодах
Добавить qos в service_plugins в /etc/neutron/neutron.conf:
service_plugins = router,metering,qos
Опционально — задать notification_drivers в секции [qos] (по умолчанию message_queue).
Для поддержки QoS на Floating IP (qos-fip) в service_plugins должны быть и router, и qos:
service_plugins = router,qos
В /etc/neutron/plugins/ml2/ml2_conf.ini добавить qos в extension_drivers:
extension_drivers = port_security,qos
В конфигурационном файле агента (/etc/neutron/plugins/ml2/<agent_name>_agent.ini) добавить qos в extensions:
[agent]
extensions = qos
На сетевых и вычислительных нодах
Аналогично добавить qos в extensions агента.
Опционально для Open vSwitch — включить qos_meter_bandwidth:
[ovs]
qos_meter_bandwidth = True
Для QoS на Floating IP добавить fip_qos в /etc/neutron/l3_agent.ini. Если включён DVR — для всех L3-агентов:
[agent]
extensions = fip_qos
Начиная с Stein поддержка bandwidth limit распространяется на Floating IP, привязанный к neutron-порту или к port forwarding.
Для QoS на gateway IP добавить gateway_ip_qos (для агентов типа dvr_snat или legacy):
[agent]
extensions = gateway_ip_qos
Совместно с fip_qos это ограничивает все L3 IP с привязанными QoS-политиками:
[agent]
extensions = fip_qos, gateway_ip_qos
Ограничение полосы не работает на OVS-портах типа internal. В качестве workaround для gateway-портов маршрутизатора — включить ovs_use_veth:
[DEFAULT]
ovs_use_veth = True
QoS сейчас работает только с ml2 (поддерживаемые драйверы — SR-IOV и Open vSwitch).
DSCP-маркировка внешнего заголовка для overlay-сетей
При использовании overlay-сетей (например, VxLAN) DSCP-маркировка применяется только к внутреннему заголовку. При инкапсуляции метка не копируется во внешний заголовок автоматически.
Чтобы задать значение DSCP для внешнего заголовка:
[agent]
dscp = 8
Чтобы скопировать DSCP из внутреннего заголовка во внешний:
[agent]
dscp_inherit = true
Если dscp_inherit = true, значение из параметра dscp игнорируется.
Настройка policy.yaml для доверенных проектов
Если пользователям проектов разрешено самостоятельно управлять QoS-политиками, нужно скорректировать /etc/neutron/policy.yaml:
"get_policy": "rule:regular_user"
"create_policy": "rule:regular_user"
"update_policy": "rule:regular_user"
"delete_policy": "rule:regular_user"
"get_rule_type": "rule:regular_user"
Для каждого типа правил — аналогичный набор записей (get/create/update/delete). Пример для bandwidth limit:
"get_policy_bandwidth_limit_rule": "rule:regular_user"
"create_policy_bandwidth_limit_rule": "rule:regular_user"
"delete_policy_bandwidth_limit_rule": "rule:regular_user"
"update_policy_bandwidth_limit_rule": "rule:regular_user"
То же — для dscp_marking_rule, minimum_bandwidth_rule, minimum_packet_rate_rule.
Пользовательский сценарий
По умолчанию QoS-политики создают только администраторы. Если проекты настроены как доверенные — пользователи могут создавать политики самостоятельно.
Создание политики и правила ограничения полосы
Важно про burst. Правильно подобранное значение burst критично для корректной работы bandwidth limit в агенте Open vSwitch. Слишком маленький burst будет дросселировать трафик даже при правильно заданном лимите; слишком большой — пропускать пакеты сверх лимита. Для TCP-трафика рекомендуется задавать burst на уровне 80% от значения лимита: например, при лимите 1000 кбит/с — burst 800 кбит. Если не задавать burst явно, он по умолчанию составит 80% от лимита.
Привязка политики к порту
$ openstack port list
$ openstack port set --qos-policy bw-limiter <port-id>
Отвязать политику:
$ openstack port unset --qos-policy <port-id>
Порт можно создать сразу с привязанной политикой:
$ openstack port create --qos-policy bw-limiter --network private port1
Привязка политики к сети
При привязке политики к сети все compute-порты в этой сети наследуют её по умолчанию — если только к конкретному порту не привязана своя политика. Внутренние порты (DHCP, маршрутизатор) под сетевую политику не попадают.
$ openstack network set --qos-policy bw-limiter private
Привязка политики к Floating IP
$ openstack floating ip set --qos-policy bw-limiter <floating-ip-id>
Отвязать:
$ openstack floating ip set --no-qos-policy <floating-ip-id>
# или
$ openstack floating ip unset --qos-policy <floating-ip-id>
Floating IP можно создать сразу с политикой:
$ openstack floating ip create --qos-policy bw-limiter public
Правила QoS, привязанные к Floating IP, активируются только после его ассоциации с портом. Политика применяется именно к Floating IP, а не к порту — qos_policy_id порта при этом не меняется.
Агент L3 для Floating IP поддерживает только правила bandwidth_limit. Другие типы (например, DSCP) игнорируются.
Каждый проект может иметь одну политику QoS по умолчанию. Если она задана, все новые сети проекта автоматически получают её — если при создании не указана другая политика.
$ openstack network qos policy create --default bw-limiter
$ openstack network qos policy set --no-default bw-limiter
Ограничение частоты пакетов
$ openstack network qos policy create pps-limiter
$ openstack network qos rule create --max-kpps 1000 --max-burst-kpps 100
--ingress --type packet-rate-limit pps-limiter
$ openstack network qos rule create --max-kpps 1000 --max-burst-kpps 100
--egress --type packet-rate-limit pps-limiter
Единица измерения — тысяч пакетов в секунду (kpps).
Применить к порту:
$ openstack port set --qos-policy pps-limiter <port-id>
Packet rate limit поддерживается только ml2 ovs driver. Используется meter action в ovs kernel datapath (ядро >= 4.15) или
userspace ovs dpdk datapath.
Административное принуждение
Если политика не является общей (shared), проект не сможет отвязать её от порта или сети, если она была привязана администратором. Если политика общая — проект вправе самостоятельно привязывать и отвязывать её от своих объектов.
Изменение правил в runtime
Правила можно менять на лету — изменения применятся ко всем привязанным портам:
$ openstack network qos rule set --max-kbps 2000 --max-burst-kbits 1600
--ingress bw-limiter 92ceb52f-170f-49d0-9528-976e2fee2d6f
$ openstack network qos rule show
bw-limiter 92ceb52f-170f-49d0-9528-976e2fee2d6f
+----------------+--------------------------------------+
| Field | Value |
+----------------+--------------------------------------+
| direction | ingress |
| id | 92ceb52f-170f-49d0-9528-976e2fee2d6f |
| max_burst_kbps | 1600 |
| max_kbps | 2000 |
| name | None |
| project_id | |
+----------------+--------------------------------------+
DSCP-маркировка
$ openstack network qos policy create dscp-marking
+------------+--------------------------------------+
| Field | Value |
+------------+--------------------------------------+
| description| |
| id | d1f90c76-fbe8-4d6f-bb87-a9aea997ed1e |
| is_default | False |
| name | dscp-marking |
| project_id | 4db7c1ed114a4a7fb0f077148155c500 |
| rules | [] |
| shared | False |
+------------+--------------------------------------+
$ openstack network qos rule create --type dscp-marking --dscp-mark 26
dscp-marking
+-----------+--------------------------------------+
| Field | Value |
+-----------+--------------------------------------+
| dscp_mark | 26 |
| id | 115e4f70-8034-4176-8fe9-2c47f8878a7d |
| name | None |
| project_id| |
+-----------+--------------------------------------+
$ openstack network qos rule set --dscp-mark 22
dscp-marking 115e4f70-8034-4176-8fe9-2c47f8878a7d
$ openstack network qos rule list dscp-marking
+--------------------------------------+-----------+
| ID | DSCP Mark |
+--------------------------------------+-----------+
| 115e4f70-8034-4176-8fe9-2c47f8878a7d | 22 |
+--------------------------------------+-----------+
$ openstack network qos rule show
dscp-marking 115e4f70-8034-4176-8fe9-2c47f8878a7d
+-----------+--------------------------------------+
| Field | Value |
+-----------+--------------------------------------+
| dscp_mark | 22 |
| id | 115e4f70-8034-4176-8fe9-2c47f8878a7d |
| name | None |
| project_id| |
+-----------+--------------------------------------+
$ openstack network qos rule delete
dscp-marking 115e4f70-8034-4176-8fe9-2c47f8878a7d
Комбинирование правил в одной политике
В одной политике можно совмещать несколько правил — при условии, что тип или направление каждого из них различаются. Например, два правила bandwidth-limit (egress и ingress) и одно minimum-bandwidth:
$ openstack network qos rule create --type bandwidth-limit
--max-kbps 50000 --max-burst-kbits 50000 --egress bandwidth-control
+----------------+--------------------------------------+
| Field | Value |
+----------------+--------------------------------------+
| direction | egress |
| id | 0db48906-a762-4d32-8694-3f65214c34a6 |
| max_burst_kbps | 50000 |
| max_kbps | 50000 |
| name | None |
| project_id | |
+----------------+--------------------------------------+
$ openstack network qos rule create --type bandwidth-limit
--max-kbps 10000 --max-burst-kbits 10000 --ingress bandwidth-control
+----------------+--------------------------------------+
| Field | Value |
+----------------+--------------------------------------+
| direction | ingress |
| id | faabef24-e23a-4fdf-8e92-f8cb66998834 |
| max_burst_kbps | 10000 |
| max_kbps | 10000 |
| name | None |
| project_id | |
+----------------+--------------------------------------+
$ openstack network qos rule create --type minimum-bandwidth
--min-kbps 1000 --egress bandwidth-control
+-----------+--------------------------------------+
| Field | Value |
+-----------+--------------------------------------+
| direction | egress |
| id | da858b32-44bc-43c9-b92b-cf6e2fa836ab |
| min_kbps | 1000 |
| name | None |
| project_id| |
+-----------+--------------------------------------+
$ openstack network qos policy show bandwidth-control
+-----------------+--------------------------------------+
| Field | Value |
+-----------------+--------------------------------------+
| description | |
| id | 8491547e-add1-4c6c-a50e-42121237256c |
| is_default | False |
| name | bandwidth-control |
| project_id | 7cc5a84e415d48e69d2b06aa67b317d8 |
| revision_number | 4 |
| rules | [{u'max_kbps': 50000, |
| | u'direction': u'egress', |
| | u'type': u'bandwidth_limit', |
| | u'id': u'0db48906-a762-4d32-8694-3f65214c34a6',|
| | u'max_burst_kbps': 50000, |
| | u'qos_policy_id': u'8491547e-add1-4c6c-a50e-42121237256c'},|
| | {u'max_kbps': 10000, |
| | u'direction': u'ingress', |
| | u'type': u'bandwidth_limit', |
| | u'id': u'faabef24-e23a-4fdf-8e92-f8cb66998834',|
| | u'max_burst_kbps': 10000, |
| | u'qos_policy_id': u'8491547e-add1-4c6c-a50e-42121237256c'},|
| | {u'direction': u'egress', |
| | u'min_kbps': 1000, |
| | u'type': u'minimum_bandwidth', |
| | u'id': u'da858b32-44bc-43c9-b92b-cf6e2fa836ab',|
| | u'qos_policy_id': u'8491547e-add1-4c6c-a50e-42121237256c'}]|
| shared | False |
+-----------------+--------------------------------------+
Политика с правилом minimum bandwidth обеспечивает best-effort соблюдение минимальной полосы — полная гарантия пока не реализована, поскольку QoS не интегрирован с планировщиком Compute.
Автор: runity

