linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Процессы и ресурсы/ebpf-basics

kb/processes ── Процессы и ресурсы ── intermediate

eBPF - программируемый kernel

eBPF - запуск sandboxed-программ в kernel без kernel-modules. Прицепляются к hooks (kprobe, uprobe, tracepoint, perf, socket, XDP). Verifier гарантирует завершение и safety. JIT компилирует в native. bpftool/libbpf/BCC - userspace tooling.

view as markdownaka: ebpf, extended-bpf, bpf, libbpf, bpftool

Что такое eBPF

extended BPF - виртуальная машина внутри kernel, на которой запускаются изолированные программы (eBPF programs), которые цепляются к "hook" точкам (вызов syscall, входящий пакет, контекст-свич) и могут читать/изменять данные, собирать метрики, фильтровать.

Историческое: cBPF (classic BPF) появился в 1992 как фильтр пакетов для tcpdump (pcap_compile). В 2014 Алексей Старовойтов расширил до eBPF: больше регистров (10×64-бит вместо 2×32-бит), новые типы программ, maps для state, JIT-компиляция в native.

Сегодня eBPF - новая базовая kernel-абстракция:

  • Networking: [[cni-plugins|cilium]], Cloudflare DDoS-фильтр, Facebook Katran (load balancer)
  • Observability: bpftrace, BCC tools, Pixie, Parca (profiler), Grafana Beyla
  • Security: tetragon, falco (runtime detection), [[seccomp|seccomp-bpf]]
  • Tracing: kprobe/uprobe replacement для DTrace, SystemTap

Архитектура

┌─────────────────────────────┐
│ userspace                   │
│ ┌──────┐  ┌──────┐  ┌─────┐ │
│ │ BCC  │  │libbpf│  │bpftl│ │  компиляция, загрузка
│ └──┬───┘  └──┬───┘  └──┬──┘ │
└────┼─────────┼─────────┼────┘
     │         │         │ syscalls (BPF_PROG_LOAD, BPF_MAP_*)
┌────▼─────────▼─────────▼────┐
│ kernel                      │
│  ┌──────────────────────┐   │
│  │ verifier             │ ← bytecode проверяется
│  └──────┬───────────────┘   │
│         ▼                   │
│  ┌──────────────────────┐   │
│  │ JIT compiler         │ → native x86-64/arm64
│  └──────┬───────────────┘   │
│         ▼                   │
│  hooks: kprobe / tracepoint │
│         tc / XDP / cgroup   │
│  ┌─────┴────────────┐       │
│  │ BPF maps (state) │       │
│  └──────────────────┘       │
└─────────────────────────────┘

Hook-типы (program types)

Каждый тип программы цепляется к своему месту в kernel:

Program typeГде attachПрименение
BPF_PROG_TYPE_KPROBEвход/выход kernel-функцииtracing kernel calls
BPF_PROG_TYPE_TRACEPOINTstatic tracepointстабильнее kprobe
BPF_PROG_TYPE_RAW_TRACEPOINTtracepoint без преобразования аргументовбыстрее, но менее портативно
BPF_PROG_TYPE_PERF_EVENTperf-event (sample N циклов)profiling, on-CPU stack
BPF_PROG_TYPE_SOCKET_FILTERsocket recv (как cBPF)tcpdump
BPF_PROG_TYPE_SCHED_CLStc-classifiernetwork policy в tc
BPF_PROG_TYPE_XDPочень рано в RX-pipelineDDoS, load balance
BPF_PROG_TYPE_CGROUP_SOCKcgroup-attached socketnetwork namespace policy
BPF_PROG_TYPE_LSMLSM hooksecurity policy

Полный список: bpftool feature или https://docs.kernel.org/bpf/

BPF maps - shared state

Программы stateless внутри одного вызова. Между вызовами и с userspace общаются через maps - типизированные KV-структуры в kernel:

Map typeОписание
BPF_MAP_TYPE_HASHхеш-таблица с произвольным ключом
BPF_MAP_TYPE_ARRAYмассив с index-key
BPF_MAP_TYPE_PERCPU_HASHper-CPU без блокировок
BPF_MAP_TYPE_LRU_HASHLRU eviction при заполнении
BPF_MAP_TYPE_RINGBUFring buffer для отправки event'ов в userspace
BPF_MAP_TYPE_PERF_EVENT_ARRAYустаревший вариант RINGBUF
BPF_MAP_TYPE_LPM_TRIElongest-prefix-match (для CIDR routing)
BPF_MAP_TYPE_PROG_ARRAYtail call - один прог вызывает другой
BPF_MAP_TYPE_SOCKMAPmapping socket → BPF program

Userspace читает/пишет через bpf(BPF_MAP_LOOKUP_ELEM) syscall.

Maps persist через pinning в /sys/fs/bpf/:

bpftool map pin name my_map /sys/fs/bpf/my_map

Несколько программ могут шарить один map.

Verifier - почему eBPF safe

При загрузке через bpf(BPF_PROG_LOAD) ядро запускает verifier. Он симулирует выполнение программы и проверяет:

  1. Программа всегда завершится (нет беспонтонных циклов)
  2. Все memory access валидны (только in-bounds reads/writes)
  3. Регистры инициализированы перед использованием
  4. Вызовы helper-функций разрешены для этого program type
  5. Указатели на map data не утекают наружу

Если что-то не так - программа отвергнута. Это и есть гарантия safety: eBPF не уронит kernel.

Ограничения classic verifier'а:

  • Стек 512 байт на программу
  • До 1M инструкций (Linux 5.2+; раньше 4096)
  • Циклы запрещены до 5.3 (с 5.3 - bounded loops с #pragma unroll или for с константной верхней границей)
  • Tail call depth ≤ 33

Если verifier ошибся (false-positive) - переписываешь код, иногда с странными хаками типа __builtin_constant_p или #pragma unroll.

Verifier не идеален - были CVE с escape: CVE-2021-3490 (alu32 sign extension), CVE-2022-23222 (pointer arithmetic). Patch быстрые, но reminder что eBPF не magically secure.

JIT - native speed

После verify программа JIT-компилируется в native код целевой архитектуры. На x86-64/arm64 - честный machine code, исполняется без интерпретации. Включается через:

sysctl -w net.core.bpf_jit_enable=1   # default since 4.15

Производительность близка к kernel-модулю. Cilium replaces iptables-based kube-proxy на eBPF и получает 5-10x improvement на больших rule sets.

Userspace стек

bpftool - swiss-army-knife

Из linux-tools-pkg или собрать из kernel-source:

bpftool prog list                     # все loaded программы
bpftool prog show id 42               # детали по ID
bpftool map list                      # все maps
bpftool map dump name my_map          # содержимое
bpftool feature                       # какие program types/helpers есть
bpftool gen skeleton prog.bpf.o       # сгенерить .h skeleton для libbpf

libbpf (C, рекомендованный путь)

Современный libc-style API. Программа = два файла:

c
// hello.bpf.c
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
SEC("tracepoint/syscalls/sys_enter_execve")
int trace_execve(void *ctx) {
    bpf_printk("execve called\n");
    return 0;
}
char LICENSE[] SEC("license") = "GPL";

Сборка: clang -O2 -target bpf -c hello.bpf.c. Загрузка через libbpf

  • skeleton-генерация через bpftool gen skeleton.

BCC (Python, legacy но удобно)

Old-school: пишешь Python, внутри строкой - C-код, BCC компилирует при запуске:

python
from bcc import BPF
BPF(text='int kprobe__sys_clone(void *ctx) {
     bpf_trace_printk("clone\\n"); return 0; }').trace_print()

Минус: тащит за собой LLVM в runtime, медленный старт. Современная альтернатива - libbpf + CO-RE (bpf-co-re).

bpftrace (DTrace-like one-liners)

bpftrace -e 'kprobe:do_sys_open { printf("%s opened %s\n", comm, str(arg1)); }'

Идеально для интерактивного debug на проде.

Helper-функции

Внутри eBPF доступен ограниченный набор kernel-функций - "helpers":

  • bpf_get_current_pid_tgid() - какой процесс
  • bpf_get_current_comm(&buf, sz) - имя процесса
  • bpf_ktime_get_ns() - время
  • bpf_map_lookup_elem(&map, &key) - чтение из map
  • bpf_perf_event_output() / bpf_ringbuf_output() - отдать event userspace
  • bpf_get_stackid() - stack trace
  • bpf_redirect(), bpf_clone_redirect() - сетевая обработка

Полный список: bpftool feature или man bpf-helpers.

Когда что-то пошло не так

  • Permission denied при загрузке - eBPF загрузка требует CAP_BPF (Linux 5.8+) или CAP_SYS_ADMIN. Запускай root или с capability.
  • R0 invalid mem access - verifier обнаружил unbounded access. Проверь if (ptr + len > end) return 0; перед чтением.
  • back-edge from insn X to Y - цикл, до 5.3 не разрешён. Развёрни через #pragma unroll.
  • program is too large - inline функции делают bytecode большим. Раздели через tail call (BPF_MAP_TYPE_PROG_ARRAY).
  • bpftool без output, программа есть - проверь permissions /sys/fs/bpf/, debugfs смонтирован (/sys/kernel/debug/).
  • bpf_printk ничего не выводит - читать из /sys/kernel/debug/tracing/trace_pipe (нужно root).
  • CO-RE не связывается - см. bpf-co-re: vmlinux.h собран не под целевое ядро.

Где почитать

  • https://docs.kernel.org/bpf/ - официальная документация
  • https://ebpf.io/ - tutorial и каталог проектов
  • "BPF Performance Tools" Brendan Gregg - bcc/bpftrace examples
  • https://github.com/iovisor/bcc - сотни готовых tools
  • https://github.com/libbpf/libbpf-bootstrap - стартовый шаблон libbpf+CO-RE

§ команды

bash
bpftool prog list

Все загруженные eBPF-программы с ID, type, name

bash
bpftool map list

Все BPF-maps в системе

bash
bpftool map dump name my_map

Содержимое конкретной map (или по ID/pinned-path)

bash
bpftool feature probe

Какие BPF program types и helpers доступны на этом kernel

bash
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { @[comm] = count(); }'

Подсчитать openat-syscall'ы по процессам - one-liner DTrace-style

bash
cat /sys/kernel/debug/tracing/trace_pipe

Читать вывод bpf_printk() - dump в реальном времени

bash
bpftool prog tracelog

Wrap для trace_pipe - то же содержимое, но через bpftool

bash
sysctl net.core.bpf_jit_enable

Проверить что JIT включён (1=on, 2=on+debug-output) - default 1 с 4.15

§ см. также

  • seccompseccomp - фильтр системных вызововseccomp - kernel-level фильтр syscall'ов. Процесс декларирует «можно только эти», и kernel отсекает остальные. Основа sandbox'а Docker и Chrome.
  • cni-pluginsCNI plugins - сеть Kubernetes (calico, cilium, flannel)CNI - спека плагина: дай pod IP и сеть. Реализации: flannel (VXLAN L2-overlay), calico (BGP routing), cilium (eBPF в kernel). Каждая даёт NetworkPolicy для firewall'а между подами. IPAM - часть CNI, выделяет адреса.
  • auditdauditd - syscall и file auditauditd пишет события ядра в /var/log/audit/audit.log: file watches (-w), syscall rules (-a), exec'и. ausearch для поиска, aureport для отчётов. Основа compliance (PCI-DSS, HIPAA, ФЗ-152).
  • kubelet-internalskubelet - архитектура агента ноды Kuberneteskubelet - демон на каждой ноде. Получает PodSpec через API, запускает контейнеры через CRI, монтирует volumes через CSI, следит за health. При pressure делает eviction. Image GC и cgroup-tree - тоже его.
  • kernel-modulesKernel modules - LKM, modprobe, signing, DKMSLKM - код, динамически загружаемый в kernel. modprobe резолвит зависимости через depmod. Подпись модуля для Secure Boot. DKMS пересобирает out-of-tree модули после kernel-upgrade. Lockdown mode запрещает загрузку неподписанных.
  • cmd-stracestrace - какие syscall'ы делает процесс`strace` показывает в реальном времени какие системные вызовы делает процесс и с какими аргументами. Главный инструмент когда «процесс молчит».
  • pyroscope-continuous-profilingContinuous profiling: Pyroscope, eBPF, flame graphs в продеContinuous profiling - always-on CPU/memory profiler в проде через eBPF. 1-2% overhead. Flame graphs показывают hot path. Pyroscope (Grafana), Parca, Polar Signals. Замена ad-hoc perf для production debug.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки