#server-performance

Управление трафиком в Linux (tc): практическое руководство

12 мин чтения - 5 июня 2026 г.

hero section cover

Управление пропускной способностью, приоритизация трафика и регулирование входящего и исходящего трафика в Linux с помощью tc. Рабочие настройки HTB, IFB, DSCP и fq_codel для реальных серверов.

Управление трафиком в Linux (tc): практическое руководство

Команда tc позволяет напрямую контролировать, как ваш сервер обрабатывает сетевой трафик. Вы можете ограничить пропускную способность для каждого сервиса, обеспечить отзывчивость интерактивных сеансов (например, SSH) при всплесках массовой передачи данных, а также регулировать как исходящие, так и входящие потоки с помощью одного инструмента. В этом руководстве рассматриваются основные концепции, рабочая настройка HTB, регулирование входящего трафика с помощью IFB, приоритезация на основе DSCP, а также способы устранения неполадок в случае сбоев.


 

Как работает tc

Каждая tc конфигурация состоит из четырёх компонентов:

  • qdisc (дисциплина очереди). Планировщик, привязанный к сетевому интерфейсу. Он определяет, как пакеты помещаются в очередь и извлекаются из неё.
  • Класс. Подразделение внутри qdisc с поддержкой классов. Представьте себе это как полосу движения со своим собственным ограничением скорости.
  • Фильтр. Проверяет заголовки пакетов (IP-адреса, порты, метки) и относит каждый пакет к определенному классу.
  • Действие. То, что происходит с пакетом после сопоставления: пересылка, отбрасывание, перенаправление.

Все это образует дерево. Пакеты поступают в корневой qdisc, проходят через фильтры, сортируются по классам с помощью major:minor идентификатора и в конечном итоге попадают в очередь на листье qdisc для передачи.

Для любых операций, более сложных, чем сопоставление по порту, помечайте пакеты с помощью iptables или nftables в таблице mangle, а затем используйте fw фильтр в tc для классификации по метке. Это гораздо лучше масштабируется, чем цепочка необработанных u32 правил для каждого типа трафика.

Исходящий трафик против входящего

Направление имеет значение. Ядро может буферизовать и задерживать исходящие пакеты, что и обеспечивает реальное формирование трафика. Входящие пакеты уже прошли по каналу к моменту, когда вы их видите, поэтому вы можете только контролировать их (отбрасывать при превышении порогового значения), если только вы сначала не перенаправите их на устройство IFB.

ОсобенностьИсходящий трафикВходящий трафик
НаправлениеИсходящийВходящий
ФормированиеВстроенныйТребуется IFB
КонтрольПоддерживаетсяПоддерживается
Типичное использованиеQoS, распределение пропускной способности, регулирование скоростиОграничение скорости, базовые меры по защите от DDoS-атак

Qdisc, которые вы будете использовать на практике

  • HTB (Hierarchical Token Bucket). С классами. Используйте его, если вам нужна гарантированная минимальная пропускная способность для каждого сервиса с возможностью заимствования неиспользуемой пропускной способности у других классов.
  • TBF (Token Bucket Filter). Без классов. Используйте его, когда вам просто нужно ограничить скорость всего интерфейса одним значением.
  • fq_codel (Fair Queuing Controlled Delay). Сочетает справедливость на уровне потоков с активным управлением очередями для устранения «буферного раздувания». Является qdisc по умолчанию в большинстве дистрибутивов Linux начиная с systemd 217 и поставляется по умолчанию в RHEL 9. Всегда подключайте его в качестве листьевого qdisc под классами HTB, иначе один «жадный» поток может захватить весь класс.

Настройка tc на сервере Linux

tc поставляется в составе пакета iproute2. В Debian и Ubuntu его можно установить с помощью apt-get install iproute2. В RHEL и производных дистрибутивах yum install iproute. Вам потребуются права root или sudo.

Сначала определите правильное имя интерфейса. Неправильное указание имени интерфейса — самая распространённая причина, по которой конфигурация без каких-либо сообщений не даёт результата:

ip link show

Проверьте, что уже происходит на интерфейсе, включая текущие счетчики:

tc -s qdisc show dev eth0

Перед применением новой конфигурации удалите все существующие корневые qdisc, чтобы избежать RTNETLINK answers: File exists ошибок:

tc qdisc del dev eth0 root 2>/dev/null || true

Если вы обновляете существующее правило, а не создаете его с нуля, используйте replace вместо add для атомарной замены.

Аппаратное разгрузочное оборудование, такое как TSO и GSO, группирует пакеты таким образом, что это мешает формированию трафика. Отключите их на интерфейсе, на котором осуществляется формирование трафика:

sudo ethtool -K eth0 tso off gso off

Установите fq_codel в качестве общесистемного qdisc по умолчанию для новых интерфейсов:

sysctl -w net.core.default_qdisc=fq_codel

Для загруженных серверов сочетайте его с алгоритмом управления перегрузкой BBR (ядро 4.9+). BBR поддерживает высокую пропускную способность без увеличения очередей:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Одна полезная привычка при настройке удалённого компьютера через SSH: откройте вторую сессию и держите tc qdisc del dev eth0 root готовность к вставке. Неправильное правило фильтрации может мгновенно заблокировать вам доступ.

Регулирование исходящего трафика с помощью HTB

HTB позволяет установить для каждого сервиса гарантированный минимум (rate) и максимальный объем (ceil). Неиспользованная пропускная способность распределяется между пользователями, нуждающимися в ней, в порядке приоритета. Ниже приведена рабочая трёхуровневая конфигурация для восходящего канала 1 Гбит/с.

Создайте корневой qdisc HTB. default 30 отправляет любой неклассифицированный пакет в класс 1:30 , а не пропускает его мимо ваших правил:

tc qdisc add dev eth0 root handle 1: htb default 30

Ограничьте общую пропускную способность на уровне 900 Мбит/с. Всегда формируйте трафик чуть ниже фактической пропускной способности канала, иначе очередь образуется на вышестоящем маршрутизаторе или модеме, которые вы не контролируете:

tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit

Определите уровни обслуживания. Уровни с более низкими prio значения получают неиспользуемую пропускную способность в первую очередь:

# High priority: web and API traffic
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1
 
# Medium priority: database replication
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 300mbit ceil 900mbit prio 2
 
# Low priority: bulk and backup traffic
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 100mbit ceil 900mbit prio 3

Привяжите fq_codel в качестве конечного qdisc к каждому классу, чтобы ни один поток не мог доминировать в своём уровне:

tc qdisc add dev eth0 parent 1:10 handle 10: fq_codel
tc qdisc add dev eth0 parent 1:20 handle 20: fq_codel
tc qdisc add dev eth0 parent 1:30 handle 30: fq_codel

Теперь классифицируйте трафик. Для простого сопоставления портов u32 быстрее всего:

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip dport 443 0xffff flowid 1:10

Для любых операций с учетом состояния помечайте в iptables и сопоставляйте метку с fw:

iptables -t mangle -A OUTPUT -p tcp --dport 5432 -j MARK --set-mark 2
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 2 fw flowid 1:20

Регулирование входящего трафика с помощью IFB

Оригинально регулировать входящий трафик невозможно, поскольку к моменту поступления пакета он уже использовал вашу пропускную способность. Обходной путь заключается в перенаправлении входящего трафика на виртуальный интерфейс промежуточного функционального блока (IFB), где ядро обрабатывает его как исходящий и позволяет применять qdisc с классами.

Загрузите модуль и активируйте интерфейс:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Добавьте qdisc для входящего трафика к физическому интерфейсу и перенаправьте весь трафик на ifb0:

tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all u32 \
  match u32 0 0 action mirred egress redirect dev ifb0

С этого момента ifb0 он ведёт себя как любой другой интерфейс. Примените к нему своё дерево HTB точно так же, как вы делали бы для исходящего трафика:

tc qdisc add dev ifb0 root handle 1: htb default 30
tc class add dev ifb0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1

Приоритезация трафика с помощью DSCP

DSCP (Differentiated Services Code Point) помечает пакеты 6-битным значением в байте TOS, поэтому ваши tc фильтры могут классифицировать трафик по меткам, а не по портам в наборе правил. При сопоставлении DSCP в tc, сдвиньте значение влево на 2 бита. DSCP EF (46) превращается в 0xb8. Маска 0xfc отделяет 6 битов DSCP от 2 битов ECN.

Разумное сопоставление по умолчанию для серверных рабочих нагрузок:

Тип трафикаDSCPTOS (шестнадцатеричный)Примеры
ИнтерактивныйEF0xb8SSH, DNS, VoIP
БизнесAF410x88HTTP, HTTPS, API
Массовая рассылкаCS10x20Резервное копирование, FTP, обновления пакетов
По возможностиCS00x00Все остальное

Помечайте исходящие пакеты в iptables до того, как они попадут в ваши tc фильтров:

iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46

Затем сопоставьте метку в tc и маршрутизируйте его в нужный класс HTB:

# EF (SSH, VoIP) goes to the high-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip tos 0xb8 0xfc flowid 1:10
 
# AF41 (web traffic) goes to the medium class
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
  match ip tos 0x88 0xfc flowid 1:20
 
# CS1 (bulk) goes to the low-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
  match ip tos 0x20 0xfc flowid 1:30

Мониторинг и устранение неполадок

Три команды, которые вы будете использовать постоянно:

tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0

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

watch -n 1 'tc -s class show dev eth0'

добавьте -d для внутренних параметров (target, interval, quantum) и -j для вывода в формате JSON, если вы направляете данные в стек метрик. Используйте в сочетании с ss -tin , чтобы увидеть оценки RTT и повторные передачи на уровне TCP.

Большинство сбоев можно отнести к нескольким основным типам:

СимптомВероятная причинаУстранение
RTNETLINK answers: File existsqdisc «Root» уже настроенtc qdisc del dev eth0 root первый
Правила применяются, но трафик не ограничиваетсяНеверный интерфейс или TSO/GSO по-прежнему включеныПроверьте с помощью ip link show, отключите разгрузку с помощью ethtool -K
Фильтр никогда не срабатываетНеверный синтаксис порта/IP или выравнивание маскиДобавьте контрмера и проверьте количество совпадений в tc -s filter show
Правила исчезают после перезагрузкиКонфигурация хранится только в памятиОберните в скрипт и вызывайте из systemd или диспетчера NetworkManager
Высокая задержка при трафике с приоритетомОтсутствует qdisc типа «leaf» или слишком низкий уровень пакетного режимаПривяжите fq_codel к классам leaf, повысить burst

Если вы когда-нибудь заблокируете себя из-за неправильной настройки, сброс прост:

tc qdisc del dev eth0 root

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

Блог

События этой недели

Другие статьи
Руководство по iperf3: тестирование скорости сети в Linux и Windows
#bandwidth#server-performance

Руководство по iperf3: тестирование скорости сети в Linux и Windows

Установите iperf3, запустите тесты пропускной способности и настройте буферы TCP для получения точных результатов в Linux и Windows. Охватывает тестирование UDP, двунаправленное тестирование и тестирование 10GbE+.

10 мин чтения - 7 мая 2026 г.

Другие статьи
background image

У вас есть вопросы или вам нужно индивидуальное решение?

icon

Гибкие варианты

icon

Глобальный охват

icon

Мгновенное развертывание

icon

Гибкие варианты

icon

Глобальный охват

icon

Мгновенное развертывание