eBPF for Observability

eBPF lets small, verified programs run inside the Linux kernel in response to events — a system call, a packet arriving, a function being entered — without changing kernel source or loading a kernel module. For observability, that means watching what every process on a machine does from the outside, with no SDK, no sidecar and no restart.

It is the technology underneath Cilium, Falco, the Amazon VPC CNI’s network policy agent, GuardDuty’s runtime monitoring and most zero-instrumentation tracing tools.

How it works

 user space                         │ kernel
                                    │
 your tool ── loads bytecode ──────►│ verifier: proves the program is safe
      ▲                             │      │
      │                             │      ▼
      │                             │ JIT: compiles to native machine code
      │                             │      │
      │                             │      ▼
      └──── reads maps / ring buffer◄──── program runs when its hook fires
                                    │      hooks: kprobe, tracepoint, uprobe,
                                    │             XDP, tc, cgroup, LSM, perf event
PieceRole
ProgramRestricted C (or Rust) compiled to eBPF bytecode
VerifierRejects anything that could crash or hang the kernel: unbounded loops, invalid memory access
JITTurns bytecode into native instructions, so overhead is small
HooksThe events a program attaches to
MapsKey-value stores shared between kernel programs and user space
CO-RE / BTF”Compile once, run everywhere”: type information that lets one binary work across kernel versions

The verifier is what distinguishes eBPF from a kernel module. A buggy module can panic the machine; a buggy eBPF program is refused at load time. Background on the kernel interfaces involved: sys, process management and strace, which answers some of the same questions with far more overhead.

Hook points and what they reveal

HookFires onUsed for
TracepointsStable, documented kernel eventsSyscalls, scheduler, block I/O, TCP state changes
kprobes / fentryEntry or exit of almost any kernel functionDeep kernel tracing; not a stable interface
uprobes / USDTFunctions in user-space binaries and librariesReading TLS plaintext at the library boundary, tracing runtimes
XDPA packet, at the driver, before the network stackVery fast filtering and load balancing
tc (traffic control)Packets entering or leaving an interfaceContainer networking, policy, flow visibility
cgroup hooksSocket operations per cgroupPer-container network accounting and policy
LSM hooksSecurity decisionsEnforcement, not only detection
perf eventsTimer or hardware counterSampling profilers

What you get without touching the application

Network visibility. Every connection, with source and destination workload, bytes, retransmits and latency. Because the program sees packets and sockets, it can build a service map and golden-signal metrics for HTTP, gRPC, DNS and Kafka without any instrumentation. Tools: Cilium Hubble, Pixie, Grafana Beyla, Coroot. The networking model underneath is in CNI and network namespaces.

Continuous profiling. A sampling profiler attached to a timer captures stack traces for every process on the node at a few percent overhead or less. The result is a flame graph of where CPU time goes fleet-wide, always on. Tools: Parca, Pyroscope’s eBPF profiler, the OpenTelemetry eBPF profiler.

Auto-instrumentation. By hooking the kernel’s socket calls and common libraries, tools generate request traces and RED metrics for services that have none. This is a fast way to get baseline telemetry for legacy or third-party workloads. Grafana Beyla and the OpenTelemetry eBPF instrumentation project emit standard OTLP.

Security observability. Process executions, file opens, privilege changes and network connections, attributed to the container and pod that made them. Tools: Falco, Tetragon, Tracee. See Falco and runtime detection.

Ad hoc investigation. bpftrace and the BCC tools answer one-off questions on a live system:

# Which processes are opening which files?
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
 
# Block I/O latency as a histogram
biolatency
 
# New TCP connections, with process and destination
tcpconnect
 
# Short-lived processes that a `ps` loop would miss
execsnoop

These are the modern successors to much of the classic process tooling, and they are the right instruments for the questions in systematic debugging.

eBPF in Kubernetes networking

Cilium replaces kube-proxy and iptables with eBPF programs and maps. Service load balancing becomes a hash-map lookup rather than a linear walk through rule chains, and network policy is enforced by identity rather than IP address. The same data path provides the flow logs. Managed platforms use the idea selectively: on EKS, the VPC CNI enforces network policy with eBPF, and GuardDuty uses an eBPF agent for runtime findings.

Limits

eBPF is powerful, and it is oversold. Be clear about what it cannot do.

LimitationWhy it matters
No application contextIt sees an HTTP request, not that it was a checkout for a premium customer. Business attributes need SDKs.
Trace propagation is hardLinking spans across services requires injecting headers into requests, which is possible only for some protocols and languages. Many eBPF “traces” are per-hop, not end to end.
Encrypted trafficThe kernel sees ciphertext. Plaintext requires uprobes on the TLS library, which differ per language and break with statically linked or custom crypto.
Kernel dependencyFeatures depend on kernel version and configuration; very old or locked-down kernels are excluded.
PrivilegeLoading programs needs CAP_BPF and related capabilities — effectively root on the node. The agent is a high-value target. See capabilities.
Not on every platformNo node access means no eBPF: serverless containers such as Fargate, and some sandboxed runtimes.
Overhead is low, not zeroA probe on a very hot path, or copying payloads to user space, is measurable.
Linux only, in practiceeBPF for Windows exists but the ecosystem is Linux.

How it fits with OpenTelemetry

They are complementary, not competing:

eBPFSDK instrumentation (OpenTelemetry)
EffortDeploy one DaemonSetPer-service work
CoverageEverything on the node, immediatelyOnly what has been instrumented
DepthNetwork and system boundaryInside the application, with business context
End-to-end tracesPartialComplete
Runs whereOn nodes you controlAnywhere the code runs

A sensible sequence is eBPF first for instant breadth — service maps, golden signals, profiles — and SDK instrumentation for the services where depth pays off. Both can export OTLP into the same backends (the LGTM stack or any other).

Further reading

Across the wiki