Zero-code инструментация с OpenTelemetry eBPF (OBI)
На этой странице:
- Введение
- Что вы получите
- Как это работает
- Требования
- Шаг 1. Включите приём OTLP на агенте
- Шаг 2. Установите OBI через Helm
- Шаг 3. Настройте
values.yaml - Шаг 4. Добавьте теги и привязку к инфраструктуре
- Полный пример
values.yaml - Шаг 5. Проверка
- Ссылки
Введение
OpenTelemetry eBPF Instrumentation (OBI) — это zero-code инструментация на основе eBPF. OBI автоматически отслеживает сетевые запросы приложения (HTTP/HTTPS, gRPC и др.) на уровне ядра Linux и сам формирует трейсы и метрики в формате OpenTelemetry (OTLP) — без изменения кода приложения, пересборки образов или подключения SDK/агентов внутрь контейнера.
Это удобно, когда:
- приложение написано на языке, для которого нет (или неудобно подключать) трейсер;
- нет возможности менять код или образ (legacy, сторонний софт, прокси вроде NGINX/Apache);
- нужно быстро получить базовую observability по входящим/исходящим HTTP-запросам.
Сформированную телеметрию OBI отправляет по OTLP в агент Proto Observability Platform, который умеет принимать OTLP (см. Подключение OpenTelemetry).
Обратите внимание
OBI даёт инструментацию на уровне протоколов (входящие/исходящие запросы). Для полной трассировки внутри процесса (спаны по функциям, запросам к БД из кода и т. п.) по-прежнему используйте языковые трейсеры из этого раздела.Что вы получите
Несмотря на zero-code инструментацию, Proto Observability Platform полностью выполняет задачи мониторинга производительности сервисов, инструментированных с помощью eBPF (OBI): обзорный дашборд сервиса, карта взаимодействия сервисов, распределённые трейсы, анализ производительности эндпоинтов и сбор логов.
Обзорный дашборд сервиса:

Карта взаимодействия сервисов:

Трейс сервиса:

Анализ производительности эндпоинтов сервиса:

Логи сервиса:

Ниже описано, как развернуть и настроить OBI, чтобы получить такой результат.
Как это работает
OBI разворачивается в кластере как DaemonSet (по одному поду на узел). Под OBI
запускается привилегированным и с hostPID, чтобы через eBPF подключаться к
процессам приложений, работающим на этом же узле. Обнаружение процессов и
обогащение телеметрии метаданными Kubernetes выполняется автоматически по правилам
discovery.
ваше приложение (под) агент ProtoOBP
┌───────────────────┐ eBPF (zero-code) (DaemonSet, OTLP receiver)
│ процесс (nginx, │◄─────────┐ ┌──────────────────────┐
│ java, go, ...) │ │ │ OTLP 4317 gRPC / │
└───────────────────┘ ┌───────┴───────┐ │ 4318 HTTP │
│ OBI DaemonSet │──┴──► OTLP traces+metrics │
└────────────────┘ └──────────────────────┘
Требования
- Кластер Kubernetes и Helm 3.
- Узлы на Linux с ядром, поддерживающим eBPF (рекомендуется 5.8 и новее).
- Установленный и работающий агент ProtoOBP с включённым приёмом OTLP (см. Шаг 1).
- OBI запускается привилегированным DaemonSet с
hostPID— это требование eBPF-инструментации (нужны права на подключение к процессам узла).
Обратите внимание
OBI работает сhostPID и видит все процессы узла. Инструментируются только те
процессы, которые соответствуют правилам discovery (см. ниже). Разворачивайте OBI
с осознанием того, что это привилегированная рабочая нагрузка.Шаг 1. Включите приём OTLP на агенте
OBI отправляет данные по OTLP, поэтому на агенте ProtoOBP должен быть включён OTLP
receiver на портах 4317 (gRPC) и/или 4318 (HTTP). Подробно это описано на
странице Подключение OpenTelemetry → Включение поддержки OpenTelemetry на агенте.
Кратко, в values.yaml Helm-чарта агента:
protoobp:
otlp:
receiver:
protocols:
grpc:
endpoint: 0.0.0.0:4317
enabled: true
http:
endpoint: 0.0.0.0:4318
enabled: true
После изменения обновите релиз агента, например:
helm upgrade protoobp -f values.yaml protoobp/protoobp --namespace protoobp
Шаг 2. Установите OBI через Helm
Для Kubernetes используется официальный Helm-чарт OpenTelemetry:
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm upgrade --install obi open-telemetry/opentelemetry-ebpf-instrumentation \
--namespace <ваш-namespace> \
-f obi-values.yaml
Файл obi-values.yaml описан ниже. OBI должен работать в том же кластере, что и
инструментируемые приложения; правила discovery указывают, какие именно рабочие
нагрузки инструментировать.
Шаг 3. Настройте values.yaml
Минимальная конфигурация чарта: режим application, привилегированный режим и
блок config.data с настройками OBI.
preset: application
privileged: true
config:
create: true
data:
attributes:
kubernetes:
enable: true
discovery:
instrument:
- namespace: <ваш-namespace>
k8s_deployment_name: <имя-deployment>
otel_metrics_export:
endpoint: http://protoobp.protoobp.svc.cluster.local:4318
otel_traces_export:
endpoint: http://protoobp.protoobp.svc.cluster.local:4318
Что инструментировать (discovery)
Блок discovery.instrument — это список правил, какие рабочие нагрузки подключать.
Правила можно задавать по имени деплоймента и namespace:
discovery:
instrument:
- namespace: payments
k8s_deployment_name: api-gateway
- namespace: payments
k8s_deployment_name: checkout
При attributes.kubernetes.enable: true OBI автоматически добавляет к телеметрии
метаданные Kubernetes (k8s.namespace.name, k8s.pod.name, k8s.deployment.name,
k8s.node.name и др.). Чтобы это работало, ServiceAccount OBI должен иметь права
на чтение pods, services, nodes и replicasets — официальный чарт создаёт
нужные ClusterRole/ClusterRoleBinding автоматически.
Куда отправлять данные (OTLP endpoint)
OBI определяет протокол OTLP по порту эндпоинта: порт, оканчивающийся на 4317,
трактуется как gRPC, на 4318 — как HTTP/protobuf.
При стандартной установке агента (Helm-релиз protoobp в namespace protoobp) в
кластере присутствуют:
- Service
protoobpв namespaceprotoobp(FQDNprotoobp.protoobp.svc.cluster.local) с OTLP-портами4317(gRPC) и4318(HTTP); - DaemonSet
protoobp(поды видаprotoobp-<hash>), работающий в режимеhostNetwork, поэтому OTLP-порты доступны и на IP узла.
Есть два рабочих варианта адреса агента:
Агент ProtoOBP, как правило, развёрнут как DaemonSet в режиме hostNetwork, поэтому
доступен на IP-адресе узла. Официальный чарт OBI уже прокидывает в под переменную
HOST_IP (из status.hostIP), поэтому достаточно задать стандартную переменную
OpenTelemetry OTEL_EXPORTER_OTLP_ENDPOINT:
env:
OTEL_EXPORTER_OTLP_ENDPOINT: "http://$(HOST_IP):4318" # HTTP; для gRPC используйте :4317
В этом случае поля otel_metrics_export.endpoint / otel_traces_export.endpoint в
config.data можно не указывать. Этот вариант соответствует рекомендации из
Подключение OpenTelemetry для Kubernetes.
У агента есть ClusterIP Service protoobp в namespace protoobp, поэтому можно
указать его DNS-имя прямо в конфиге OBI:
config:
data:
otel_metrics_export:
endpoint: http://protoobp.protoobp.svc.cluster.local:4318
otel_traces_export:
endpoint: http://protoobp.protoobp.svc.cluster.local:4318
<code>protoobp.protoobp</code> — это <code><имя-Service>.<namespace></code> при стандартной установке
агента (релиз protoobp в namespace protoobp). Если ваш релиз/namespace другой —
подставьте свои значения.
Группировка маршрутов (routes)
Чтобы идентификаторы в путях (ID пользователя, заказа и т. п.) не «раздували» имена спанов и значения меток метрик, задайте низкокардинальные шаблоны маршрутов:
config:
data:
routes:
patterns:
- /users/:user_id/home
- /api/orders/:order_id
- /api/products/:product_id/reviews
unmatched: path
Параметры в шаблоне обозначаются через :имя. Запросы, не подошедшие ни под один
шаблон, обрабатываются согласно unmatched (например, path — оставить путь как есть).
Шаг 4. Добавьте теги и привязку к инфраструктуре
Чтобы в интерфейсе Proto Observability Platform у спанов отображались ссылки на инфраструктурные сущности (кластер, узел, namespace, под) и удобная группировка, к телеметрии нужно добавить соответствующие теги. Для этого используются:
- поле
config.data.attributes.kubernetes.cluster_name— для имени кластера; - стандартная переменная
OTEL_RESOURCE_ATTRIBUTES— для статических тегов (окружение, группа сервисов и т. д.).
Перечисленные в OTEL_RESOURCE_ATTRIBUTES атрибуты добавляются ко всей
телеметрии данного пода OBI и становятся тегами на агенте.
Соглашение по именам тегов
Имена тегов (env, service_group, kube_cluster_name и др.) указывайте согласно
конвенции наименования тегов.Имя кластера
Без явного имени кластера OBI пишет предупреждение can't fetch Kubernetes Cluster Name, поле k8s.cluster.name остаётся пустым, и ссылка на кластер в интерфейсе не
строится. Задайте имя кластера:
config:
data:
attributes:
kubernetes:
enable: true
cluster_name: <имя-кластера>
Дополнительно продублируйте имя кластера тегом kube_cluster_name (см. ниже) —
именно по этому тегу строится ссылка на кластер.
Окружение, группа сервисов и произвольные теги
Статические теги задаются через OTEL_RESOURCE_ATTRIBUTES в блоке env:
env:
OTEL_RESOURCE_ATTRIBUTES: "deployment.environment=<env>,kube_cluster_name=<имя-кластера>,service_group=<группа>"
Где:
deployment.environment→ тегenv(логическое окружение:production,demoи т. д.);kube_cluster_name→ ссылка на кластер в интерфейсе;service_group→ группировка сервисов;- можно добавить любые свои пары
ключ=значениечерез запятую.
Тег узла (node)
Так как OBI — это DaemonSet с hostPID, каждый под OBI инструментирует процессы
только своего узла. Значит имя узла одинаково для всех его спанов и его можно
взять из downward API. Официальный чарт поддерживает блок envValueFrom:
envValueFrom:
NODE_NAME:
fieldRef:
fieldPath: spec.nodeName
env:
# NODE_NAME подставляется из envValueFrom (объявлен раньше env), Kubernetes
# раскрывает $(NODE_NAME) во время запуска контейнера.
OTEL_RESOURCE_ATTRIBUTES: "deployment.environment=<env>,kube_cluster_name=<имя-кластера>,service_group=<группа>,node=$(NODE_NAME)"
Тег node даёт ссылку на узел в интерфейсе.
Теги пода и namespace
Теги пода и namespace (pod_name, kube_namespace) задавать вручную не нужно —
они различаются для каждого инструментируемого пода, и OBI проставляет их
автоматически из метаданных Kubernetes (k8s.pod.name, k8s.namespace.name) при
attributes.kubernetes.enable: true.
Привязка логов сервиса (service / env / version)
OBI формирует трейсы и метрики, но не собирает логи приложения — их собирает
сам агент ProtoOBP (при включённом сборе логов контейнеров). По умолчанию агент
тегирует такие логи именем образа (например, nginx, httpd), поэтому на вкладке
«Логи» сервиса (запрос вида service:"<имя-сервиса>") они не находятся.
Чтобы логи привязались к тому же сервису, что и трейсы OBI, добавьте метки Unified Service Tagging в шаблон пода инструментируемого приложения (не пода OBI):
spec:
template:
metadata:
labels:
# = имя, под которым сервис виден в Proto Observability Platform
# (по умолчанию OBI использует имя deployment).
tags.proto.group/service: <имя-сервиса>
tags.proto.group/env: <env> # то же окружение, что и в OBI
tags.proto.group/version: <version>
После этого логи контейнера тегируются service / env / version и отображаются
на вкладке «Логи» соответствующего сервиса. Значение tags.proto.group/service
должно точно совпадать с именем сервиса в APM, а tags.proto.group/env — с
окружением, заданным для OBI (deployment.environment), чтобы трейсы, метрики и
логи сходились на одном сервисе.
Полный пример values.yaml
Ниже — собранный воедино пример для официального чарта
open-telemetry/opentelemetry-ebpf-instrumentation. Замените значения в угловых
скобках на свои.
preset: application
privileged: true
config:
create: true
data:
attributes:
kubernetes:
enable: true
cluster_name: <имя-кластера>
discovery:
instrument:
- namespace: <ваш-namespace>
k8s_deployment_name: <имя-deployment>
routes:
patterns:
- /users/:user_id/home
- /api/orders/:order_id
unmatched: path
# Если используете отправку по host IP (ниже, через OTEL_EXPORTER_OTLP_ENDPOINT),
# эти два поля можно не указывать. Альтернатива — слать на Service агента
# (релиз protoobp в namespace protoobp):
# otel_metrics_export:
# endpoint: http://protoobp.protoobp.svc.cluster.local:4318
# otel_traces_export:
# endpoint: http://protoobp.protoobp.svc.cluster.local:4318
# Имя узла из downward API — для тега node.
envValueFrom:
NODE_NAME:
fieldRef:
fieldPath: spec.nodeName
env:
# Отправка в агент по host IP узла (HOST_IP чарт подставляет сам).
OTEL_EXPORTER_OTLP_ENDPOINT: "http://$(HOST_IP):4318"
# Прочие настройки OBI.
OTEL_EBPF_DISCOVERY_POLL_INTERVAL: "5s"
OTEL_EBPF_METRICS_INTERVAL: "30s"
OTEL_EBPF_NAME_RESOLVER_SOURCES: "k8s,dns"
# Теги для группировки и привязки к инфраструктуре.
OTEL_RESOURCE_ATTRIBUTES: "deployment.environment=<env>,kube_cluster_name=<имя-кластера>,service_group=<группа>,node=$(NODE_NAME)"
Установка/обновление:
helm upgrade --install obi open-telemetry/opentelemetry-ebpf-instrumentation \
--namespace <ваш-namespace> \
-f obi-values.yaml
Шаг 5. Проверка
Под OBI запущен и привязался к процессам:
kubectl -n <ваш-namespace> rollout status ds/obi-opentelemetry-ebpf-instrumentation kubectl -n <ваш-namespace> logs ds/obi-opentelemetry-ebpf-instrumentation | grep -i "instrumenting process"В логах появятся строки
msg="instrumenting process"для обнаруженных процессов. Предупреждение проbpffs(если есть) не критично — трейсы и метрики работают; оно лишь отключает дополнительные функции (например, обогащение логов).Нет ошибок экспорта OTLP:
kubectl -n <ваш-namespace> logs ds/obi-opentelemetry-ebpf-instrumentation | grep -iE "export|otlp" | grep -i errorПустой вывод — ошибок нет.
В интерфейсе Proto Observability Platform появятся сервисы с трейсами и HTTP-метриками, сгруппированными по маршруту и
http.response.status_code, а у спанов — теги и ссылки на инфраструктуру (кластер, узел, namespace, под). Примеры того, как это выглядит, приведены в начале страницы, в разделе «Что вы получите».
Ссылки
- Документация OBI: https://opentelemetry.io/docs/zero-code/obi/
- Официальные примеры (NGINX, Apache) и манифесты Kubernetes: https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/tree/v0.9.0/examples
- Helm-чарт OBI: https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-ebpf-instrumentation
- Подключение OpenTelemetry (включение OTLP на агенте)
- Конвенция наименования тегов