Juniper Class of Service

Спустя значительную паузу после крайней публикации вновь объявилось желание и время немного поделиться знаниями – чем и воспользуемся.

Тема сегодняшнего урока – Juniper Class of Service.
Там где Cisco говорит QoS, Juniper говорит CoS – это вовсе не отсылка к 802.1p, просто им так удобнее, надеюсь. Далее в тексте, QoS и CoS будут использоваться в случайном порядке, просто как ссылка на набор технологий обеспечения качества обслуживания.

0. Введение
Традиционно, принимая во внимание, что cisco-адептов гораздо больше чем juniper-кунов, будут наблюдаться регулярные отсылки на названия и конкретные реализации той или иной технологии на Cisco IOS. Местами может даже показаться, что целью статьи является унижение Juniper, представляя 30-строчные примеры реализации в сравнение с 5-строчниками Cisco – это жжение будет ошибочным.
Вы можете ужаснуться от того как сложно это реализуется на Juniper, но, во-первых эта многословность дарит возможность ооочень гибкой и тонкой настройки, которая Cisco и не снилась. А во-вторых, монструозность CLI это лишь дело привычки и спустя недели лаб иерархичность Junos становится родной и понятной.

1. Теория
Многие выполняют по десятку подходов к осмыслению QoS и раз за разом сдаются – всему виной ворох технологий QoS, которые не понятно как работают и где их следует применять.
Целью данной статьи не является достаточное углубление в теорию качества обслуживания и для этих целей могу порекомендовать следующие статьи:

2. Легенда
Для обеспечения читателю возможности упорядоченного следования нам необходимо определиться с задачей, которую будет решать наша конфигурация.
Будет использоваться следующая схема, на базе реального оборудования:

juniper-cos_scheme_00

  • S3 – Juniper EX4200 – источник немаркированного трафика
  • R1 – Juniper MX5 – точка выполнения CoS-манипуляций
  • R3 – Cisco 3845 – получатель трафика

Как видите, для некоторого упрощения процесса, один из узлов на базе Cisco IOS – к этому узлу трафик будет направляться и там будет выполнятся классификация трафика, с целью определения корректности выполнения маркировки на R1.
Далее будут вносится разъяснения в задачу, но поэтапно, чтобы не вызвать чувства запутанности.
Весь трафик будет направляться к трём loopback-интерфейсам на R3, со следующими IP-адресами:

  • lo0 – 3.3.3.3
  • lo1 – 123.0.0.1
  • lo2 – 123.0.0.2

Эти адреса нужны чтобы можно было разделить трафик на три группы:

  • трафик с адресом назначения 123.0.0.1 – считается высокоприоритетным трафиком телефонии (будем называть его телефонным);
  • трафик с адресом назначения 123.0.0.2 – считается приоритетным трафиком важных корпоративных приложений (будем называть его серверным);
  • трафик с адресом назначения 3.3.3.3 – считается обычным трафиком

(легко запомнить, если смотреть на последний октет как на степень важности – 1=первая, максимальная важность).

Итак, мы имеет условный трафик, направляемый посредством утилиты ping, с S3 в сторону R3, через транзитный R1, который выполняет следующие манипуляции на интерфейсе ge-1/1/0:

  • телефонный трафик маркируется DSCP EF, помещается в очередь VOICE и считается (кол-во байт и пакетов, для диагностики);
  • серверный трафик маркируется DSCP AF31, помещается в очередь DATA и считается;
  • обычный трафик маркируется DSCP BE, помещается в очередь OTHER и считается.

Очень важно поместить трафик в нужные и разные очереди, так как основные манипуляции выполняются именно с очередями – некими трубами, где трафик скапливается в ожидании своей участи.

Далее, как бы внутри устройства выполняются следующие манипуляции:

  • очередь VOICE наделяется высшим приоритетом на передачу (LLQ), получает гарантированную полосу в 10% от общей полосы, без права выхода за рамки и 5% от общего объёма буферов без права выхода за рамки. Традиционно считается, что нет смысла давать много буферного пространства под трафик реального времени (голос, видео), ведь в случае перегрузки линии долгое время нахождения этого трафика в буфере будет бесполезной тратой ресурсов – к конечному узлу задержанный трафик придёт с большим опозданием, вероятно будучи уже не нужным, а значит его проще отбросить гораздо раньше;
  • очередь DATA наделяется средним приоритетом, получает гарантированную полосу в минимум 40% от общей полосы, т.е. с правом выхода за рамки и гарантированные 50% от общего объёма буферов с правом выхода за рамки;
  • очередь OTHER наделяется наименьшим приоритетом, получает всю незанятую кем-либо полосу и все незанятые кем-либо объёмы буферов от общего объёма буферов (доедает крошки со стола). При этом, за счёт именно этой очереди выполняется попытка избежания перегрузки (congestion avoidance – CA), с помощью WRED (weighted random early detection) – при достижении 70% занятости полосы отбрасываются 25% случайного трафика, при достижении 90% отбрасывается 50%. Это гораздо эффективнее чем базовый CA средствами Taildrop, благодаря которому при 100% перегрузке линии отбрасывается 100% трафика и рождается TCP global synchronization – график трафика будет выглядеть как зубчики пилы, ибо все TCP-сессии не получив ACK снижают свой MSS в 2 раза, показывая провал в графике и начинают передавать вновь, до повторения зубчика.

3. Настройка
3.1. Получатель

Давайте для начала выполнил быструю настройку R3 – обеспечим классификацию трафика и убедимся, что весь трафик приходит немарированный:

Мы выполняем простую Behavior aggregate (BA) классификацию пакетов, на основании DSCP, не применяя никаких действий к этому трафику. В итоге мы можем смотреть сколько пакетов одного из трёх классов с помощью одной простой командой:

(для обычного трафика не создаём отдельный класс, а используем встроенный class-default)

3.2. Отправитель
Отправим несколько пакетов с S3 и убедимся, что весь данный трафик попадает в class-default, т.е., как минимум, ни метки EF, ни AF31 там нет (вывод сокращён, для улучшения читабельности):

Проверим на R3:

Как видите все 6 пришедших пакета успешно дошли до Получателя и попали в класс для немаркированного трафика.

3.3. Транзит
Это важно. Всю настройку мы разобьём на следующие этапы:

  1. Создание очередей
  2. Классификация, маркировка, помещение в очередь
  3. Создание планировщиков
  4. Привязывание очередей к планировщикам
  5. Закрепление на интерфейсе
  6. Policer

3.3.1 Создание очередей
Как уже говорилось ранее, очереди это те самые трубы в которые попадает трафик и в котором он ожидает своей участи. С точки зрения конфигурации нам это удобно для логического разделения трафика на блоки с которыми и творится вся магия. Т.е. раз у нас три типа трафика, то мы сделаем под них три разных очереди.
Отступление 1: конфигурацию Juniper можно приводить в нескольких вариантах – в длинном выводе формата конфигурационного файла, с кучей скобочек {{{{ }}}} а ля perl, либо в формате set, то как выполняется сама настройка. Мы будем использовать второй вариант с переходом по иерархическим уровням.
Отступление 2: все параметры указываемые исключительно буквами верхнего регистра являются именуемыми параметрами, имя для который выбирается администратором и задаётся вручную. В некоторых случая добавлено обозначение места куда применяется имя, чтобы не путаться, например RULE-VOICE, COUNTER-VOICE, SCHEDULER-VOICE.
Всё это используется для улучшения читабельности конфигурации.

Надеюсь, такие конфигурации вас не пугают – перешли на уровень, сделали класс привязали его к какому захотели номеру очереди.
Проверим, что всё правильно создалось (несмотря на то, что безошибочный commit гарантирует это):

Видим все наши очереди и в столбце Queue видим номера.

3.3.2 Классификация, маркировка, помещение в очередь
Мы заведомо знаем, что трафик с S3 отправляется немаркированным, значит для того чтобы его классифицировать нам необходимо воспользоваться классификацией на основе Multi-field (MF) [т.е. отлов по любым значениям кроме самих меток CoS – по IP-адресам, портам, etc] – с самого начала мы определились, что специально для этого у нас есть три адреса назначения.
Процедура классификации, маркировки, подсчёта пакетов выполняется через обычный firewall-фильтр, который вещается на нужный интерфейс. В нашем случае это интерфейс ge-1/1/0 на R1 смотрящий в сторону S3.

Как видите конфигурация легко читается. Специально используется возможность Junos CLI, указания нескольких настроек сразу в одной строке. В конфигурации это выглядит иерархически и отдельно:

(представлен не полный вывод вышесозданного правила, а только ознакомительный блок TERM-VOICE).

Итак, мы сделали очереди, запихали туда трафик на основании известных о нём данных – самое время прикрепить фильтр на ближайших к S3 интерфейс – ge-1/1/0.

 

Прекрасно, проверяем – ещё раз отправляем пакеты до R3 и смотрим всё ли маркируется как было приказано.
Проверим для VOICE (помните, что это трафик до 123.0.0.1 ?):

 

 

Вуаля – пакеты вот прям реально маркируются на R1 и приходят таковыми до R3, где он может их классифицировать на основании BA – простого DSCP кода.

Мы так же можем зафиксировать корректную классификацию трафика на R1, просмотрев заблаговременно прикрученные счётчики:

3.3.3 Создание планировщиков
Планировщики это те ребята которые будут управлять очередями на основании заданных нами правил. Именно здесь на очередях применяются все технологии QoS, от избежания перегрузок до управления доступным буферным пространством.
Раз у нас три типа трафика, три DSCP кода, три счётчика, три очереди, то и планировщиков (schedulers) будет три, со следующими именами:

  • планировщик SCHED-VOICE для очереди VOICE;
  • планировщик SCHED-DATA для очереди DATA;
  • планировщик SCHED-OTHER для очереди OTHER.

Настоятельно рекомендую подняться в раздел “Легенда” и перечитать как именно планируется управлять очередями.

Итак:

Переходим на уровень настройки планировщиков

Планировщик SCHED-VOICE в будущем будет ассоциирован с очередью VOICE и выполняет следующие инструкции: выставляет наивысший приоритет трафику данной очереди (LLQ), обеспечивая максимально быструю отправку пакетов данной очереди, для обеспечения минимальной задержки и джиттера.

Так как лучше отбросить трафик реального времени, вместо долгосрочной  задержки в буферах, мы выдаём данной очереди только 5% объёма буферов, без права эти пределы превысить, таким образом, когда буфер заполнен, мы не может поместить в него новые пакеты и отбрасываем их,  надеясь, что перегрузка вот-вот прекратится.

Далее нам нужно ограничить максимально утилизируемую голосовым трафиком полосу пропускания, так как если этого не сделать, то наделяя его наивысшим приоритетом, мы рискуем, что при правильных объёмах голоса никакой другой трафик не пролезет вовсе. Сделать это можно несколькими путями:

  • shaping-rate – суть метода заключается в буферизации трафика перед отправкой, что для голоса не годится;
  • transmit-rate – гарантирует часть полосы, при этом, если трафика больше, то совершаются попытки использовать никем не занятую пропускную способность, что для нашего случая не походит, так как нам необходимо жёстко лимитировать полосу под голос, ибо приоритет опасен;
  • transmit-rate exact – гарантируется часть полосы и всё что выходит за рамки попросту отбрасывается. К сожалению, наивысший приоритет и transmit-rate exact не могут использоваться одновременно и при попытке сделать это Junos ругнётся следующим образом: “cos_config_scheduler_attributes: cannot configure transmit rate exact and priority strict-high at the same time.”
  • policer – последний и идеальный вариант для ограничения полосы под голос, так как во-первых policing, в отличие от shaping, не использует буферы, а во-вторых имеется особая возможность – вместо отбрасывания голосового трафика при превышении лимита, можно например перемаркировывать его (допустим в DSCP BE) и дальше уже пусть добирается как повезёт. Таким образом, мы обходим проблему буферов, отброса важного трафика и опасности переполнения линии высокоприоритетным трафиком.

Делается это не в планировщиках и мы вернёмся к этому чуть позже.
Конец планировщика SCHED-VOICE

Для очереди которая будет привязана к планировщику SCHED-DATA (у нас это будет DATA), выполняются следующие условия: средний приоритет, позволяющий обеспечить отправку пакетов из очереди данного планировщика, раньше чем ожидающие пакеты из очередей с меньшим приоритетом.  

Такого трафика ожидается много, но мы гарантируем ему только 40% буферного пространства

, а так же гарантируем 50% пропускной способности, при этом не жёстко ограничиваем его в этих рамках, т.е. если часть линии свободна, он может её занять

Для обычного трафика, как и договорились, остаются все объедки не съеденные явным # образом кем-то более привилегированным

Без комментариев список команд конфигурации выглядит так:

Согласитесь – ничего пугающего.

3.3.4. Привязывание очередей к планировщикам
Согласно уговору привязываем планировщики к одноимённым классам (воису воисово, дате датово, кесарю кесарево). Нашу карту планировщиков назовёт SCHEDMAP1:

3.3.5. Закрепление на интерфейсе
Вспомним схему:

juniper-cos_scheme_00Всё основное мы сделали, осталось зацепить это на тот интерфейс смотрящий в сторону R3ge/1/1/1 и после этого там же обеспечить там policing.

Привязка к интерфейсу:

3.3.6. Policer
Уже сейчас всё нами настроеное находится в эксплуатации и нарезается раздаётся согласно тем условиями которые мы указали.
Осталось “зарезать” голосовой трафик, чтобы защитить себя от обработки только высокоприоритетных пакетов. Есть два уточнения благодаря которым мы поймём как и где это делать:

  • policing можно использовать как для входящего трафика, так и для исходящего, в отличие от shaping, который не особо разумен для входящего трафика, так как буферы уже были использованы для трафика который отбросится;
  • как и многие другие вещи, policing выполняется посредством firewall filter, который назначается на некоторый интерфейс;

Собственно из этого можно сделать вывод, что ничего не мешает и даже следует использовать policing уже в составе имеющегося фильтра на порту ge-1/1/0, смотрящего в сторону S3!

Для начала создадим сам policer, чтобы можно было его поместить как условие в наш фильтр.

Вы наверняка заметили, что правила фаервольных полисеров и фильтров очень удобно читать – если так, то делать вот это.
В нашем случае мы говорим, что если нечто, к чему будет применён данный полисер пытается занять больше положенных 10% от пропусной способности линии (10Мб/с для 100Мбит/с), то трафик сверх этого лимита стоит переместить в класс OTHER, для которого как вы помните имеется большой выбор крошек. Мы не станем перемаркировывать трафик, а просто поместим в очередь для обычного трафика, где он, если выживет, то может на следующей узле всё будет хорошо, и на основании его сохранившего DSCP EF, его обслужат его как подабает таким особам.

Далее, мы имеем следующий фильтр, на интерфейсе, смотрящем в сторону S3:

Значит нам необходимо прицепить только что созданный policer POLICER1 к правилу TERM-VOICE:

В итоге правило TERM-VOICE обретёт следующий вид:

Только-только трафик будет классифицирован, маркирован и помещён в очередь, как тут же будет проверен и на соответствие правилу допустимой ему полосы пропускания.

Рассморение калькуляции значения burst-size преднамеренно не упоминается в рамках статьи, для обеспечения небольшого уровня сложности текста.

4. Проверка
Не сказать, что Junos достоин похвалы за удобство проверки корректности работы (по сравнению с IOS), но инструменты имеются.

show class-of-service
show class-of-service scheduler-map
show class-of-service scheduler-map SCHEDMAP1
show class-of-service drop-profile
show class-of-service drop-profile DROPMAP1
show class-of-service interface ge-1/1/1 comprehensive | find “Scheduler map”
show class-of-service interface
show class-of-service interface ge-1/1/1
show class-of-service interface ge-1/1/1 comprehensive | find “CoS info”
show interfaces ge-1/1/0 extensive detail | find “CoS info”
show interfaces queue ge-1/1/1

5. Источники

JUNOS CoS Components

Configuring Large Delay Buffers in CoS

Schedulers Overview

Configuring CoS Hierarchical Schedulers

Day One: Deploying Basic QoS [pdf]

Enabling Class of Service on EX Series Switches in a Campus LAN [pdf]

Example: Configuring CoS on EX Series Switches

 

6. Обновления

UPDATE1 [300913] Микросекунды
Для голосового трафика может быть полезным указать размер буфера не в процентах, а явным образом, в микросекундах, ограничив тем самым время жизни трафика который уставает задержаваясь в буферах. Известно, что delay голосового трафика, при котором наблюдается явная деградация звука имеется уже на 150мс. Так как данный параметр выставляется в микросекундах, что на три порядка меньше миллисекунды, 150мс будут выглядеть как 150000, но мы поставишь чуть меньше:

UPDATE1 [290913] RED
Совсем забыли про необходимость пытаться избегать перегрузки на линии, за счёт предварительного отбрасывания части пакетов полуслучайным образом – random early detection (RED).
Разумеется, это будет делаться за счёт трафика в очереди класса OTHER, который у нас best-effort.
Согласно легенде будет выполняться следующее: “при достижении 70% занятости полосы отбрасываются 25% случайного трафика, при достижении 90% отбрасывается 50%”.
Настраивается всё в отдельной ветке иерархии и после цепляется к нужному планировщику:

Как видите и здесь блок конфигурации отлично читается.
Обновим на ходу планировщик SCHED_OTHER:

Проверка:

The End

SHARE: Tweet about this on TwitterShare on FacebookShare on VKShare on LinkedInShare on Google+Email this to someone
  • Артем Лисенков

    Большое спасибо за статью!

  • Ildar Gafiatullin

    к видеотрафику iptv какие критерии для шедулера?

    • Sk1f3r

      Спасибо за вопрос.
      Надеюсь достаточно подробно ответил в Skype.

  • Ars Nomadov

    S1 узла нету же на схеме,я так понял это S3?

    • Sk1f3r

      Здравствуйте.
      Всё верно, речь про S3 – исправлено.
      Спасибо.

  • Ars Nomadov

    Нужна помощь в настройке CoS для SIP между juniper (1-srx240. 2-srx100), которые работают по IPSEC VPN между собой. Вычитал что на SRX-ах нельзя повесить Cos на vpn интерфейс st.0. Наверно есть другие способы. Автор очень надеюсь на вас,может есть статья по этому поводу, типа этой.

    • Sk1f3r

      Здравствуйте.
      Насколько я знаю на интерфейсах st устройств Juniper SRX до сих пор нельзя применять CoS.
      Решения два: либо использовать GRE (на них можно применять политики CoS), либо решать ваши задачи по обеспечению качества обслуживания _до_ интерфейса st, например на входе на устройство со стороны ЛВС.