QoS Качество обслуживания: классификация, маркировка, очереди

Полоса пропускания не бесконечна, а трафик неоднороден: голосовой звонок умирает от 150 мс задержки, а большой бэкап готов ждать. QoS (Quality of Service) — это набор механизмов, который решает, чей пакет важнее, когда канал перегружен. Не «ускорить всё» (это невозможно), а осознанно распределить дефицит: кому приоритет, кого притормозить, кого выбросить первым.

🟡 Калибровка: практическая база глубоко, операторская экзотика для голоса — обзорно. Тебе важно понимать четыре кита (классификация, маркировка, управление очередями, управление перегрузкой), модель DiffServ/DSCP и разницу policing vs shaping — это спрашивают и это переносится в облако/Kubernetes. Тонкую настройку LLQ под конкретные кодеки VoIP давать наизусть не будем.
Заявка из очереди

«Заявка #54230. Филиал „Юг“: в часы пик (10:00–12:00) IP-телефония заикается и рвётся, при этом файлы с сервера качаются нормально. Канал до филиала 20 Мбит/с, загрузка по графикам — до 100% в пиковые часы. Директор филиала требует „расширить канал“». Спойлер: расширение канала здесь — не первое и не единственное решение. Голос умирает не от нехватки мегабит (звонку хватает 0,1 Мбит/с!), а от того, что его пакеты стоят в общей очереди за большими файлами. Разруливание таких очередей — и есть QoS. К концу урока ты сможешь и объяснить это директору, и настроить.

Что узнаешь — после урока ты сможешь
Вспомни из прошлых модулей

Модуль 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% уже слышно
Ключевая мысль: QoS не создаёт полосу. Он перераспределяет дефицит. Если канал хронически забит на 100% — это вопрос апгрейда, а не QoS. QoS спасает в моменты всплесков и защищает чувствительный трафик от «жадного».

2. Три модели QoS

Дальше всё — про DiffServ: это де-факто стандарт.

3. Где живёт маркировка: CoS и DSCP

Чтобы применять политику к классу, пакет надо пометить. Метки есть на двух уровнях:

Поле ToS в IPv4 → переосмыслено как DSCP (6 бит) + ECN (2 бита)
DSCP — 6 бит (класс) ECN — 2 бита DSCP: 64 возможных значения класса (0–63). ECN — сигнал перегрузки без отбрасывания. Раньше эти 8 бит назывались ToS (IP Precedence 3 бита). DiffServ переопределил их в DSCP. CoS (L2) ↔ DSCP (L3) часто маппят друг в друга на границе.
DSCP едет в каждом IP-пакете и сохраняется на всём пути — если домен ему «доверяет».

Стандартные классы (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)0best-effort — весь обычный трафик
Запомни главное: EF (46) = голос, Default (0) = всё остальное. Остальное — нюансы. Имя «AFxy»: x — класс очереди (1–4), y — приоритет отбрасывания (1 лучше, 3 первым дропнут).

4. Классификация и trust boundary

Классификация — определить, к какому классу относится пакет. Способы: по входному интерфейсу, по ACL (адреса/порты), по уже стоящей метке DSCP/CoS, по протоколу (NBAR на Cisco — распознавание приложений).

Trust boundary — граница доверия меткам. Принцип: метить трафик как можно ближе к источнику, но не доверять меткам, которые поставил сам пользователь. Иначе любой ПК выставит себе EF и «обгонит» голос. Обычно доверяют IP-телефонам (через CDP/LLDP) и серверам, а пользовательский трафик ре-маркируют на access-порту.

Trust boundary: где начинаем доверять меткам
ПКне верим IP-тел.верим (LLDP) Switchaccess Core WAN trust boundary До границы метки перепроверяем/ставим сами; после — доверяем и только применяем политику.
Граница доверия — обычно access-свитч. Телефону верим, пользовательскому ПК — нет.

5. Policing против shaping

Два способа ограничить скорость класса — и их постоянно путают:

Policing — «выбросить лишнее»

  • Превышение лимита → пакет дропается (или ре-маркируется)
  • Не вносит задержку, не буферизует
  • Можно применять на вход и на выход
  • Резкий, рваный трафик (особенно бьёт TCP)
  • Потери → ретрансмиты

Shaping — «придержать в очереди»

  • Превышение → пакет буферизуется и выпускается ровно
  • Гладкий трафик, дружелюбен к TCP
  • Идеален к скорости провайдера/контракту
  • Вносит задержку (буфер)
  • Только на выход; нужен буфер (память)
Один и тот же всплеск: policing режет, shaping сглаживает
лимит Policing: всё выше лимита — обрезано (дроп) Shaping: пики растянуты во времени (буфер)
Правило: к скорости провайдера/контракту — shaping (свой край), злоупотребление лимитом — policing.

6. Очереди: кого пропускать вперёд

Когда на выходной интерфейс приходит больше, чем он может отправить, пакеты ждут в очередях. Дисциплина очереди решает, в каком порядке их выпускать:

МеханизмИдея
FIFOодна очередь, «кто первый пришёл». Никакого QoS.
WFQавтоматически делит полосу «по-честному» между потоками
CBWFQклассам выделяется гарантированная доля полосы (bandwidth)
LLQCBWFQ + строгая приоритетная очередь для голоса (EF) — её обслуживают первой, всегда

LLQ (Low Latency Queueing) — стандарт для голоса: EF-трафик идёт в priority-очередь и обслуживается раньше всех (минимальная задержка), но с ограничением (policer), чтобы голос не «съел» весь канал и не заморил остальных. Это лучшее из двух миров: приоритет + защита от голодания.

LLQ: голос — мимо очереди, остальные — по гарантированным долям
EF / голос (priority) AF / видео (35%) критичные данные (25%) best-effort (остаток) SchedulerLLQ WAN-линк Голос всегда обслуживается первым (но с лимитом). Остальные делят полосу по долям.
Это типовая «иерархия классов» enterprise: голос → видео → бизнес-данные → всё прочее.

7. Управление перегрузкой: tail drop, RED/WRED, CoDel

Что делать, когда очередь переполнилась? Самое наивное — tail drop: новые пакеты просто отбрасываются. Проблема — TCP global synchronization: множество TCP-сессий одновременно теряют пакеты, разом сбрасывают скорость, потом разом разгоняются — канал «пилит» то пусто, то перегруз.

🌉 Bufferbloat и CoDel — это уже про Linux и облако, а не про Cisco. На серверах qdisc fq_codel — дефолт во многих дистрибутивах. Понимание «большой буфер ≠ хорошо, он добавляет задержку» — зрелый сетевой взгляд, который ценят и в DevOps.

8. Как это конфигурится: MQC (Cisco)

Cisco собирает QoS из трёх кирпичей — Modular QoS CLI:

  1. class-map — «что является этим классом» (классификация).
  2. policy-map — «что делать с классом» (маркировать, дать полосу, приоритет, shape).
  3. service-policy — «применить политику к интерфейсу».
# 1) классифицируем R1(config)# class-map match-any VOICE R1(config-cmap)# match dscp ef R1(config)# class-map match-any VIDEO R1(config-cmap)# match dscp af41 # 2) политика: голос — приоритет, видео — доля R1(config)# policy-map WAN-OUT R1(config-pmap)# class VOICE R1(config-pmap-c)# priority percent 20 # LLQ: строгий приоритет + лимит R1(config-pmap)# class VIDEO R1(config-pmap-c)# bandwidth percent 35 # гарантированная доля R1(config-pmap)# class class-default R1(config-pmap-c)# fair-queue R1(config-pmap-c)# random-detect # WRED для best-effort # 3) применяем на выход WAN R1(config)# interface gi0/0 R1(config-if)# service-policy output WAN-OUT

А теперь — главная диагностическая команда QoS и чтение её вывода построчно:

R1# show policy-map interface gi0/0 Service-policy output: WAN-OUT Class-map: VOICE (match-any) 215384 packets ... Priority: 20% (4000 kbps) (total drops) 1847 ← ★ голос ДРОПАЕТСЯ — вот и «заикание» Class-map: VIDEO (match-any) 88123 packets ... bandwidth 35% — 0 drops ← видео живёт Class-map: class-default 992001 packets ... (total drops) 55102 ← best-effort жертвует первым, это норма

Читается сверху вниз: у каждого класса — счётчик пакетов, выделенная полоса и дропы. Дропы в class-default при перегрузке — штатная работа QoS (жертвуем неважным). Дропы в классе VOICE — сигнал: либо голосового трафика стало больше лимита priority (кто-то маркирует себе EF — ищи нарушителя trust boundary), либо лимит выбран мал.

9. Плейбук: «голос заикается» — закрываем заявку #54230

Подтверди симптом цифрами
Графики канала: загрузка в пике 100% — перегруз есть. MOS/жалобы совпадают по времени с пиками? Совпадают → это очередь, идём дальше. Не совпадают → ищи потери на физике (CRC) или проблему телефонии, QoS ни при чём.
Есть ли вообще QoS-политика на узком месте?
show policy-map interface на WAN-выходе обеих сторон. Пусто — вот и причина: голос стоит в общей FIFO-очереди за бэкапами. Решение — иерархия LLQ из раздела 8 (в заявке #54230 было именно это).
Политика есть — где дропы?
Смотри счётчики по классам (разбор выше). Дропы в VOICE → лимит priority мал или в EF попадает лишний трафик. Дропы только в default → голос жив; если жалобы остаются, проверь, что голос вообще попадает в свой класс (шаг 4).
Голос доезжает с правильной меткой?
Классика: телефон маркирует EF, а по пути кто-то переписал DSCP в 0 — и голос едет как best-effort. Проверка: захват (фильтр Wireshark ip.dsfield.dscp == 46) на входе и на выходе пути — метка сохранилась? Потерялась — ищи хоп с ре-маркировкой (незатрастованный порт, чужой оператор без соглашения о DSCP).
Отчитайся по-инженерному
Директору: «канал в пике полон, но голосу нужно не расширение, а приоритет — включили LLQ, голос больше не конкурирует с файлами; расширение канала отдельным вопросом, когда данные упрутся». Две проблемы, два решения — не смешивай.

10. Мини-лаба: услышь QoS-проблему на своём канале

Измерь свой bufferbloat
Открой тест Waveform Bufferbloat (ищи «waveform bufferbloat test»). Он меряет задержку без нагрузки и под полной загрузкой канала. Оценка C и ниже — твой роутер копит гигантские очереди: во время любой загрузки звонки и игры у тебя «плывут». Это раздел 7 вживую.
Тот же эффект руками
Запусти ping 8.8.8.8 -t и параллельно — speedtest или большую загрузку. Смотри, как пинг растёт с 10–20 мс до сотен: пакеты пинга стоят в очереди за загрузкой. Ровно это происходит с голосом филиала «Юг» в часы пик.
Найди DSCP в живых пакетах
Wireshark → захват → в деталях любого пакета разверни IPv4-заголовок → поле Differentiated Services. У обычного трафика DSCP 0 (CS0). Позвони через мессенджер с включённым захватом и поищи пакеты с ненулевым DSCP (фильтр ip.dsfield.dscp != 0) — многие VoIP-приложения маркируют голос в EF/AF41.
Если есть Linux/WSL — потрогай qdisc
tc qdisc show dev eth0 — какая дисциплина очереди стоит? Во многих дистрибутивах увидишь fq_codel — тот самый анти-bufferbloat из раздела 7, уже работающий на твоей машине.

11. Словарик урока

ТерминПо-английскиСмысл в одну строку
QoSquality of serviceмеханизмы распределения дефицита полосы: кому приоритет при перегрузке
Джиттерjitterдрожание задержки от пакета к пакету — главный враг голоса после потерь
DiffServ / DSCPdifferentiated servicesпобедившая модель: 6-битная метка класса в IP-заголовке, политика per-hop
CoSclass of service, 802.1p3 бита приоритета в VLAN-теге; живёт только внутри L2-сегмента
PHB / EF / AF / CSper-hop behaviorстандартные классы: EF(46)=голос, AFxy=гарантии с уровнями дропа, CS=совместимость
Trust boundaryграница, с которой меткам доверяют; метки пользователей переписываются на краю
Полисинг / шейпингpolicing / shapingвыбросить лишнее сразу / придержать в буфере и выпустить ровно
LLQlow latency queueingстрогая приоритетная очередь для голоса + лимит, поверх CBWFQ
Tail dropнаивный сброс с хвоста полной очереди; вызывает синхронизацию TCP
WREDweighted random early detectionранний случайный дроп с учётом DSCP — очередь не доходит до края
Bufferbloatраздутые буферы: потерь нет, зато задержка огромная; лечится CoDel
ECNexplicit congestion notificationпометить «впереди затор» вместо дропа — отправитель сам сбросит темп
MQCmodular 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

# Linux: shaping и борьба с bufferbloat — те же концепции $ tc qdisc add dev eth0 root fq_codel # современный AQM против задержки $ tc qdisc add dev eth0 root tbf rate 100mbit burst 32kb latency 400ms # shaping

14. Вопросы с собеседования

❓ В чём разница policing и shaping?
Policing отбрасывает (или ре-маркирует) превышение — без задержки, но рвано. Shaping буферизует и выпускает ровно — гладко, но добавляет задержку. К контракту провайдера — shaping; для жёсткого лимита — policing.
❓ Какой DSCP у голоса и почему именно строгий приоритет?
EF = DSCP 46. Голос чувствителен к задержке и jitter, поэтому его кладут в priority-очередь (LLQ), обслуживаемую первой — но с лимитом, чтобы не заморить остальной трафик.
❓ Зачем WRED, если можно просто tail drop?
Tail drop вызывает TCP global synchronization (все сессии разом тормозят и разом разгоняются). WRED роняет пакеты заранее и вразнобой, сглаживая поведение TCP и держа очередь короче.
❓ Что такое trust boundary?
Граница, с которой мы доверяем меткам QoS. Пользовательскому ПК не доверяем (ре-маркируем на access-порту), IP-телефону/серверу — доверяем. Метим как можно ближе к источнику.

15. Частые ошибки джунов

ошибка 1 «QoS добавит скорость». Нет. QoS перераспределяет дефицит. Хронически забитый канал лечится апгрейдом.
ошибка 2 Доверяют меткам пользователя. Без trust boundary любой ПК выставит себе EF и обгонит голос. Ре-маркируй на крае.
ошибка 3 Маркируют CoS и ждут, что доедет до конца. CoS живёт только в L2; через роутер теряется. Для end-to-end — DSCP.
ошибка 4 QoS только на одном устройстве. QoS работает hop-by-hop: политика и доверие к DSCP должны быть согласованы по всему пути (domain-wide), иначе на любом «нечестном» хопе всё рассыпется.
ошибка 5 Гигантские буферы «чтобы не терять». Это bufferbloat: пакеты не теряются, зато задержка взлетает — для голоса хуже потерь. Управляй временем в очереди (CoDel), а не только её длиной.
Мост к следующему модулю

QoS решает, чей пакет важнее внутри одного канала. А следующий модуль — про то, как firewall и NAT решают, пройдёт ли пакет вообще: трансляция адресов, ACL с их неявным deny и stateful-логика. Кстати, policing тарифов, который ты здесь освоил, встретится там с обратной стороны — как «полка», в которую упирается клиент.