Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Сообщество системных администраторов Litl-Admin.ru Шейпим трафик Linux при помощи tc


Ссылка на материал

Друзья, приветствую. Одной из важнейших задач системного администратора является управление и справедливое разделение полосы пропускания между всеми сотрудниками в компании, где он работает. Под справедливым я понимаю именно выделение приоритетов, а не чью-то прихоть.

Изначально, мой первый шлюз сети Интернет представлял собой машинку на FreeBSD 8.2 с пересобранным ядром под поддержку dummynet и файрволла ipfw с 128 мегабайтами оперативы на борту. Поскольку эта версия морально устарела, да и захотелось перейти на что-то более современное (как минимум по железу), решено было осваивать другой шейпер трафика, так как пайпы и очереди в FreeBSD мне дались не очень хорошо.

Решено было переходить на CentOS (который я сейчас изучаю в рамках подготовки к RHCSA) иiproute2 (а именно tc). Первое впечатление от tc – во-от такие глаза “О_О” и вопрос “как это вообще можно понять?”. А сейчас ничего, втягиваюсь потихоньку. Поэтому и хочу оформить своё понимание в виде статьи, чтобы и себе на будущее и вам всем для справки, вдруг кто не знает эти инструменты.

Итак, в своей работе я буду использовать две виртуальные машины, CentOS 6.7 на борту – прототип шлюза, и linux microcore 3.8 – как рабочая машинка для теста (это ядро весьма легковесно и не нагружает мой нубук).

Статья будет дополняться, так как у tc много интересных вещей есть (разные типа дисциплин), каждая из которых заслуживает определённой доли внимания, а обо всех сразу я рассказать не смогу. Поэтому по мере изучения я буду делать выкладки здесь.

Итак, приступим.

Создадим скриптовый файл:

# vi /etc/tc.conf

следующего содержания:

#!/bin/bash
IF=eth0
tc qdisc del dev $IF root
tc qdisc add dev $IF root handle 1:0 htb default 10
tc class add dev $IF parent 1:0 classid 1:1 htb rate 100mbit
tc class add dev $IF parent 1:1 classid 1:10 htb rate 2mbit ceil 3mbit prio 0
#9999/TCP
tc class add dev $IF parent 1:1 classid 1:20 htb rate 4mbit ceil 7mbit prio 0
#10000/TCP
tc class add dev $IF parent 1:1 classid 1:21 htb rate 10mbit ceil 12mbit prio 0
#IPTABLES RULES#
iptables -t mangle -F OUTPUT
iptables -t mangle -A OUTPUT -o $IF -p tcp -m multiport --dports 9999 -j CLASSIFY --set-class 1:20
iptables -t mangle -A OUTPUT -o $IF -p tcp -m multiport --dports 10000 -j CLASSIFY --set-class 1:21

Не забываем сделать файл исполняемым:

# chmod +x /etc/tc.conf

Выполняем его.

Внимательный читатель наверняка уже всё понял, но я лучше перескажу порционно, дабы не запутаться, ибо у меня был небольшой затык в tc (не конкретно тут, а в других дисциплинах).

IF=eth0

Мы задали наш интерфейс, обращённый в локальную сеть. Именно этот трафик мы будем резать.

tc qdisc del dev $IF root

Удалили корневую дисциплину на порту eth0.

tc qdisc add dev $IF root handle 1:0 htb default 10

Добавили корневую дисциплину на порт типа htbHierarchical TokenBucket, по этой дисциплине под каждый вид трафика выделяется собственная полоса, кроме того по умолчанию мы задали класс 10. Очень желательно задавать класс по умолчанию, (то есть такой, который не соответствует никаким другим классам), если этого не сделать – этот трафик будет считаться трафиком нулевого класса и возьмёт всю скорость интерфейса.

Здесь важно понимать иерархичность классов. Вот смотрите, в корневой дисциплине мы задали класс 1:0 – корень.

tc class add dev $IF parent 1:0 classid 1:1 htb rate 100mbit

Далее мы указали новый класс 1:1, который является вложенным в 1:0 (parent), и уже у него определили скорость 100mbit. То есть на все классы, вложенные в 1:1 будет выделяться не больше 100mbit скорость. По хорошему здесь мы должны указать потолок провайдера.

tc class add dev $IF parent 1:1 classid 1:10 htb rate 2mbit ceil 3mbit prio 0

А тут мы указали вложенный класс 1:10 (который вложен в 1:1), и для него скорость 2mbit с возможностью заимствования до 3mbit (если полоса свободна). В самом деле, заимствование может нам помочь. Если на какую-то группу пользователей выделено, к примеру, 10 мбит/с, а на каждого из них по 1 мбит/с, то, в случае, если работает только один – нет смысла ему резать до 1 мбит/с. Пусть берёт всё, что позволено его группе (10). Но как только появится второй (следующие) они будут делить эту десятку между собой, но не больше.

Кстати, класс 1:10 тут – это именно класс по умолчанию (см. несколько шагов вперёд).

#9999/TCP
tc class add dev $IF parent 1:1 classid 1:20 htb rate 4mbit ceil 7mbit prio 0

Здесь мы задали 20 класс и скорость на 4 мбит/с с ростом до 7мбит/с соответственно. Аналогично и 21 класс, я не буду его расписывать.

Ну а дальше самое интересное:

#IPTABLES RULES#
iptables -t mangle -F OUTPUT
iptables -t mangle -A OUTPUT -o $IF -p tcp -m multiport --dports 9999 -j CLASSIFY --set-class 1:20
iptables -t mangle -A OUTPUT -o $IF -p tcp -m multiport --dports 10000 -j CLASSIFY --set-class 1:21

Здесь мы берём на вооружение наш файрволл iptables и задаём правила метки трафика. В первом случае мы берём весь исходящий трафик через интерфейс eth0, протокол tcp и порт назначения 9999 и метим его классом 1:20, во втором случае – 1:21! Вроде бы всё понятно.

А теперь посмотрим, как себя будет вести трафик. Замерять скорость будем iperf.

Запускаем на принимающей стороне:

# iperf -s

Принимающая сторона

Принимающая сторона

А на нашем сервере:

# iperf -c 192.168.10.10

это IP адрес сервера (принимающей стороны).

Класс по умолчанию (1:10)

Класс по умолчанию (1:10)

Скорость 3 Мбит/с, это как раз скорость класса по умолчанию, так как мы не задали дополнительных параметров.

Теперь запустим сервер (принимающую сторону) с параметрами:

# iperf -s -p 9999

А на передающей стороне:

# iperf -c 192.168.10.10 -p 9999

Класс 1:20

Класс 1:20

Скорость уже 7 Мбит/с, что соответствует классу 1:20, которым мы метим весь трафик идущий на 9999 порт протокола tcp.

Ну и аналогично проверим порт 10000:

Класс 1:21

Класс 1:21

Как видите, ничего сложного нет. Подобным образом можно метить трафик от (к) конкретных IP адресов, протоколов и портов, чтобы задать собственные классы/приоритеты. Чтож, попробую реализовать эту систему на практике.

 



В избранное