LINUX.ORG.RU
ФорумAdmin

Разделеть uplink bandwidth честно между всеми хостами сети

 , , , ,


0

2

Привет. Представим, что есть:

  1. VPS сервер, download/upload скорость не гарантирована, может 10 mbps, а может и 500 mbps
  2. VPS сервер является WG сервером, образует со своими клиентами локалку, клиенты используют сервер как gateway шлюз в инет
  3. Несколько заметок о движении трафика:
    3.1. когда клиент download: сервер download -> трафик попадает на WG интерфейс (возможно несколько flow, если загрузка данных от > 1 хоста в инете) -> из WG интерфейса выходит один encrypted flow (даже если входящих flow > 1) -> eth0 -> хост клиента
    3.2. когда клиент upload: хост клиента (всегда один encrypted flow) -> eth0 сервера -> порт WG -> трафик выходин из WG интерфейса, возможно трансформируется в несколько flow (если отдаём что-то нескольким хостам в инете) -> eth0

Из п3 видна асимметрия - когда клиент загружает данные, то сервер отдаёт хосту в локалке данные всегда в одном потоке, когда хост в локалке выгружает данные куда-то в инет, то из сервера может выходить несколько потоков (flow - уникальный набор src/dest ip/port).

Почему это важно? А потому что это мешает адекватно (относительно честно) разделить uplink канал сервера. Дефолтный fq_codel qdisc делит канал честно между всеми flow, но все download клиента упакованы в один flow, в то время как upload потоков может быть множество. Следовательно, скорость выгрузки клиентов локалки потенциально может забить всю пропускную способность канала и быть сильно больше download.

А что для меня честно? У каждого клиента своя равная доля канала, где upload <= download (желательно меньше). fq_codel сделает честную максимальную download скорость между всеми клиентами, а upload скорость будет зависеть от количества потоков (активных коннектов), не подходит.

Если бы у сервера была бы гарантированная минимальная скорость uplink канала, то я мог бы заюзать одну CAKE qdisc на WG egress c лимитом в 70% от min uplink speed (download клиентов); Входящий трафик из WG направить IFB интерфейс, где применил бы ещё один CAKE c лимитом в 30% от min uplink speed (upload клиентов). CAKE’и классифицировали бы трафик по host’у и flow, и всё бы было как хотел - у каждого хоста своя доля (отдельно upload и download), внутри этой доли у каждого flow свой кусочек канала.

Но проблема в том, что у сервера нет гарантированной bandwidth speed, следовательно, я не могу заюзать CAKE, без указания максимального лимита он бесполезен (т.к. он не будет узким местом).

Что можно сделать, какие идеи, какую qdisc можно использовать, как разделить канал честно?



Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от futurama

Ну одна зацепка всё же есть.

Ведь fq_codel не требует указания bandwidth. Предполагаю, что он делает что-то вроде пересортировки очереди на отправку - если от условного потока №5 пакеты поступают реже, чем от потока №2, то пакеты от потока №5 имеют больший приоритет, уходят сразу при поступлении, обгоняя пакеты потока №2 (которые хранятся некоторое время в буфере).

При этом всеь upload трафик клиентов локалки выходит из WG интерфейса, и имеет предсказуемый src ip (qdisc даже может «размотать» NAT, CAKE умеет). Так вот я подумал, что может есть какой-то qdisc схожий с fq_codel, но которому можно сказать: «смотри, вот тебе подсеть/адрес 192.168.1.0/24, все потоки от каждого хоста из этой подсети воспринимай как один flow, а не множество разных, дальше всё делай как и fq_codel». По идее, это бы решило задачу

kvpfs_2
() автор топика
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от kvpfs_2

Предполагаю, что он делает что-то вроде пересортировки очереди на отправку - если от условного потока №5 пакеты поступают реже, чем от потока №2, то пакеты от потока №5 имеют больший приоритет, уходят сразу при поступлении, обгоняя пакеты потока №2 (которые хранятся некоторое время в буфере).

Посмотрел как он работает - для каждого потока создаётся своя очередь на отправку, далее из каждой очереди выгребается сколько-то пакетов, передаётся в NIC. Если какая-то очередь переполнится, то пакеты в ней будут дропаться.

Да, мне нужен qdisc подобный fq_codel, но которому можно сказать, что всё что приходит от x.x.x.x - ставь в одну очередь. Да, может это не очень правильно (по-хорошему нужна гарантированная мин скорость + CAKE), но это ведь всё для того случая, когде основной трафик - download, а если кто-то там торренты раздаёт - то виноват сам, пусть страдает

kvpfs_2
() автор топика
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от kvpfs_2

Наверное, меня осенило

Надо взять какую-нибудь classfull qdisc (DRR, например), к ней добавить fq_codel (download всех клиентов), также надо добавить одну pfifo для каждого клиента (его upload). Добавляем фильтр, который будет добавлять в pfifo соответствущего клиента или fq_codel иначе. DRR имеет параметр quantum, т.е. можно задавть веса (как интенсивно выгребать из каждой очереди). Фильтры умеет смотреть за NAT, вроде как можно эффективно смотреть на src ip (что там с хэшами имеется). Вроде звучит как что-то потенциально рабочее. Конечно много приседаний для добавления каждого клиента и хотелось бы что-то более прстое, но и кленты добавляются автоматом. Во всяком случае покопать в этом направлении можно, может что-то получиться

kvpfs_2
() автор топика
Ответ на: комментарий от kvpfs_2

С другой стороны, если я вот это всё сделаю, и текующий bandwidth == 10 mbps, то вот этот вот bottleneck будет не на моём vps::eth0 а где-то выше по топологии. Следовательно, из моих очередей пакеты будут улетать мигом, никакой честности не получится.

В общем да, похоже, что если нет гарантированной пропускной способности, то ничего не выйдет.

kvpfs_2
() автор топика
Ответ на: комментарий от kvpfs_2

Ну тогда значение из костыльного скрипта брать iperf подобного и ставить в bandwith max

pinachet ★★★★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария