
Привет, Хабр! Мы уже разбирали 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.
