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 — 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.
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
| Задача | Traditional | eBPF способ |
|---|---|---|
| Что открывает файлы | strace + lsof | opensnoop |
| Slow disk | iostat | biolatency, biosnoop |
| Какие connections | tcpdump, ss | tcpconnect, tcplife |
| Что exec’ится | ps -ef в loop | execsnoop |
| Profile приложения | perf | offwaketime, profile (BCC) |
| Что в kernel medленно | perf top | funclatency |
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 интересен глубже:
- Books: ‘Learning eBPF’ Liz Rice, ‘BPF Performance Tools’ Brendan Gregg.
- bcc tools tutorial: https://github.com/iovisor/bcc/blob/master/docs/tutorial.md
- bpftrace reference: https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md
- Cilium docs — examples of advanced 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, дамп карты счётчиков