DevOps

eBPF и observability в Kubernetes: глубокий мониторинг микросервисов без изменения кода

Ruslan Ismailov Опубликовано 12 мин чтения
E

Введение: eBPF — революция в наблюдаемости

Традиционный подход к observability в Kubernetes строился вокруг sidecar-агентов, инструментирования кода и тяжёлых APM-решений. Каждый микросервис требовал ручного добавления SDK, настройки трейсинга и дополнительного контейнера-агента рядом с основным. В 2026 году этот подход всё чаще уступает место революционной технологии — eBPF (extended Berkeley Packet Filter).

eBPF позволяет запускать безопасный, верифицированный код прямо в ядре Linux без изменения его исходников и без перезагрузки системы. Для Kubernetes и микросервисов это означает глубокую наблюдаемость на уровне syscall, сети и CPU — без единой строки изменённого кода приложения. Инструменты на базе eBPF собирают телеметрию на уровне ядра и передают её в пространство пользователя с минимальным оверхедом.

eBPF делает для Linux то же, что JavaScript сделал для браузеров: позволяет динамически расширять возможности ядра без его изменения. — Brendan Gregg

Как eBPF работает в контексте Kubernetes

В среде Kubernetes каждый Pod работает в изолированном пространстве имён Linux (network namespace, PID namespace). eBPF-программы, загруженные в ядро, прикрепляются к различным точкам трассировки:

  • kprobes/kretprobes — перехват вызовов функций ядра
  • tracepoints — статические точки трассировки в ядре
  • XDP (eXpress Data Path) — перехват сетевых пакетов на уровне сетевой карты
  • tc (traffic control) — перехват трафика на уровне сетевого стека
  • uprobe — трассировка функций в пространстве пользователя

Ключевое преимущество в контексте Kubernetes — один eBPF-агент на узле (DaemonSet) покрывает все поды на этом узле. Не нужен отдельный sidecar-контейнер для каждого микросервиса. Это снижает накладные расходы на CPU и память в разы, а также упрощает операционное управление.

eBPF-программы используют специальные структуры данных — maps — для обмена данными между ядром и пространством пользователя. Данные о системных вызовах, сетевых соединениях, задержках и ошибках собираются в real-time и экспортируются в форматах, совместимых с Prometheus, OpenTelemetry и Grafana.

Инструменты на базе eBPF: Cilium, Hubble, Pixie, Tetragon

Cilium

Cilium — CNI-плагин (Container Network Interface) для Kubernetes, построенный полностью на eBPF. Он заменяет традиционные iptables-правила на eBPF-программы, обеспечивая более высокую производительность и гибкость сетевых политик. Cilium поддерживает L3/L4/L7 политики, шифрование WireGuard/IPsec и интеграцию с сервисными мешами без Envoy-sidecar.

Hubble

Hubble — слой observability поверх Cilium. Он предоставляет полную видимость сетевых потоков между сервисами: кто с кем общается, какие HTTP-эндпоинты вызываются, где возникают задержки и ошибки. Hubble работает без изменения кода приложений и без sidecar — вся информация извлекается из eBPF-программ Cilium.

Pixie

Pixie (от New Relic, open-source) — платформа observability на базе eBPF для Kubernetes. Поддерживает автоматическое обнаружение протоколов (HTTP/2, gRPC, MySQL, PostgreSQL, Redis), трассировку запросов, профилирование CPU. Использует собственный язык запросов PxL, похожий на Python/pandas. Pixie работает полностью in-cluster, не передавая данные наружу по умолчанию.

Tetragon

Tetragon от Isovalent — инструмент runtime security и observability на базе eBPF. Обеспечивает видимость на уровне syscall, process execution, network connections и file access. Может применять политики безопасности прямо в ядре, блокируя подозрительные действия в реальном времени.

Сравнивая инструменты: Cilium+Hubble — лучший выбор для сетевой observability и политик; Pixie — для быстрого старта с полным стеком без конфигурации; Tetragon — для security-сценариев и compliance. В production 2026 года часто используют все три в связке.

Практика: установка Cilium и Hubble в Kubernetes-кластер

Установка Cilium через Helm — стандартный путь для production-кластера. Убедитесь, что версия ядра Linux не ниже 5.4 (рекомендуется 5.15+).

# Добавляем Helm-репозиторий Cilium
helm repo add cilium https://helm.cilium.io/
helm repo update

# Устанавливаем Cilium с включённым Hubble
helm install cilium cilium/cilium \
  --version 1.15.0 \
  --namespace kube-system \
  --set hubble.enabled=true \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true \
  --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2}" \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=YOUR_API_SERVER_IP \
  --set k8sServicePort=6443

После установки проверяем статус Cilium:

# Проверка статуса агентов
kubectl -n kube-system get pods -l app.kubernetes.io/name=cilium

# Проверка через cilium CLI
cilium status --wait

# Проверка Hubble
cilium hubble port-forward &
hubble status
hubble observe --follow

Hubble UI доступен через port-forward:

kubectl port-forward -n kube-system svc/hubble-ui 12000:80

В браузере по адресу http://localhost:12000 вы увидите граф сервисных зависимостей в реальном времени: какие поды общаются, по каким портам, с какими HTTP-кодами ответа. Это работает для любых микросервисов без каких-либо изменений в их коде.

Пример NetworkPolicy на уровне L7 через Cilium CRD:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-api-to-backend
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend-service
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: api-gateway
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/api/v1/.*"
        - method: "POST"
          path: "/api/v1/orders"

Профилирование Go-микросервисов через eBPF: continuous profiling

Профилирование Go-сервисов в production исторически было болезненным: встроенный pprof требовал явного включения HTTP-эндпоинта, а continuous profiling съедал значительные ресурсы. eBPF меняет это кардинально.

Parca и Pyroscope (теперь часть Grafana Stack как Grafana Pyroscope) используют eBPF для непрерывного профилирования CPU без инструментирования кода. Они периодически снимают стеки вызовов (stack traces) через eBPF-программы, прикреплённые к perf_event, и строят flame graphs в реальном времени.

Установка Pyroscope через Helm:

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

helm install pyroscope grafana/pyroscope \
  --namespace monitoring \
  --create-namespace \
  --set pyroscope.components.querier.resources.limits.memory=512Mi

Установка Grafana Alloy (агент) с eBPF-профилированием:

helm install alloy grafana/alloy \
  --namespace monitoring \
  --set alloy.configMap.content='
pyroscope.ebpf "ebpf_profiler" {
  targets = discovery.kubernetes.pods.targets
  forward_to = [pyroscope.write.default.receiver]
}

pyroscope.write "default" {
  endpoint {
    url = "http://pyroscope:4040"
  }
}

discovery.kubernetes "pods" {
  role = "pod"
}'

Для Go-сервисов eBPF-профайлер автоматически разворачивает стеки вызовов с использованием DWARF debug info или frame pointers. Начиная с Go 1.21, frame pointers включены по умолчанию, что значительно улучшает качество профилей. Flame graphs в Grafana позволяют увидеть, какие функции микросервиса потребляют больше всего CPU — без единого изменения в коде сервиса.

Важно: для корректного профилирования Go-бинарников через eBPF рекомендуется компилировать с флагом -gcflags="all=-trimpath" и убедиться, что бинарник не stripped (или доступны отдельные символы).

Безопасность через eBPF: Tetragon и runtime security

Tetragon переводит runtime security на новый уровень. Вместо того чтобы анализировать логи или события post-factum, он работает in-kernel: eBPF-программы перехватывают системные вызовы и могут как логировать, так и блокировать действия в реальном времени.

Установка Tetragon:

helm repo add cilium https://helm.cilium.io/
helm install tetragon cilium/tetragon \
  --namespace kube-system \
  --set tetragon.grpc.address="localhost:54321"

Пример TracingPolicy для обнаружения выполнения подозрительных бинарников:

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: detect-shell-execution
spec:
  kprobes:
  - call: "sys_execve"
    syscall: true
    args:
    - index: 0
      type: "string"
    selectors:
    - matchArgs:
      - index: 0
        operator: "Postfix"
        values:
        - "/sh"
        - "/bash"
        - "/python3"
      matchActions:
      - action: Sigkill

Эта политика автоматически уничтожает процесс, если внутри контейнера запускается shell — классический признак атаки. Tetragon экспортирует события в формате JSON, совместимом с SIEM-системами (Elastic, Splunk). Интеграция с Falco и OPA позволяет строить многоуровневую защиту.

В контексте Kubernetes Tetragon видит каждый fork/exec, каждое сетевое соединение и каждую операцию с файловой системой внутри подов — без изменения манифестов деплойментов.

Сравнение с классическим подходом: sidecar + OpenTelemetry

Классический подход к observability в Kubernetes предполагает:

  • Sidecar-контейнер (Envoy, Jaeger agent) в каждом поде
  • Инструментирование кода через OpenTelemetry SDK
  • Ручная настройка трейсинга в каждом микросервисе
  • Дополнительные ресурсы: ~50-100MB RAM и ~0.1 CPU на pod

Подход на базе eBPF предлагает:

  • Один DaemonSet на node вместо sidecar в каждом поде
  • Zero-code instrumentation — код приложения не меняется
  • Данные из ядра: более полные и достоверные
  • Меньший overhead: ~10-30MB RAM и ~0.05 CPU на node

Когда использовать OpenTelemetry + sidecar: когда нужна бизнес-логическая трассировка (контекст запроса, пользовательские атрибуты), детальные спаны внутри одного сервиса, или когда используются устаревшие версии ядра Linux (до 5.4). В CI/CD пайплайнах для тестирования сервисов инструментирование кода даёт более точные данные о внутреннем поведении.

Когда использовать eBPF: для инфраструктурного мониторинга, сетевой observability, security, профилирования и в ситуациях, когда изменение кода нежелательно или невозможно (сторонние сервисы, legacy). В 2026 году best practice — гибридный подход: eBPF для инфраструктурного слоя, OpenTelemetry для бизнес-трейсинга.

Ограничения eBPF: версии ядра, права, совместимость

eBPF — мощная технология, но с важными ограничениями, которые нужно учитывать в production:

  • Версия ядра Linux: минимум 4.9 для базового eBPF, 5.4+ для большинства фич, 5.15+ для полного набора возможностей (BTF, CO-RE). Managed Kubernetes (EKS, GKE, AKS) обычно используют ядра 5.15+, но проверяйте конкретные AMI/node images.
  • Права: загрузка eBPF-программ требует CAP_BPF (Linux 5.8+) или CAP_SYS_ADMIN. В Kubernetes это значит, что DaemonSet-агент должен работать с повышенными привилегиями — это требует отдельного security review.
  • Windows-узлы: eBPF for Windows существует (Microsoft проект), но значительно уступает Linux-реализации. Смешанные кластеры с Windows-узлами потребуют отдельной стратегии observability.
  • Верификатор eBPF: программы проходят строгую верификацию в ядре. Сложные программы могут не пройти верификацию на старых ядрах из-за ограничения числа инструкций.
  • BTF (BPF Type Format): для CO-RE (Compile Once, Run Everywhere) необходима поддержка BTF в ядре (CONFIG_DEBUG_INFO_BTF=y). Большинство современных дистрибутивов включают это по умолчанию.
  • eBPF в managed Kubernetes: Fargate (EKS) и некоторые managed node pools имеют ограничения на eBPF из-за архитектуры гипервизора.

Roadmap observability в 2026 году

Экосистема observability на базе eBPF в 2026 году развивается стремительно. Ключевые тренды:

  • eBPF + OpenTelemetry: проект OpenTelemetry eBPF Agent (otebi) позволяет автоматически генерировать OTLP-совместимую телеметрию из eBPF-данных, заполняя разрыв между ядерным и прикладным уровнем.
  • Профилирование как стандарт: Continuous profiling становится частью базовой observability наравне с метриками, логами и трейсами — так называемые «4 столпа» вместо трёх.
  • AI-assisted anomaly detection: eBPF-данные с их высокой детализацией становятся основой для ML-моделей обнаружения аномалий в реальном времени.
  • Kubernetes Gateway API + Cilium: Cilium становится reference implementation для Gateway API, объединяя ingress, сервисную сеть и observability в едином решении.
  • eBPF в CI/CD: использование eBPF в тестовых окружениях для автоматического построения карт зависимостей и обнаружения неожиданных сетевых взаимодействий в integration tests.

Go-микросервисы выигрывают особенно: runtime Go хорошо поддаётся eBPF-трассировке, а компилятор gc начиная с версии 1.21 генерирует frame pointers по умолчанию, что критично для качественного CPU-профилирования через eBPF.

Заключение

eBPF кардинально меняет подход к observability в Kubernetes. Возможность получить глубокую телеметрию — сетевую, системную, профилировочную, security — без изменения кода микросервисов и без накладных расходов sidecar-архитектуры делает eBPF must-have инструментом для DevOps-инженеров и SRE в 2026 году.

Практический путь для начала: установите Cilium как CNI с включённым Hubble для немедленной сетевой видимости, добавьте Pyroscope для continuous profiling Go-сервисов, и настройте Tetragon для runtime security. Этот стек покроет три из четырёх столпов observability без единой строки изменённого кода приложений.

Классический подход с OpenTelemetry не уходит — он эволюционирует в сторону интеграции с eBPF-слоем, создавая гибридную модель, где ядерный уровень даёт инфраструктурную телеметрию, а SDK — бизнес-контекст. Именно эта комбинация определяет будущее observability в облачных микросервисных архитектурах.

Технологии

Теги

Руслан Исмаилов

Senior Web / Backend разработчик. Senior web/backend разработчик с 9-летним опытом. Стек: PHP, Laravel, PostgreSQL, Redis, Docker, Kubernetes, REST, микросервисы, CI/CD. Подробнее обо мне →