ADG Оставить заявку
Блог DevOps 6 мин чтения

eBPF-трассировка на Astra Linux: полная картина задержек PostgreSQL и Kafka без единой строчки в коде приложений

Подключили eBPF-инструменты на кластере с PostgreSQL и Kafka на Astra Linux - и получили трассировку задержек на уровне ядра без изменения кода приложений.

Контекст момента

eBPF-based observability инструменты приходят в отечественные дистрибутивы Linux - 2025

История началась с жалобы на «периодические притормаживания» в одном из production-кластеров, которые мы ведём на managed-сопровождении. Кластер: Astra Linux 2.12, PostgreSQL 15, Kafka 3.8, несколько Java-сервисов. Жалоба размытая - иногда запросы к PostgreSQL уходят в несколько секунд, иногда Kafka начинает копить consumer lag без видимой причины. Метрики Prometheus выглядят нормально, логи чистые, дашборды в Grafana ничего не показывают.

Мы решили попробовать eBPF-трассировку, хотя до этого использовали её только в тестовых средах. Оказалось, что это был правильный момент.

Почему именно eBPF и почему именно сейчас

eBPF - это механизм ядра Linux, позволяющий запускать верифицированный код в пространстве ядра без модулей и без перекомпиляции. С точки зрения observability это значит: можно цеплять хуки на системные вызовы, сетевые события, дисковые операции и видеть latency на каждом слое - от приложения до железа - не трогая само приложение.

Инструменты на базе eBPF существуют несколько лет, но долгое время Astra Linux была проблемой: собственное ядро с патчами для мандатного контроля периодически конфликтовало с требованиями BPF-верификатора, а часть bpf-хелперов была отключена в угоду безопасности. В 2.12 ситуация изменилась - ядро обновилось до версии достаточно свежей, чтобы BTF (BPF Type Format) работал корректно, а базовые eBPF-программы запускались без ручной правки политик. Это не значит, что всё идеально - но порог входа заметно упал.

Из инструментов взяли связку: bpftrace для ручной диагностики, Pixie для continuous observability, и pyroscope-ebpf-профайлер для CPU profiling без агентов в JVM.

Что мы увидели, чего раньше не видели

Первый запуск bpftrace со скриптом для трассировки latency системных вызовов pread64 и pwrite64 дал картину, которую мы не ожидали. Задержки дискового ввода-вывода у PostgreSQL распределялись нормально - 99-й перцентиль около 2 мс, что для нашего железа ожидаемо. Но у одного из Java-сервисов, который пишет в Kafka, периодически возникали системные вызовы epoll_wait с временем ожидания, уходящим за 800 мс. Причём из метрик Kafka broker-а это никак не следовало.

Дальнейшая трассировка сетевого стека через XDP-счётчики показала: проблема в ретрансмиссиях TCP между Java-сервисом и Kafka-брокером. Не потеря пакетов в классическом смысле, а именно ретрансмиссии на коротких промежутках - признак либо перегрузки сетевого буфера, либо неправильных настроек TCP stack. Оказалось: кто-то в своё время выставил net.core.wmem_max в нестандартное значение на одной из нод, и при пиковой нагрузке Java-клиент Kafka упирался в этот лимит.

Это классический пример: проблема видна только на уровне ядра. Никакие метрики JVM, никакой мониторинг Kafka consumer lag, никакие логи приложения не показывали ретрансмиссии. Prometheus node-exporter показывал общее количество ретрансмиссий на хосте, но без привязки к конкретному процессу и без временной корреляции.

Pixie на практике

Pixie - open-source observability platform под эгидой CNCF, работающая полностью на eBPF. Поднимается в Kubernetes, собирает данные о HTTP-запросах, SQL-запросах, DNS, TCP-соединениях без единого SDK в приложении. Именно «без единого SDK» нас и интересовало - менять Java-сервисы мы не хотели, да и не могли оперативно.

На Astra 2.12 поставить Pixie получилось со второй попытки. Первая упала на этапе загрузки BPF-программ с ошибкой верификатора - оказалось, что один из eBPF-хелперов, который Pixie использует для трассировки TLS, требовал capability CAP_BPF, которую нужно явно добавить в SecurityContext DaemonSet-а. После правки манифеста всё поднялось.

После запуска Pixie начал вытаскивать SQL-запросы PostgreSQL прямо из сетевого трафика - без изменения pg_hba.conf, без логирования на стороне базы. Мы увидели топ медленных запросов с реальной latency от отправки до получения ответа, причём именно с клиентской стороны - не с серверной. Это важно: pg_stat_statements показывает время выполнения на сервере, а Pixie показывает время, которое видит клиент, включая сетевую задержку. Разница иногда оказывалась существенной.

Что изменилось в подходе к диагностике

Раньше при жалобе на «тормоза» мы шли в стандартную последовательность:

  • Смотрим Grafana - метрики CPU, RAM, disk I/O, JVM heap.
  • Лезем в логи - ищем slow query в PostgreSQL, consumer lag в Kafka.
  • Запускаем tcpdump - если подозреваем сеть, но это тяжело и оперативно так не сделаешь.
  • Делаем выводы - часто приблизительные, потому что прямой видимости в kernel-пространство не было.

С eBPF-инструментами появился дополнительный слой: смотрим syscall latency по процессу, смотрим сетевой стек с привязкой к pid, смотрим дисковый I/O на уровне блочного устройства. Диагностика конкретного инцидента с ретрансмиссиями заняла около двух часов, из которых большую часть мы потратили на настройку Pixie на Astra. Без eBPF мы бы, вероятно, неделю смотрели на метрики и гадали.

Что пока остаётся ограничением

Честно о сложностях. Astra Linux с мандатным контролем накладывает ограничения на то, что eBPF-программы могут делать. Трассировка TLS-трафика (чтобы видеть plaintext до шифрования) на части окружений не поднялась вообще - там процессы работали в restricted-контексте, и необходимые hprobes не цеплялись. В итоге SQL-трассировку PostgreSQL мы увидели, потому что там трафик внутри кластера шёл без TLS. Kafka с TLS - только на уровне сетевых метрик без тела сообщений, что для observability задач и не нужно, но факт.

bpftrace-скрипты работают стабильно, но требуют навыка - это не point-and-click инструмент. Писать kprobe/uprobe-программы, не угробив production-ноду неправильным хуком, нужно уметь.

Pixie не имеет нормальной коробочной интеграции с OTel Collector - данные уходят в собственный PEM (Pixie Edge Module), и пробрасывать их в Tempo или Grafana Tempo приходится через API. Мы настроили экспорт основных span-ов через OpenTelemetry-плагин, но это не коробочное решение.

Где мы сейчас

Клиент получил конкретную причину «притормаживаний» - настройки TCP-буфера - и мы их поправили. Pixie работает в кластере уже несколько недель в режиме постоянного наблюдения. Само по себе это дало несколько неожиданных находок: один из сервисов делал повторные DNS-запросы каждые несколько секунд вместо кэширования, что никогда не всплывало в обычном мониторинге.

eBPF-трассировка не заменяет OpenTelemetry-инструментацию приложений - когда SDK встроен, данные богаче и контекст сохраняется через границы сервисов. Но там, где код менять нельзя или некогда, а видимость нужна прямо сейчас, eBPF закрывает слой, который иначе остаётся тёмным.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.