QoS Качество обслуживания: классификация, маркировка, очереди
Полоса пропускания не бесконечна, а трафик неоднороден: голосовой звонок умирает от 150 мс задержки, а большой бэкап готов ждать. QoS (Quality of Service) — это набор механизмов, который решает, чей пакет важнее, когда канал перегружен. Не «ускорить всё» (это невозможно), а осознанно распределить дефицит: кому приоритет, кого притормозить, кого выбросить первым.
«Заявка #54230. Филиал „Юг“: в часы пик (10:00–12:00) IP-телефония заикается и рвётся, при этом файлы с сервера качаются нормально. Канал до филиала 20 Мбит/с, загрузка по графикам — до 100% в пиковые часы. Директор филиала требует „расширить канал“». Спойлер: расширение канала здесь — не первое и не единственное решение. Голос умирает не от нехватки мегабит (звонку хватает 0,1 Мбит/с!), а от того, что его пакеты стоят в общей очереди за большими файлами. Разруливание таких очередей — и есть QoS. К концу урока ты сможешь и объяснить это директору, и настроить.
- Назвать четырёх «врагов» трафика (bandwidth, delay, jitter, loss) и кто из них убивает голос
- Объяснить, почему победил DiffServ, а не IntServ
- Показать, где живёт маркировка: CoS (L2) и ToS/DSCP (L3) — побитно
- Расшифровать стандартные классы PHB: EF, AF, CS, Default
- Провести trust boundary: чьим меткам верить, чьи переписывать
- Выбрать policing или shaping под задачу — и обосновать
- Собрать иерархию очередей LLQ/CBWFQ и конфиг MQC под заявку #54230
- Прочитать show policy-map interface и найти класс, в котором дропается голос
- Объяснить bufferbloat и почему большой буфер — враг задержки
- Перенести всё это в DevOps: tc/qdisc в Linux, DSCP в облаке
Модуль 3: VLAN-тег 802.1Q — сегодня выяснится, что в нём есть 3 бита приоритета (CoS). Модуль 5: каждый роутер принимает решение сам, hop-by-hop — QoS работает так же: политика должна быть согласована на каждом хопе пути. Модуль 4: заголовок IPv4 — поле ToS, которое мы тогда пропустили, сегодня главный герой.
1. Четыре характеристики, которые портят трафик
| Параметр | Что это | Кому критично |
|---|---|---|
| Bandwidth (полоса) | сколько бит/с проходит | загрузкам, видео |
| Delay (задержка) | время доставки end-to-end | голос, игры (норма для VoIP ≤150 мс) |
| Jitter (вариация задержки) | «дрожание» — пакеты приходят неравномерно | голос/видео (буфер сглаживает до предела) |
| Loss (потери) | % потерянных пакетов | всем; для VoIP >1% уже слышно |
2. Три модели QoS
- Best-effort — никакого QoS, «как получится». По умолчанию весь интернет так и работает.
- IntServ (Integrated Services) — резервирование ресурсов под каждый поток через RSVP. Точно, но не масштабируется (нужно состояние на каждый поток) — почти мёртв.
- DiffServ (Differentiated Services) ⭐ — трафик делится на классы, каждый помечается, и роутеры применяют политику к классу, не к потоку. Масштабируется, поэтому победил.
Дальше всё — про DiffServ: это де-факто стандарт.
3. Где живёт маркировка: CoS и DSCP
Чтобы применять политику к классу, пакет надо пометить. Метки есть на двух уровнях:
- CoS (L2) — 3 бита в теге 802.1Q (помнишь VLAN-тег из модуля 3?). Значения 0–7. Живёт только внутри L2-сегмента — на маршрутизаторе тег снимается, CoS теряется.
- DSCP (L3) — 6 бит в поле ToS/DS заголовка IP. Живёт end-to-end, пока кто-нибудь не перепишет. Это главный инструмент.
Стандартные классы (PHB — Per-Hop Behavior)
Чтобы все вендоры понимали метки одинаково, RFC задают стандартные значения DSCP:
| Класс | DSCP | Для чего |
|---|---|---|
| EF (Expedited Forwarding) | 46 | голос (VoIP) — минимальная задержка, строгий приоритет |
| AF (Assured Forwarding) | AF11–AF43 | видео, важные приложения; 4 класса × 3 уровня drop |
| CS (Class Selector) | CS0–CS7 | совместимость со старым IP Precedence; CS6/CS7 — сетевое управление |
| Default (BE) | 0 | best-effort — весь обычный трафик |
4. Классификация и trust boundary
Классификация — определить, к какому классу относится пакет. Способы: по входному интерфейсу, по ACL (адреса/порты), по уже стоящей метке DSCP/CoS, по протоколу (NBAR на Cisco — распознавание приложений).
Trust boundary — граница доверия меткам. Принцип: метить трафик как можно ближе к источнику, но не доверять меткам, которые поставил сам пользователь. Иначе любой ПК выставит себе EF и «обгонит» голос. Обычно доверяют IP-телефонам (через CDP/LLDP) и серверам, а пользовательский трафик ре-маркируют на access-порту.
5. Policing против shaping
Два способа ограничить скорость класса — и их постоянно путают:
Policing — «выбросить лишнее»
- Превышение лимита → пакет дропается (или ре-маркируется)
- Не вносит задержку, не буферизует
- Можно применять на вход и на выход
- Резкий, рваный трафик (особенно бьёт TCP)
- Потери → ретрансмиты
Shaping — «придержать в очереди»
- Превышение → пакет буферизуется и выпускается ровно
- Гладкий трафик, дружелюбен к TCP
- Идеален к скорости провайдера/контракту
- Вносит задержку (буфер)
- Только на выход; нужен буфер (память)
6. Очереди: кого пропускать вперёд
Когда на выходной интерфейс приходит больше, чем он может отправить, пакеты ждут в очередях. Дисциплина очереди решает, в каком порядке их выпускать:
| Механизм | Идея |
|---|---|
| FIFO | одна очередь, «кто первый пришёл». Никакого QoS. |
| WFQ | автоматически делит полосу «по-честному» между потоками |
| CBWFQ | классам выделяется гарантированная доля полосы (bandwidth) |
| LLQ ⭐ | CBWFQ + строгая приоритетная очередь для голоса (EF) — её обслуживают первой, всегда |
LLQ (Low Latency Queueing) — стандарт для голоса: EF-трафик идёт в priority-очередь и обслуживается раньше всех (минимальная задержка), но с ограничением (policer), чтобы голос не «съел» весь канал и не заморил остальных. Это лучшее из двух миров: приоритет + защита от голодания.
7. Управление перегрузкой: tail drop, RED/WRED, CoDel
Что делать, когда очередь переполнилась? Самое наивное — tail drop: новые пакеты просто отбрасываются. Проблема — TCP global synchronization: множество TCP-сессий одновременно теряют пакеты, разом сбрасывают скорость, потом разом разгоняются — канал «пилит» то пусто, то перегруз.
- RED / WRED (Random Early Detection) — начинает случайно подроняв пакеты заранее, до переполнения. Это «намекает» части TCP-сессий притормозить вразнобой — синхронизации нет. WRED учитывает DSCP (низкоприоритетные дропает раньше).
- CoDel / FQ-CoDel — современный ответ на bufferbloat (раздутые буферы дают огромную задержку). Управляет не длиной очереди, а временем пребывания пакета в ней. Стандарт в Linux сегодня.
- ECN — вместо дропа пометить пакет «впереди затор», и отправитель сам снизит темп. Без потерь.
fq_codel — дефолт во многих дистрибутивах. Понимание «большой буфер ≠ хорошо, он добавляет задержку» —
зрелый сетевой взгляд, который ценят и в DevOps.
8. Как это конфигурится: MQC (Cisco)
Cisco собирает QoS из трёх кирпичей — Modular QoS CLI:
- class-map — «что является этим классом» (классификация).
- policy-map — «что делать с классом» (маркировать, дать полосу, приоритет, shape).
- service-policy — «применить политику к интерфейсу».
А теперь — главная диагностическая команда QoS и чтение её вывода построчно:
Читается сверху вниз: у каждого класса — счётчик пакетов, выделенная полоса и дропы. Дропы в class-default при перегрузке — штатная работа QoS (жертвуем неважным). Дропы в классе VOICE — сигнал: либо голосового трафика стало больше лимита priority (кто-то маркирует себе EF — ищи нарушителя trust boundary), либо лимит выбран мал.
9. Плейбук: «голос заикается» — закрываем заявку #54230
show policy-map interface на WAN-выходе обеих сторон. Пусто —
вот и причина: голос стоит в общей FIFO-очереди за бэкапами. Решение — иерархия LLQ из
раздела 8 (в заявке #54230 было именно это).ip.dsfield.dscp == 46)
на входе и на выходе пути — метка сохранилась? Потерялась — ищи хоп с ре-маркировкой
(незатрастованный порт, чужой оператор без соглашения о DSCP).10. Мини-лаба: услышь QoS-проблему на своём канале
ping 8.8.8.8 -t и параллельно — speedtest или большую
загрузку. Смотри, как пинг растёт с 10–20 мс до сотен: пакеты пинга стоят в очереди за загрузкой.
Ровно это происходит с голосом филиала «Юг» в часы пик.ip.dsfield.dscp != 0) — многие VoIP-приложения маркируют голос в EF/AF41.tc qdisc show dev eth0 — какая дисциплина очереди стоит?
Во многих дистрибутивах увидишь fq_codel — тот самый анти-bufferbloat из раздела 7,
уже работающий на твоей машине.11. Словарик урока
| Термин | По-английски | Смысл в одну строку |
|---|---|---|
| QoS | quality of service | механизмы распределения дефицита полосы: кому приоритет при перегрузке |
| Джиттер | jitter | дрожание задержки от пакета к пакету — главный враг голоса после потерь |
| DiffServ / DSCP | differentiated services | победившая модель: 6-битная метка класса в IP-заголовке, политика per-hop |
| CoS | class of service, 802.1p | 3 бита приоритета в VLAN-теге; живёт только внутри L2-сегмента |
| PHB / EF / AF / CS | per-hop behavior | стандартные классы: EF(46)=голос, AFxy=гарантии с уровнями дропа, CS=совместимость |
| Trust boundary | — | граница, с которой меткам доверяют; метки пользователей переписываются на краю |
| Полисинг / шейпинг | policing / shaping | выбросить лишнее сразу / придержать в буфере и выпустить ровно |
| LLQ | low latency queueing | строгая приоритетная очередь для голоса + лимит, поверх CBWFQ |
| Tail drop | — | наивный сброс с хвоста полной очереди; вызывает синхронизацию TCP |
| WRED | weighted random early detection | ранний случайный дроп с учётом DSCP — очередь не доходит до края |
| Bufferbloat | — | раздутые буферы: потерь нет, зато задержка огромная; лечится CoDel |
| ECN | explicit congestion notification | пометить «впереди затор» вместо дропа — отправитель сам сбросит темп |
| MQC | modular QoS CLI | конструктор Cisco: class-map (что) → policy-map (что делать) → service-policy (где) |
12. Задачи: распредели дефицит
Задача 1. Директор: «купим канал 100 Мбит вместо 20 — и голос починится?» Твой ответ инженера (2 предложения).
Возможно, на время — пока трафик данных не вырастет и снова не заполнит канал (а он заполнит: бэкапы и обновления съедают любую полосу). Голосу нужен не запас мегабит, а приоритет в очереди (LLQ) — тогда он неуязвим для любых пиков данных; расширение канала — отдельное решение для скорости файлов.
Задача 2. В show policy-map interface дропы растут ТОЛЬКО в class-default. Пользователи жалуются на медленные загрузки в пик. Это авария QoS?
Нет, это QoS работает как задуман: при перегрузке жертвуют best-effort, защищая голос и критичные классы. Медленные загрузки в пик при полном канале — вопрос расширения полосы или переноса тяжёлых задач на ночь, а не поломка.
Задача 3. Голос маркируется EF на телефонах, LLQ настроен, а звонки всё равно плохие. Захват на WAN-выходе показывает у голосовых пакетов DSCP 0. Что случилось?
По пути метку переписали в ноль — чаще всего незатрастованный access-порт (свитч ре-маркирует всё пользовательское) или промежуточное устройство без trust. Голос едет как best-effort и стоит в общей очереди. Найди хоп, где DSCP теряется (захват до/после), и настрой trust для телефонов (LLDP/CDP) или ре-маркировку по ACL.
Задача 4. Сотрудник поставил в настройках своего ПК маркировку EF для торрентов. Trust boundary нет. Что произойдёт и как защититься?
Его торренты попадут в приоритетную очередь голоса, съедят лимит LLQ — и настоящие звонки начнут дропаться (растущие drops в классе VOICE). Защита: trust boundary на access-портах — меткам ПК не верить, переписывать в 0; доверять только телефонам (по LLDP) и согласованным серверам.
Задача 5. Провайдер даёт 50 Мбит/с, твой роутер отправляет в порт 1 Гбит/с. Полисер провайдера режет превышение, TCP «пилит». Что настроить у себя и почему это лучше?
Shaping на своём WAN-выходе на 50 Мбит/с (чуть ниже — например, 48): роутер сам придержит всплески в буфере и отдаст ровный поток, до полисера провайдера превышение не доедет. Плавно для TCP, без потерь. Правило: к чужому лимиту — шейпь себя сам.
Задача 6. После включения shaping жалоба: «пинг вырос с 20 до 180 мс под нагрузкой». Потерь нет. Что происходит и чем лечить?
Классический bufferbloat: шейпер копит большую очередь — пакеты не гибнут,
но ждут. Лечение: ограничить буфер/задержку очереди, применить AQM — fq_codel/CoDel в связке
с шейпером (в Linux: tc qdisc … cake/fq_codel), голос — в priority мимо
общей очереди.
13. Мост в DevOps
- DSCP в облаке: AWS/GCP в основном не гарантируют QoS внутри, но DSCP-маркировка сохраняется и важна на гибридных линках (Direct Connect, VPN к корпоративной сети с голосом/видео).
- Linux tc/qdisc: ровно те же идеи — classful qdisc (HTB ≈ CBWFQ),
fq_codelпротив bufferbloat, policing/shaping. Это и есть «QoS на сервере». - Kubernetes QoS classes (Guaranteed/Burstable/BestEffort) — это про CPU/память, другой QoS, но философия та же: при дефиците решаем, кого ужать первым. Не путай с сетевым DSCP.
- Service mesh / Envoy — rate limiting и приоритеты на L7 — современный наследник идей policing/shaping.
14. Вопросы с собеседования
15. Частые ошибки джунов
- QoS не создаёт полосу — распределяет дефицит при перегрузке. Враги: bandwidth, delay, jitter, loss.
- Победившая модель — DiffServ: классы + маркировка + политика к классу.
- CoS (3 бита, L2, локально) vs DSCP (6 бит, L3, end-to-end). EF=46 — голос, Default=0 — всё прочее.
- Классификация по ACL/интерфейсу/метке; trust boundary — где начинаем доверять меткам.
- Policing = выбросить лишнее (без задержки, рвано); shaping = придержать в буфере (гладко, с задержкой).
- Очереди: FIFO → WFQ → CBWFQ (доли) → LLQ (строгий приоритет голосу + лимит).
- Против перегрузки: WRED (ранний случайный дроп вместо tail drop), CoDel/FQ-CoDel против bufferbloat, ECN без потерь.
- Cisco MQC: class-map → policy-map → service-policy.
- В Linux/облаке те же идеи: tc/qdisc, HTB, fq_codel; не путать с QoS-классами Kubernetes (это про CPU/RAM).
QoS решает, чей пакет важнее внутри одного канала. А следующий модуль — про то, как firewall и NAT решают, пройдёт ли пакет вообще: трансляция адресов, ACL с их неявным deny и stateful-логика. Кстати, policing тарифов, который ты здесь освоил, встретится там с обратной стороны — как «полка», в которую упирается клиент.