Сразу отмечу, я невеликий специалист в сетевой подсистеме Linux. Я исхожу из следующих положений:
1) у вас, судя по всему, реализована схема
Equal cost multi-path.
2) я предполагаю, что сетевую подсистему Linux реализовывали разумные люди, поэтому выбор исходящего маршрута производится per-flow, т.е. для каждого 'потока' данных ('поток' характеризуется IP-адресами источника назначения, типом протокола (IP protocol number), портами источника и назначения)
Почему при балансировке нагрузки через один шлюз идет больше трафика, чем через другой?
Вкратце, потому что балансировки трафика не наблюдается. В моем понимании балансировка - это когда мы отслеживаем один параметр ('нагрузку', будь то утилизация линка, количество соединений, что угодно) и соответственно изменяем другой параметр (исходящий маршрут, интерфейс, и т.д.), чтобы выровнять (привести в баланс) изменения, реализуя обратную связь. В этом смысле балансировка наблюдается в различных балансировщиках нагрузки (load balancers), типа F5, haproxy и прочая.
В вашем случае, скорее всего, трафик разделяется (
load sharing) на основании того, к какому flow он принадлежит. Соответственно, повышенная утилизация одного из линков говорит о том, что есть flow высокой интенсивности (
Elephant flow), т.е. большое количество пакетов имеет один и тот же хэш и направляется в один и тот же линк. Также могут быть нюансы с разделением трафика, порожденного самим хостом. Ну и всегда есть вероятность багов в ПО.
Куда копать?
Чтобы удостовериться правильности гипотезы, вы можете снять дамп трафика (в точке до разделения на линки) и изучить его при помощи wireshark (Statitics -> Conversations -> вкладки TCP, UDP, две правые колонки в bps). Если гипотеза верна, вы обнаружите пару сокетов, утилизирующих значительную долю пропускной способности линка.
Я также исходил из того, что вы показали актуальные настройки и у вас ровно два маршрута по умолчанию. Если вдруг затесался еще один, с тем же весом (с той же метрикой), то даже в идеальном случае разделение будет, скорее всего 1:1:2. Это обусловлено особенностями реализации ECMP.
TL;DR: Это не балансировка, это разделение трафика. Идеального разделения трафика пополам в общем случае добиться крайне затруднительно.
UPD:
Сейчас машина стоит на тестовом стенде. Здесь нет вообще никакого трафика, кроме двух пингов, запускающихся для теста.
Приведите, пожалуйтса, точные команды, которые вы запускаете. Уточните, запускаете ли вы их на самом сервере-маршрутизаторе с длвумя линками или на сторонней машине. Цели для пингов - отвечают ли они на пинги. Каковы точные количественные характеристики трафика на линках (интерфейс такой-то, столько-то входящего, столько-то исходящего), как вы его меряете (среднее значение за 1,5,10 минут)
Но даже без этих данных можно сказать, что ваш тест не вполне корректен. Per-flow хэширование оптимизировано под UDP и TCP трафик. Поэтому, рекомендую вам на машине за интерфейсов eth0 (и корректно прописанным default gateway) сгенерировать при помощи
hping UDP-трафик с рандомизированными адресами источника и назначения, портами источника и назначения. Если в этом случае трафик распределится примерно равномерно, то все работает штатно.