отлаживать задержки и сетевые проблемы на уровне ядра в продакшене
eBPF в продакшене: наблюдаемость и отладка на уровне ядра для DevOps-команд
14 минут
Метрики приложений не объясняют повторные передачи TCP, задержки планирования cgroup или горячие точки системных вызовов. eBPF запускает изолированные программы в ядре Linux и снимает эти сигналы с минимальными накладными расходами — без strace, sidecar и пересборки ядра.
Почему метрики приложений не видят сбои на уровне ядра
Prometheus и APM-агенты хорошо показывают задержку сервисов, долю ошибок и насыщение ресурсов. Они не видят повторные передачи TCP, throttling cgroup, давление на inode или конкуренцию за блокировки внутри ядра. strace и tcpdump отвечают на точечные вопросы, но добавляют риск и нагрузку на CPU на живых узлах. Кратковременные симптомы — всплески давления на память, штормы futex, схлопывание TCP-окна — часто исчезают до того, как инженер подключится по SSH. Команды понимают, что нужны данные ядра, только после часов прикладного «копания в логах» во время P1. eBPF закрывает этот разрыв: проверенные программы цепляются к точкам перехвата в ядре и экспортируют структурированные события в user space с накладными расходами в однозначных процентах при корректной области применения.
Промышленный стек: программы ядра, агрегация и визуализация
Типичная схема состоит из трёх уровней. Программы ядра цепляются к tracepoints, kprobes, uprobes или LSM-хукам и пишут в BPF-карты — hash map, ring buffer или per-CPU массивы. Уровень агрегации читает эти карты: Cilium Hubble для сетевых потоков и вердиктов политик в Kubernetes, Falco или Tetragon для событий runtime security, Pixie для автотелеметрии без правок кода, Parca или Pyroscope для непрерывных профилей CPU и памяти, bpftrace для разовых one-liner на узле. Визуализация потребляет агрегированные данные через Grafana, scrape Prometheus или OTLP-экспортеры. Cilium с Hubble подходит командам, которые заменяют или дополняют CNI для обзора потоков в кластере. Falco и Tetragon — для security, но их лучше вводить после read-only observability. bpftrace — инструмент break-glass с ограничением по времени, а не постоянный DaemonSet.
bpftrace: горячие точки syscalls у «шумного» пода
Когда CPU пода высокий, а метрики приложения выглядят ровно, узкое место часто в системных вызовах, а не в бизнес-логике. Установите bpftrace на узле или запустите официальный контейнер с host PID и смонтированным debugfs. Получите PID контейнера через crictl или kubectl debug и посчитайте входы в syscalls для процесса. Доминирующие futex или epoll_wait указывают на конкуренцию за блокировки или event loop, а не на вычисления. Ограничивайте ad-hoc запуски по времени, сохраняйте вывод в тикет и избегайте пиковых окон без записи об изменении.
# Ubuntu / Debian
sudo apt-get install -y bpftrace
# Amazon Linux 2023
sudo dnf install -y bpftrace
# Эфемерный контейнер на узле (нужен privileged debug)
docker run --rm --privileged --pid=host \
-v /sys/kernel/debug:/sys/kernel/debug:ro \
quay.io/bpftrace/bpftrace:latest bpftrace --versionPID=$(crictl inspect <container-id> | jq -r .info.pid)
bpftrace -p "$PID" -e 'tracepoint:raw_syscalls:sys_enter { @[probe] = count(); }'@[tracepoint:raw_syscalls:sys_enter]: 45210
@[kprobe:sys_futex]: 380112
@[kprobe:sys_clock_nanosleep]: 1200
@[kprobe:sys_epoll_wait]: 890455bpftrace -e '
kprobe:tcp_sendmsg
/ntop(AF_INET, args->sk->__sk_common.skc_daddr) == "10.0.1.45"/
{
@start[tid] = nsecs;
}
kretprobe:tcp_sendmsg
/@start[tid]/
{
@latency_us = hist((nsecs - @start[tid]) / 1000);
delete(@start[tid]);
}'Cilium Hubble: сетевые потоки и политики на уровне кластера
Для Kubernetes Cilium с Hubble показывает потоки L3/L4, DNS-метаданные и вердикты политик без инструментирования приложений. Включите Hubble relay, UI и метрики при установке через Helm, затем фильтруйте отброшенные потоки через Hubble CLI по namespace и протоколу — ошибочная NetworkPolicy сразу видна как вердикт DROPPED. Снимайте метрики Hubble с подов Cilium на порту 9965 в Prometheus для дашбордов и алертов. Считайте Cilium платформенным решением: проверьте версию ядра, наличие BTF и последствия замены kube-proxy в staging перед продакшеном.
helm repo add cilium https://helm.cilium.io
helm repo update
helm upgrade --install cilium cilium/cilium \
--version 1.16.0 \
--namespace kube-system \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set hubble.metrics.enabled="{dns,http,tcp,flow,drop}" \
--set prometheus.enabled=trueexport HUBBLE_VERSION=$(curl -fsSL https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --remote-name-all \
"https://github.com/cilium/hubble/releases/download/${HUBBLE_VERSION}/hubble-linux-amd64.tar.gz"
tar xzf hubble-linux-amd64.tar.gz
sudo mv hubble /usr/local/bin
hubble observe --namespace production --protocol tcp --verdict DROPPEDJul 3 10:23:45.123: 10.0.1.45:54321 (default/payment-svc) -> 10.0.2.12:5432 (default/payment-db) to-stack FORWARDED (TCP)
Jul 3 10:23:45.234: 10.0.3.88:42110 (prod/order-svc) -> 10.0.2.12:5432 (default/payment-db) Policy denied DROPPED (TCP)scrape_configs:
- job_name: hubble
kubernetes_sd_configs:
- role: pod
namespaces:
names: [kube-system]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_k8s_app]
regex: cilium
action: keep
- source_labels: [__meta_kubernetes_pod_ip]
target_label: __address__
replacement: ${1}:9965Операционные практики безопасного внедрения eBPF в продакшене
Начните с read-only observability — Hubble, break-glass bpftrace, профилирование Parca — и только потом включайте enforcement в Tetragon или строгие режимы Cilium NetworkPolicy. Разверните непрерывное профилирование через Parca или Grafana Pyroscope, чтобы видеть, какие пути ядра и user space съедают CPU; храните профили на persistent volume для сравнения регрессий. Ограничивайте каждую долгоживущую BPF-карту: неограниченные hash map — частая причина давления на память ядра. CO-RE и BTF требуют ядро 5.2+ с доступной отладочной информацией; интеграция cgroup v2 — 5.7+. Перед rollout выполните bpftool feature probe и зафиксируйте minor-версии ядра в образах узлов. Храните BPF-программы в git, документируйте, что измеряет каждый probe, и тестируйте в staging на том же билде ядра, что и в продакшене. eBPF дополняет Prometheus, трейсы OpenTelemetry и агрегаторы логов, а не заменяет их. Типичный drill-down: высокая задержка в Prometheus, доминирующие futex в bpftrace, retransmit или DROPPED в Hubble, исправление NetworkPolicy или маршрутизации. Следите за самим eBPF через JSON-вывод bpftool prog и map, контролируйте дропы ring buffer и согласуйте security-инструменты с общим hardening кластера.
helm upgrade --install parca oci://ghcr.io/parca-dev/parca/charts/parca \
--namespace observability --create-namespace \
--set persistentVolume.enabled=true \
--set persistentVolume.size=50Gibpftrace -e '
BEGIN { @latency = lruhash(10240); }
// populate @latency in probes; old entries evict automatically
'bpftool feature probe kernel
bpftool prog show --json | jq -r '.[] | "\(.name): xlated \(.bytes_xlated // 0) bytes"'
bpftool map show --json | jq -r '.[] | "\(.name): max_entries=\(.max_entries // "n/a")"'Наложите сигналы ядра на прикладной baseline из гайда по observability для небольших платформенных команд.
Когда распределённые трейсы обрываются на границе syscall, продолжите расследование с распределённым трассированием OpenTelemetry в Kubernetes.
