Выберите продукт

Linux: eBPF для сетевого troubleshooting — где теряются пакеты (tc/qdisc/conntrack)

Когда «тормозит сеть», виноваты не всегда приложение и не всегда канал. Ниже — практичный eBPF-плейбук: как поймать TCP retransmit через bpftrace, найти tc drops в qdisc и подтвердить проблему conntrack table full.
Linux: eBPF для сетевого troubleshooting — где теряются пакеты (tc/qdisc/conntrack)

Зачем eBPF, когда есть tcpdump и ss

Классический набор для сетевой диагностики в Linux — tcpdump, ss, ip, ethtool, иногда conntrack. Этого достаточно, когда проблема видна «на проводе» или в статистике сокетов. Но как только начинается история уровня «потери есть, но где именно?» или «ретрансляции растут, но в дампе тихо», вы упираетесь в отсутствие наблюдаемости внутри ядра.

eBPF закрывает именно эту дыру: вы можете подключиться к ключевым точкам стека и ответить на вопрос: в каком месте пакеты или события исчезают, тормозят или массово дропаются — на входе в стек, на qdisc, в conntrack/NAT, на выходе к драйверу, в очередях.

Ниже — практический разбор, как собрать картину из трёх источников, которые чаще всего дают «невидимые» проблемы в проде: симптомы TCP через ss, дропы в очередях через tc/qdisc, и насыщение таблицы состояний через conntrack. А eBPF используем как «клей», который связывает симптомы с местом, где они возникают.

Быстрый чеклист симптомов: с чего начать

Прежде чем включать eBPF, полезно зафиксировать симптомы «в лоб» — это ускорит интерпретацию eBPF-данных и поможет не уйти в «трейсинг ради трейсинга».

1) TCP ретрансляции и очереди сокетов

Проверьте, есть ли явные признаки проблем доставки (retransmits, RTO, очереди):

ss -ti dst :443
ss -s
netstat -s | grep -i retrans

В выводе ss -ti обращайте внимание на рост retransmits, большие RTT, признаки RTO, а также на очереди (send-q/recv-q). Если retransmits растут, это уже хороший маркер «потери или недоставки», но ещё не ответ на вопрос «где именно».

2) Drops в qdisc (tc)

Дропы могут происходить до того, как пакет попадёт в TCP/UDP (например, на egress-очереди). Проверяем:

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

Ищите поля drops, overlimits, backlog. Если растут именно drops — это уже локализация по слою: очередь/шейпинг/буфер.

3) Переполнение conntrack

Если сервер делает NAT, балансирует L3/L4, работает как VPN-шлюз или просто имеет много коротких соединений, conntrack может стать узким местом. Признаки:

dmesg -T | grep -i conntrack
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

Сообщение conntrack table full — почти готовый диагноз. Но важно понять источник всплеска и что именно «забивает» таблицу, чтобы исправление не свелось к бесконечному повышению лимитов.

Чеклист первичной диагностики: ss, netstat и tc для поиска ретрансляций и drops

Минимальная подготовка: что нужно для eBPF в проде

На практике быстрее всего стартовать с bpftrace и утилитами из bpftool или пакета libbpf-tools. BCC тоже полезен, но чаще тяжелее по зависимостям.

Минимальные условия:

  • ядро с поддержкой eBPF (в современных LTS это норма);
  • права root (для инцидента обычно разумнее, чем долго настраивать capabilities);
  • наличие BTF (ускоряет запуск многих eBPF-скриптов и упрощает доступ к структурам ядра).

Быстрые проверки:

uname -r
bpftool feature probe | head
ls -l /sys/kernel/btf/vmlinux

eBPF тоже потребляет ресурсы. В проде держите трейсинг короткими сессиями, фиксируйте окно времени и по возможности фильтруйте по порту, адресу или cgroup, чтобы не «снимать весь мир».

Если вы выбираете площадку под сервисы с сетевой нагрузкой (прокси, балансеры, VPN, high-traffic API), удобнее, когда у вас есть полный контроль над ядром и доступ к трейсингу. В таких задачах чаще берут VDS, чтобы без ограничений использовать bpftool/bpftrace и диагностировать инциденты на уровне хоста.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Часть 1. TCP retransmit через bpftrace: подтверждаем «потери» на уровне транспорта

Если вы видите ретрансляции в ss, следующий вопрос: это реальная потеря пакетов, перегруз очередей, проблема MTU/PMTU, деградация на пути, или локальные дропы на выходе или входе?

Начнём с подтверждения события ретрансляции из ядра. В современных ядрах есть tracepoint’ы по TCP. Один из самых быстрых способов «прямо сейчас» — использовать bpftrace по tracepoint’ам.

bpftrace: счётчик ретрансляций в секунду

Сначала убедитесь, что нужные события присутствуют (названия зависят от ядра):

bpftrace -l | grep -E 'tcp:tcp_retransmit|sock:inet_sock_set_state|tcp:tcp_retransmit_skb' | head -n 50

Пример «ретрансляции в секунду» (имя tracepoint уточняйте по выводу выше):

bpftrace -e 'tracepoint:tcp:tcp_retransmit_skb { @retrans = count(); } interval:s:1 { printf("tcp retransmit/s: %d\n", @retrans); clear(@retrans); }'

Как интерпретировать результаты

  • Ретрансляции растут вместе с нагрузкой и синхронно растут drops в qdisc: вероятна локальная проблема очередей или шейпинга.
  • Ретрансляции растут, но qdisc drops = 0: смотрите RX-дропы/драйвер/NAPI, MTU/PMTU, деградацию на пути, и отдельно проверьте conntrack (если есть stateful firewall или NAT).
  • Ретрансляции растут скачками: часто это микробёрсты, конкуренция за CPU (softirq), неудачная IRQ affinity, либо буферизация в неожиданных местах.

Если вам нужно глубже разобрать инструменты и подходы, которые обычно доступны в дистрибутивах (BCC, bpftrace, libbpf-tools), пригодится материал про выбор набора для диагностики: как подобрать eBPF-инструменты для продакшена.

Часть 2. Drops в tc/qdisc: где очередь начинает «сыпаться»

Qdisc — место, где Linux реально «держит» пакеты перед отправкой и может их сбрасывать при переполнении очереди или при шейпинге/полисинге. На виртуальных интерфейсах и под нагрузкой qdisc нередко становится первым узким местом именно из-за микробёрстов.

Быстрая диагностика через tc

Фиксируем, какой qdisc стоит и сколько там дропов:

tc -s qdisc show dev eth0

Типовые варианты, которые часто встречаются:

  • fq_codel или cake — борются с буферблоатом, дропы возможны при перегрузе;
  • fq — нередко идёт как дефолт;
  • htb/tbf — шейпинг, легко устроить «самострел» неправильным rate/ceil/limit;
  • ingress/clsact — если включены фильтры/полисинг/eBPF на ingress/egress.

Что считать подозрительным

  • drops растут на egress qdisc — вы теряете пакеты ещё до «реальной отправки» в сторону линка/виртуального свитча.
  • backlog постоянно ненулевой и увеличивается — очередь не успевает разгребаться.
  • overlimits растут при шейпинге — вы упираетесь в заданный rate/ceil/limit, и это начинает проявляться как latency и retransmits.

Где тут eBPF полезен

tc -s показывает факт, но не отвечает на главный вопрос: какой трафик и какие потоки создают дропы. eBPF помогает привязать событие к 5-tuple (src/dst IP, порты, протокол) и иногда к cgroup.

Если у вас уже используется eBPF в tc (например, фильтры), обязательно проверьте счётчики самих фильтров:

tc -s filter show dev eth0 ingress
tc -s filter show dev eth0 egress

Сценарий из практики: tc показывает рост drops, приложение видит таймауты и TCP retransmits. Частая причина — слишком маленький limit у tbf или агрессивная настройка burst/latency, из-за чего микробёрсты превращаются в дропы. Дальше TCP ретранслирует, усиливая нагрузку на очереди, и получается замкнутый круг.

Часть 3. conntrack table full: когда stateful NAT начинает убивать сеть

Conntrack нужен для stateful firewall и NAT. Цена — память и CPU на ведение таблицы соединений. При всплесках коротких коннектов (особенно UDP или TCP с быстрым закрытием) таблица может заполняться, и ядро начнёт дропать новые соединения. Снаружи это выглядит как «рандомные таймауты», а в логах — conntrack table full.

Подтверждаем переполнение

dmesg -T | grep -i 'conntrack table full'
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max

Если nf_conntrack_count близко к nf_conntrack_max и параллельно пользователи жалуются на «отваливается API», вы почти наверняка нашли причину деградации.

Находим, кто забивает таблицу

Дальше нужно понять распределение по протоколам и состояниям. Если есть conntrack из conntrack-tools:

conntrack -S
conntrack -L | head

Часто «виноваты» такие классы событий:

  • бурст входящих SYN (много SYN_RECV);
  • UDP-трафик с большим количеством уникальных 5-tuple;
  • исходящие короткие подключения без keep-alive (сервис «стреляет» запросами наружу);
  • NAT на узле, который не должен был быть NAT’ом (например, случайно включён MASQUERADE).

Как eBPF помогает с conntrack

Проблема conntrack в том, что вы видите «таблица полная», но не всегда понимаете, какой именно трафик генерирует новые записи и какие пути в netfilter чаще всего срабатывают.

eBPF-трейсинг по функциям/хукам netfilter позволяет:

  • посчитать скорость создания новых conntrack entries;
  • увидеть, какие порты и протоколы лидируют;
  • сопоставить всплеск с конкретным приложением (особенно для исходящих соединений, если удобно фильтровать по cgroup).

Здесь важна сама идея: conntrack — это измеряемый поток событий. Если вы умеете померить «rate создания entries», вы обычно быстро находите первопричину (не только симптом).

Проверка conntrack: nf_conntrack_count, nf_conntrack_max и признаки переполнения таблицы

Сводим всё вместе: практический сценарий расследования

Ниже — рабочий порядок действий для инцидентов уровня «таймауты», «потери», «скачки latency».

  1. Фиксируем симптомы: ss -s, ss -ti, netstat -s. Понимаем: это больше похоже на потери/ретрансляции или на прикладные очереди.

  2. Смотрим qdisc: tc -s qdisc. Если растут drops — локализовали слой. Дальше выясняем: шейпинг/лимиты или реальная перегрузка.

  3. Проверяем conntrack: dmesg и nf_conntrack_count. Если близко к максимуму или есть conntrack table full — это отдельная ветка расследования.

  4. Подтверждаем события из ядра через eBPF: короткими сессиями bpftrace измеряем частоту ретрансляций и коррелируем по времени с ростом drops и насыщением conntrack.

  5. Корреляция: retransmit синхронно с qdisc drops — лечим очередь/шейпинг. Retransmit синхронно с conntrack saturation — лечим conntrack/NAT. Retransmit без обоих — идём в MTU/PMTU, RX/TX в драйвере, IRQ/softirq и сеть между хостами.

Если ваша проблема проявляется «между машинами» (например, балансировка TCP/UDP или прокси на уровне L4), полезно проверить конфигурацию и keep-alive на стороне балансера: настройка Nginx stream для TCP/UDP.

Частые причины и что чинить, если диагноз подтвердился

Если виноват tc/qdisc

  • Проверьте, не включён ли ограничивающий qdisc (htb/tbf) с слишком маленькими лимитами и неудачными burst/latency.
  • Если это буферблоат и длинные очереди, рассмотрите fq_codel/cake, но настройку делайте осознанно и с измерениями до/после.
  • Ищите микробёрсты: иногда помогает не «увеличить очередь», а стабилизировать отправку (пейсинг, правильный qdisc, разгрузка приложения).

Если виноват conntrack

  • Проверьте, действительно ли вам нужен conntrack для всего трафика: иногда часть потоков можно обрабатывать без stateful логики (в рамках вашей политики безопасности).
  • Поднимать nf_conntrack_max имеет смысл только вместе с расчётом памяти, CPU и мониторингом, иначе можно получить OOM или деградацию.
  • Сократите churn: keep-alive, пулы соединений, меньше коротких коннектов.
  • Найдите источник всплеска и фильтруйте как можно раньше (на периметре, на входе, в правилах firewall), не доводя до заполнения таблицы.

Если retransmits есть, но drops не видны

  • Проверяйте MTU/PMTU blackhole и MSS (особенно через туннели, VLAN, overlay).
  • Смотрите CPU softirq и обработку RX/TX (перегруз на одном ядре, IRQ affinity, RPS/RFS).
  • Проверяйте ошибки интерфейса и драйвера: ethtool -S eth0, а также общую статистику линка.

Мини-рукбук: команды, которые удобно держать рядом

# Симптомы TCP
ss -s
ss -ti dst :443
netstat -s | grep -i retrans

# qdisc / tc drops
tc -s qdisc show dev eth0
tc -s filter show dev eth0 ingress
tc -s filter show dev eth0 egress

# conntrack saturation
dmesg -T | grep -i conntrack
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

# eBPF: поиск tracepoint по TCP
bpftrace -l | grep -E 'tcp:tcp_retransmit|tcp:tcp_retransmit_skb' | head

# eBPF: ретрансляции в секунду (пример, имя tracepoint уточняйте)
bpftrace -e 'tracepoint:tcp:tcp_retransmit_skb { @retrans = count(); } interval:s:1 { printf("tcp retransmit/s: %d\n", @retrans); clear(@retrans); }'

Что мониторить, чтобы не ловить это во время пожара

Если один раз поймали такой инцидент, следующий шаг — «приземлить» его в метрики:

  • TCP retransmits, RTT, RTO (хотя бы агрегаты по хосту).
  • tc drops и backlog по ключевым интерфейсам.
  • nf_conntrack_count и доля от nf_conntrack_max, плюс скорость создания новых записей (если можете измерять).

Тогда eBPF останется инструментом второго уровня: быстро выяснить, какой трафик и почему дал всплеск — а не единственным способом понять, что вообще происходит.

Итог

eBPF не заменяет ss, tc и conntrack-инструменты — он связывает их в причинно-следственную цепочку. Практический подход такой: сначала фиксируем симптомы (ретрансляции), затем проверяем явные места дропов (qdisc), затем исключаем «тихий убийцу» conntrack, и только после этого включаем eBPF-трейсинг короткими сессиями для точной локализации и корреляции по времени.

Главное правило: не пытайтесь «лечить сеть» вслепую настройками таймаутов в приложении. Сначала измерьте: retransmit, drops, conntrack saturation. Потом чините ровно тот слой, который подтвердился метриками.

Поделиться статьей

Вам будет интересно

Linux IRQ/softirq и ksoftirqd: как убрать CPU jitter и настроить RPS/RFS, irqbalance и ethtool OpenAI Статья написана AI (GPT 5)

Linux IRQ/softirq и ksoftirqd: как убрать CPU jitter и настроить RPS/RFS, irqbalance и ethtool

Если ksoftirqd грузит CPU, растёт softirq и «пилит» задержка, обычно виноваты сетевые IRQ и распределение очередей. Разберём /proc ...
Linux: apt/yum/dnf зависают — проверяем DNS, IPv6 и MTU (практический чеклист) OpenAI Статья написана AI (GPT 5)

Linux: apt/yum/dnf зависают — проверяем DNS, IPv6 и MTU (практический чеклист)

Если apt update висит на Connecting, yum/dnf уходят в таймаут, а веб «вроде работает», чаще всего виноваты DNS (включая systemd-re ...
NVMe в Linux: scheduler, read_ahead, discard и mount options для минимальной latency и максимальных IOPS OpenAI Статья написана AI (GPT 5)

NVMe в Linux: scheduler, read_ahead, discard и mount options для минимальной latency и максимальных IOPS

Разбираем настройки, которые реально влияют на NVMe в Linux: scheduler (none и mq-deadline), read_ahead, TRIM через discard или fs ...