eBPF Instrumentation: Observability a Livello Kernel
eBPF (extended Berkeley Packet Filter) e una tecnologia del kernel Linux che permette di eseguire programmi sandbox all'interno del kernel, senza modificare il codice sorgente del kernel stesso o caricare moduli kernel. Applicata all'observability, eBPF consente di ottenere tracce distribuite, metriche di performance e visibilità di rete senza modificare il codice applicativo e senza agenti.
Mentre l'auto-instrumentation di OpenTelemetry opera a livello applicativo (intercettando le chiamate alle librerie), eBPF opera a livello kernel, intercettando le syscall, i pacchetti di rete e le operazioni su file system. Questo approccio offre un overhead inferiore e una copertura più ampia, includendo servizi che non possono essere instrumentati tradizionalmente.
Cosa Imparerai in Questo Articolo
- I fondamenti di eBPF e come funziona nel kernel Linux
- Come eBPF abilita l'observability zero-instrumentation
- Pixie: observability Kubernetes basata su eBPF
- Cilium e Hubble: networking observability con eBPF
- Confronto tra eBPF e auto-instrumentation tradizionale
- Limiti attuali e scenari di adozione
Come Funziona eBPF
eBPF permette di caricare piccoli programmi nel kernel Linux che vengono eseguiti in risposta a eventi specifici: syscall, arrivo di pacchetti di rete, context switch tra processi, operazioni su file system. Questi programmi sono verificati dal kernel per garantire sicurezza (nessun crash, nessun loop infinito) e vengono compilati in bytecode efficiente.
Architettura eBPF per l'Observability
Applicazione esegue una syscall (es. connect(), write()) →
Kernel attiva il probe eBPF associato →
Programma eBPF cattura metadata (PID, timestamp, parametri) →
User-space collector legge i dati dal buffer eBPF →
OTel Collector riceve e esporta verso il backend
Tipi di Probe eBPF
I programmi eBPF possono essere attaccati a diversi punti del kernel, ognuno utile per un aspetto diverso dell'observability:
// Esempio concettuale: probe eBPF per catturare connessioni TCP
// Questo programma si attacca alla syscall connect()
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
struct connection_event {
__u32 pid;
__u32 tid;
__u64 timestamp_ns;
__u32 src_addr;
__u32 dst_addr;
__u16 dst_port;
char comm[16]; // nome del processo
};
// Buffer per inviare eventi allo user-space
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
} events SEC(".maps");
// Probe attaccato a tcp_connect
SEC("kprobe/tcp_connect")
int trace_tcp_connect(struct pt_regs *ctx) {
struct connection_event event = {};
event.pid = bpf_get_current_pid_tgid() >> 32;
event.tid = bpf_get_current_pid_tgid();
event.timestamp_ns = bpf_ktime_get_ns();
bpf_get_current_comm(&event.comm, sizeof(event.comm));
// Estrarre indirizzo e porta di destinazione
// ... (accesso alle strutture del kernel)
// Inviare l'evento allo user-space
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
&event, sizeof(event));
return 0;
}
Tipi di Probe per l'Observability
| Tipo di Probe | Punto di Attacco | Uso nell'Observability |
|---|---|---|
| kprobe/kretprobe | Funzioni del kernel | Tracciare syscall (connect, read, write) |
| uprobe/uretprobe | Funzioni user-space | Tracciare chiamate a librerie (SSL, HTTP parser) |
| tracepoint | Punti stabili del kernel | Scheduling, I/O, networking |
| XDP | Driver di rete (pre-stack) | Analisi traffico ad alte prestazioni |
| TC (Traffic Control) | Stack di rete | Monitoring traffico L3/L4 |
Pixie: Observability Kubernetes con eBPF
Pixie (ora parte del progetto CNCF) e una piattaforma di observability per Kubernetes che usa eBPF per fornire visibilità automatica su applicazioni, rete e infrastruttura senza richiedere modifiche al codice, agent applicativi o sidecar.
# Installare Pixie su un cluster Kubernetes
# Prerequisiti: Kubernetes 1.21+, kernel Linux 4.14+
# 1. Installare la CLI di Pixie
bash -c "$(curl -fsSL https://withpixie.ai/install.sh)"
# 2. Deploy di Pixie nel cluster
px deploy
# 3. Verificare lo stato
px get viziers
# 4. Eseguire query dal terminale
# Visualizzare le connessioni HTTP tra servizi
px run px/http_data
# Latenza per endpoint
px run px/service_stats
# Traffico DNS
px run px/dns_data
# Profiling CPU (flame graph)
px run px/perf_flamegraph -- --pod=order-service
Pixie cattura automaticamente il traffico HTTP, gRPC, MySQL, PostgreSQL, Redis, Kafka e DNS a livello kernel, ricostruendo le richieste e calcolando latenze senza alcuna instrumentazione applicativa.
Cilium e Hubble: Network Observability
Cilium e un progetto CNCF che usa eBPF per il networking e la sicurezza in Kubernetes. Hubble, il componente di observability di Cilium, fornisce visibilità completa sul traffico di rete tra pod, incluse metriche L3/L4/L7, policy di rete e service map automatiche.
# Installare Cilium con Hubble abilitato
# helm install cilium cilium/cilium --version 1.15.0
# Configurazione Cilium con Hubble
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# Abilitare Hubble per observability
enable-hubble: "true"
hubble-listen-address: ":4244"
hubble-metrics-server: ":9965"
# Metriche L7 per HTTP
hubble-metrics: >-
dns
drop
tcp
flow
icmp
http
httpV2:sourceContext=workload-name|reserved-identity;destinationContext=workload-name|reserved-identity
# Esportazione verso OpenTelemetry
hubble-export-file-max-size-mb: "10"
hubble-export-file-max-backups: "5"
# Abilitare il relay per la UI
hubble-relay-enabled: "true"
hubble-ui-enabled: "true"
# Comandi Hubble per network observability
# Osservare il traffico in tempo reale
hubble observe --namespace ecommerce
# Filtrare per protocollo HTTP
hubble observe --namespace ecommerce --protocol http
# Visualizzare solo gli errori (4xx, 5xx)
hubble observe --namespace ecommerce --http-status 400-599
# Traffico tra servizi specifici
hubble observe --from-pod ecommerce/order-service \
--to-pod ecommerce/payment-service
# Metriche per Prometheus
# Le metriche Hubble sono esposte su :9965/metrics
# e possono essere scrappate da Prometheus
eBPF vs Auto-Instrumentation: Confronto
eBPF e auto-instrumentation sono approcci complementari, non alternativi. Ciascuno ha punti di forza e limiti specifici che li rendono adatti a scenari diversi.
Confronto Dettagliato
| Aspetto | eBPF | Auto-Instrumentation OTel |
|---|---|---|
| Modifica codice | Nessuna | Nessuna (agent/flag JVM) |
| Overhead | Molto basso (kernel-level) | Basso-medio (user-space) |
| Copertura protocolli | HTTP, gRPC, DNS, SQL, Redis | 100+ librerie per linguaggio |
| Attributi custom | Limitati (solo dati di rete) | Completi (span, attributi, eventi) |
| Contesto di business | Non disponibile | Disponibile con SDK manuale |
| Supporto OS | Solo Linux (kernel 4.14+) | Cross-platform |
| Linguaggio applicativo | Agnostico (qualsiasi linguaggio) | Specifico per linguaggio |
Quando Usare eBPF per l'Observability
- Visibilità di rete: monitorare traffico L3/L4/L7 tra tutti i pod di un cluster Kubernetes
- Servizi legacy: ottenere tracce da applicazioni che non possono essere instrumentate (binari, C/C++)
- Security monitoring: rilevare connessioni anomale, DNS tunneling, lateral movement
- Performance profiling: CPU flame graph, I/O profiling senza overhead significativo
- Complemento a OTel: usare eBPF per la rete e OTel per il contesto applicativo
Limiti Attuali di eBPF
Nonostante il potenziale rivoluzionario, eBPF ha limiti importanti che ne condizionano l'adozione:
- Solo Linux: eBPF e una tecnologia del kernel Linux, non disponibile su Windows o macOS (in produzione)
- Versione kernel: richiede kernel 4.14+ (5.8+ per le feature avanzate), limitando i sistemi legacy
- Traffico TLS: eBPF vede i dati dopo la decryption solo con uprobe su librerie SSL, con complessità aggiuntiva
- Nessun contesto di business: eBPF vede pacchetti e syscall, non order ID o customer tier
- Complessità di sviluppo: scrivere programmi eBPF personalizzati richiede conoscenze del kernel
Conclusioni e Prossimi Passi
eBPF rappresenta il futuro dell'observability a basso overhead. La capacità di ottenere tracce distribuite, metriche di rete e profiling senza modificare il codice applicativo e rivoluzionaria, specialmente per cluster Kubernetes con centinaia di servizi.
L'approccio ottimale combina eBPF (per la visibilità di rete e infrastruttura) con OpenTelemetry (per il contesto applicativo e di business). Strumenti come Pixie e Cilium/Hubble rendono eBPF accessibile anche a team senza esperienza kernel.
Nel prossimo articolo esploreremo le strategie di sampling, analizzando come ridurre il volume di telemetria e i costi associati senza perdere visibilità sugli eventi critici.







