Learning Platform
Глоссарий Troubleshooting
Урок 16.05 · 20 мин
Начальный
eBPFbccbpftraceobservabilitytracingLinux

eBPF — безопасная инспекция kernel в runtime

В последних 5-10 лет в мире Linux-observability произошла революция: пришёл eBPF (extended Berkeley Packet Filter). Это технология, которая позволяет писать маленькие программы, загружаемые в kernel, выполняющиеся при определённых событиях (syscall, network packet, kernel function call), но при этом гарантированно безопасные — kernel верифицирует их перед загрузкой. eBPF — это то, на чём построены современные observability tools: Pixie, Cilium, Falco, BCC tools, bpftrace.

В этом уроке обзорно: что такое eBPF, чем отличается от kernel modules, что такое bcc и bpftrace, и какие задачи решает (без deep dive в писание программ — это материал отдельного курса).


Эволюция от BPF к eBPF

BPF (Berkeley Packet Filter, 1993) — изначально для фильтрации сетевых пакетов в Unix. tcpdump использует BPF: вы пишете tcpdump 'port 80', оно компилируется в BPF-программу, kernel выполняет её на каждом packet, отдаёт matching userspace.

eBPF (extended, ~2014) — огромное расширение:

  • 64-bit registers (вместо 32).
  • Гораздо больше instructions.
  • Программы могут читать структуры kernel (через helpers).
  • Hooks не только на network — на любые события: kprobes, tracepoints, USDT.
  • Verifier — проверяет программу перед загрузкой (нет infinite loops, нет out-of-bounds memory access).
  • Maps — shared data structures между programs и userspace.
  • JIT compiler — компилирует eBPF bytecode в native машинный код, скорость как у kernel module.

В итоге: возможность писать “kernel модули lite” — мощные, но безопасные.


Зачем eBPF (vs kernel modules)

eBPF vs Kernel Modules
Kernel modulePure C код. Загружается через insmod. Может всё, что kernel может. Если есть баг -> kernel panic. Должен быть signed для production
eBPF programELF bytecode, написан на C/Rust/Go и compiled. Загружается через bpf() syscall. Verifier проверяет на загрузку -- если небезопасно, отказ. Не может крешить kernel
Можетkernel module: всё. eBPF: ограниченный набор helpers, доступ к зарегистрированным структурам, max instruction count 1M, no unbounded loops
Riskkernel module: panic, data corruption. eBPF: только если есть bug в verifier (это уже security issue, fix-ит сообщество). Production-safe
Loadingkernel module: требует matching kernel version, rebuild на каждый upgrade. eBPF: загружается на любую kernel >=4.x с правильной CONFIG. Portable через BTF (BPF Type Format)
PerformanceОба JIT compiled в native code, аналогичная скорость. eBPF чуть медленнее из-за verifier-restrictions, но difference negligible

Главное преимущество eBPF — safety + performance. Можно писать advanced kernel instrumentation, не боясь уронить production.


Где hooked eBPF: типы программ

eBPF может цепляться (attach) к разным точкам kernel. Главные типы:

  • kprobe / kretprobe — любая kernel function. “Когда вызывается tcp_v4_connect, выполни мою программу” — получаем info о connection.
  • tracepoint — predefined event в kernel (syscall enter/exit, sched events, network events).
  • USDT (User Statically Defined Tracepoints) — маркеры в userspace библиотеках (libc, Postgres имеет их встроенными).
  • uprobe — любая userspace function (можно цепляться даже к Python).
  • XDP (eXpress Data Path) — на самом раннем месте сетевого стека (на NIC driver). Используется для DDoS protection, load balancing.
  • tc (traffic control) — на сетевом packet level, после XDP. Cilium, Calico используют для k8s network policies.
  • socket programs — на open/read/write/connect sockets.
  • LSM (Linux Security Modules) — security policies (как SELinux, но через eBPF). Falco, Tetragon используют.

bcc: коллекция готовых инструментов

BCC (BPF Compiler Collection) — репозиторий с десятками готовых eBPF-программ для observability. Большинство уже-в-составе дистрибутивов.

# Установка (Ubuntu):
sudo apt install bpfcc-tools linux-headers-$(uname -r)

# Утилиты обычно с суффиксом -bpfcc:
ls /usr/sbin/*bpfcc | head -10
/usr/sbin/argdist-bpfcc
/usr/sbin/bashreadline-bpfcc
/usr/sbin/biolatency-bpfcc
/usr/sbin/biosnoop-bpfcc
/usr/sbin/biotop-bpfcc
/usr/sbin/bitesize-bpfcc
/usr/sbin/cpudist-bpfcc
/usr/sbin/dcsnoop-bpfcc
/usr/sbin/execsnoop-bpfcc
/usr/sbin/filetop-bpfcc

Эти tools обычно требуют root (BPF загрузка). Они отвечают на конкретные вопросы:

# 1. Какие процессы запускаются (новые exec):
sudo execsnoop-bpfcc
# Видим в реальном времени каждый exec()

# 2. Latency disk I/O:
sudo biolatency-bpfcc 5      # каждые 5 сек гистограмма
# Распределение latency: 99% IO < 1 ms, 1% > 10 ms

# 3. Какие файлы открываются и кем:
sudo opensnoop-bpfcc
PID    COMM               FD ERR PATH
1234   postgres            5   0 /var/lib/postgresql/.../tableX
5678   node                7   0 /opt/app/config.json
9012   bash                3   0 /etc/passwd

# 4. Topологически "горячие" файлы:
sudo filetop-bpfcc 5
# Сортировка файлов по байтам IO в течение 5 сек

# 5. Какие process делают tcp connections:
sudo tcpconnect-bpfcc

# 6. Сетевая latency:
sudo tcplife-bpfcc       # каждое закрытое TCP-соединение и его время жизни

Это всё дешевые observability tools — работают на production с минимальным overhead.


bpftrace: язык для quick BPF-скриптов

bpftrace — awk/dtrace-подобный язык для написания one-liner eBPF-скриптов. Гораздо проще чем писать BPF на C.

sudo apt install bpftrace

# Помощь:
sudo bpftrace -l '*'  | head     # список доступных probes (тысячи)

Примеры one-liners:

# 1. Считать syscalls по типу:
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[probe] = count(); }'
# Ctrl-C, увидим топ syscalls

# 2. Latency syscall read:
sudo bpftrace -e '
    tracepoint:syscalls:sys_enter_read { @start[tid] = nsecs; }
    tracepoint:syscalls:sys_exit_read /@start[tid]/ {
        @us = hist((nsecs - @start[tid]) / 1000);
        delete(@start[tid]);
    }'

# 3. Какие процессы вызывают openat() и какие файлы:
sudo bpftrace -e '
    tracepoint:syscalls:sys_enter_openat {
        printf("%s pid=%d %s\n", comm, pid, str(args->filename));
    }'

# 4. TCP retransmits (network issue indicator):
sudo bpftrace -e '
    tracepoint:tcp:tcp_retransmit_skb {
        printf("retransmit src=%s -> dst=%s\n", ntop(args->saddr), ntop(args->daddr));
    }'

# 5. Page faults per process:
sudo bpftrace -e '
    software:page-fault:1 { @[comm] = count(); }'

bpftrace компилирует ваш скрипт в eBPF, загружает в kernel, в реальном времени интерпретирует output из maps. На Ctrl-C дампит maps.


Реальные use-cases eBPF

Network performance:

  • Cilium заменяет iptables в k8s, реализует network policies через eBPF.
  • XDP DDoS protection — Cloudflare обрабатывает миллионы packets/sec в eBPF.

Security:

  • Falco — detection unusual syscalls (контейнер пытается ssh подключиться куда не должен).
  • Tetragon (Isovalent) — runtime security, blocks suspicious actions.

Observability:

  • Pixie (New Relic) — автоматическое profiling и tracing без instrumentation.
  • BCC tools, bpftrace — ad-hoc diagnostics.
  • Datadog, New Relic используют eBPF для transparent APM.
kubectl top и Metrics API: eBPF-агенты как источник метрик

Performance:

  • Sched_ext (Google, Meta) — writable scheduler на eBPF, для custom scheduling policies (game servers).
  • Glommio (DataDog) — async runtime с eBPF integration.

Debugging:

  • Profiling production без stop процессов.
  • Trace specific functions selectively.

eBPF vs traditional debugging tools

ЗадачаTraditionaleBPF способ
Что открывает файлыstrace + lsofopensnoop
Slow diskiostatbiolatency, biosnoop
Какие connectionstcpdump, sstcpconnect, tcplife
Что exec’итсяps -ef в loopexecsnoop
Profile приложенияperfoffwaketime, profile (BCC)
Что в kernel medленноperf topfunclatency

eBPF tools обычно: low overhead (менее 1%), детальнее, можно запустить ad-hoc и убрать.


CO-RE и portability

Раньше каждый BPF-программа требовала точное совпадение с kernel data structures. После kernel-upgrade — надо пересобирать. С 2020 появилась CO-RE (Compile Once - Run Everywhere): программы используют BTF (BPF Type Format — метаданные о kernel structures) для late binding. Скомпилированная на Linux 5.10 программа работает на Linux 6.5 без пересборки.

Это значит: eBPF tools stable through kernel upgrades, что критично для production.


Ограничения eBPF

Не серебряная пуля:

  • Verifier strict: программы должны быть короткими (макс ~1M instructions), без unbounded loops, со статически анализируемым access. Сложные алгоритмы не подойдут.
  • Limited memory: maximum 512 KB stack, maps — size limit.
  • Helpers limited: можно вызывать только зарегистрированные kernel helpers (для безопасности). Список расширяется, но не всё доступно.
  • Kernel version: для full features нужен Linux 5.x+. На LTS 4.x работает с ограничениями.
  • Learning curve: писать на C для eBPF — сложно. bpftrace проще, но менее мощный. Rust/Go варианты (Aya, libbpf-go) растут, но всё ещё ниша.

Куда дальше

Если eBPF интересен глубже:

В курсе мы остановимся на обзоре. Для junior DE достаточно знать что eBPF существует, что BCC tools = “вот это запустить и узнать почему медленно”, и как их искать.


Попробуй сам

# 1. Установить BCC tools и bpftrace:
sudo apt install bpfcc-tools bpftrace

# 2. Посмотреть, какие BPF-программы загружены сейчас:
sudo bpftool prog list
sudo bpftool prog show

# 3. execsnoop -- что запускается:
sudo execsnoop-bpfcc
# В другом окне запустить любую команду, увидеть в snoop output

# 4. opensnoop -- какие файлы открываются:
sudo opensnoop-bpfcc -p $(pgrep -n bash)
# Запустить cat в shell -- увидим

# 5. bpftrace простой:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat {
    printf("%s -> %s\n", comm, str(args->filename));
}'
# Запустить любую программу, увидеть все её open()

# 6. tcpconnect -- новые TCP-соединения:
sudo tcpconnect-bpfcc
# В другом окне -- curl https://example.com

# 7. cpudist -- распределение CPU on/off times:
sudo cpudist-bpfcc 10 1
# 10 секунд, потом гистограмма

# 8. biolatency:
sudo biolatency-bpfcc 5 1
# Гистограмма дисковой latency

# 9. Самый простой bpftrace -- считать syscalls по типу:
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter {
    @[probe] = count();
}'
# Ctrl-C, дамп карты счётчиков

Проверка знанийKnowledge check
Production-сервер. Жалуется, что API endpoint иногда работает в 100 раз медленнее. Не воспроизводится локально. perf flame graphs не выявили ничего особенного (большинство времени быстро). Как eBPF может помочь -- что конкретно использовать?
ОтветAnswer
Это классический случай 'tail latency' -- большинство requests fast, редкие выпадают. Flame graph aggregated, и аномалии могут утопиться в общем шуме. eBPF здесь отлично подходит: позволяет ловить specific events и анализировать их в реальном времени с минимальным overhead. Конкретные подходы: 1. funclatency-bpfcc -- гистограмма latency конкретной функции: sudo funclatency-bpfcc 'tcp_*' # все TCP syscalls Покажет: 99% быстро (< 1 ms), 0.1% медленно (> 100 ms). И count for each bucket. Дальше -- зум в slow путь. 2. biosnoop-bpfcc -- каждый IO операция отдельно с PID, latency: sudo biosnoop-bpfcc | awk '$NF > 50' # IO > 50 ms Покажет уникальные slow IO. Возможно, видим что иногда disk latency взлетает на короткий период. Цвета: бэкапы, log rotation, fsync flush? 3. offwaketime-bpfcc -- кто блокировал thread и сколько: sudo offwaketime-bpfcc -p <pid> 10 Показывает: thread X спал X миллисекунд, и кто его разбудил. Помогает найти tail latency от lock contention или IO waits, которые не видны в perf (т.к. perf только on-CPU). 4. tcpretrans-bpfcc -- TCP retransmits: sudo tcpretrans-bpfcc Если slow API -- это network issue, увидим retransmits. Это часто причина unpredictable latency. 5. tcplife-bpfcc -- каждое закрытое TCP-соединение: sudo tcplife-bpfcc | tail -100 Latency от connect до close. Если иногда > 5 сек -- backend slow. 6. Custom bpftrace -- latency конкретного syscall на конкретном PID: sudo bpftrace -e ' tracepoint:syscalls:sys_enter_read /pid == 1234/ { @start[tid] = nsecs; } tracepoint:syscalls:sys_exit_read /@start[tid]/ { $lat = (nsecs - @start[tid]) / 1000000; if ($lat > 100) { printf("slow read pid=%d tid=%d lat=%dms\n", pid, tid, $lat); } delete(@start[tid]); }' Печатает каждый slow read для PID 1234. 7. profile-bpfcc -- классический profiling с stack traces: sudo profile-bpfcc -F 99 -p 1234 30 > /tmp/profile.txt /path/to/FlameGraph/flamegraph.pl < /tmp/profile.txt > /tmp/flame.svg Аналог perf но через eBPF -- ниже overhead. Decision tree: - Если slow events на уровне IO (DB, disk) -- biosnoop, biolatency. - Если slow events network -- tcpretrans, tcplife, sockstat. - Если slow events lock contention -- offwaketime, mutex_lock с funclatency. - Если непонятно где -- offwaketime для конкретного PID -- покажет полный путь блокировки. Ключевое преимущество eBPF: можно ловить редкие события (1 in 1000). perf усредняет, eBPF может фильтровать. Дополнительно: instrument application с USDT (User Statically Defined Tracepoints). Postgres имеет встроенные probes для transactions, locks, query parsing -- доступны через bpftrace для precise tracing. Кстати, как только нашли root cause -- сразу залогать сценарий для воспроизведения. Tail latency обычно не случайна -- есть pattern (backup в полночь, GC pause, scheduled task, network spike). Понимание pattern -> определить trigger -> stable diagnostic.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 6. Что такое eBPF и в чём ключевое отличие от kernel modules?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5