eBPF face aux approches traditionnelles : analyse comparative des performances

Ce document compare les performances d'eBPF par rapport aux méthodes traditionnelles de surveillance système, en s'appuyant sur des données empiriques pour démontrer les différences.

En général, eBPF offre des gains de performance significatifs dans la majorité des cas d'utilisation, bien qu'il ne soit pas universellement adapté à toutes les situations.

En juin 2024, une évaluation a été menée pour déterminer la viabilité d'eBPF en environnement de production. Les scénarios de test suivants ont été examinés :

  • Suivi des appels système
  • Surveillance des paquets réseau
  • Surveillance des accès aux fichiers
  • Suivi du cycle de vie des processus

Les approches comparées étaient :

  • eBPF
  • strace
  • auditd
  • inotify
  • tcpdump

Configuraton du laboratoire de test

Matériel

  • CPU : Intel Xeon E5-2680 v4 (28 cœurs)
  • Mémoire vive : 64 Go
  • Carte réseau : 10 Gbps

Logiciel

  • Système d'exploitation : Ubuntu 22.04
  • Noyau : 5.15.0-60-generic
  • Compilateur Clang : 12.0.0
  • Bibliothèque libbpf : 0.8.0

Méthodologie de test

Métriques de performance

  • Utilisation du processeur
  • Consommation de mémoire
  • Latence
  • Débit
  • Précision

Outils d'analyse

  • perf : pour l'analyse CPU et mémoire
  • ab : pour les tests de charge
  • wrk : pour les tests de charge réseau
  • time : pour mesurer la latence

Trajet technique : Analyse par scénario

Scénario 1 : Suivi des appels système

Solution eBPF
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

struct syscall_event_data {
    __u32 process_id;
    char process_name[16];
    __u64 syscall_number;
    __u64 event_timestamp;
};

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 24);
} syscall_events SEC(".maps");

SEC("tracepoint/raw_syscalls/sys_enter")
int trace_syscall_entry(struct trace_event_raw_sys_enter *ctx)
{
    struct syscall_event_data *event_data;

    event_data = bpf_ringbuf_reserve(&syscall_events, sizeof(*event_data), 0);
    if (!event_data) {
        return 0;
    }

    event_data->process_id = bpf_get_current_pid_tgid() >> 32;
    bpf_get_current_comm(event_data->process_name, sizeof(event_data->process_name));
    event_data->syscall_number = ctx->id;
    event_data->event_timestamp = bpf_ktime_get_ns();

    bpf_ringbuf_submit(event_data, 0);
    return 0;
}

char _license[] SEC("license") = "GPL";

Solution strace
strace -c -f -p $(pidof nginx)

Solution auditd
auditctl -a exit,always -F arch=b64 -S all

Résultats du test

Indicateur eBPF strace auditd
Utilisation CPU 2% 25% 8%
Consommation mémoire 50 Mo 200 Mo 100 Mo
Latence 5 µs 100 µs 50 µs
Débit 200 K/s 20 K/s 80 K/s
Précision 100% 100% 100%

Conclusion du scénario 1

eBPF se révèle la solution la plus performante pour le suivi des appels système :

  • L'utilisatino CPU est 12 fois inférieure à celle de strace.
  • La consommation mémoire est 4 fois moindre que celle de strace.
  • La latence est 20 fois plus faible qu'avec strace.
  • Le débit est 10 fois supérieur à celui de strace.

Scénario 2 : Surveillance des paquets réseau

Solution eBPF (XDP)
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>

struct network_packet_info {
    __u32 source_ip;
    __u32 destination_ip;
    __u16 source_port;
    __u16 destination_port;
    __u64 capture_timestamp;
};

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF)

Étiquettes: eBPF performance surveillance système analyse comparative strace

Publié le 3 juin à 22h41