Volver al inicio

eBPF NetFlow monitoreo de tráfico bare metal K8s

El artículo describe la implementación de un sistema de recolección de estadísticas de NetFlow usando eBPF/XDP para bare metal, virtualización y Kubernetes. Cubre selección de mapas BPF (PERCPU_HASH), sharding, muestreo con temporizadores. Se proporcionan benchmarks y código.

eBPF + NetFlow: telemetría desde servidores a Kubernetes
Advertisement 728x90

eBPF y NetFlow para monitoreo de tráfico: Desde servidores bare metal hasta Kubernetes

Un sistema basado en eBPF/XDP y NetFlow ofrece telemetría de red detallada en todas las capas, desde servidores físicos hasta clústeres de Kubernetes. Superó las limitaciones de sFlow/NetFlow tradicionales, como el alto costo de hardware, la muestreo y la falta de campos personalizados. El tráfico se procesa a través de una interfaz unificada router-on-a-stick, permitiendo que XDP capture paquetes entrantes sin modificar el kernel.

eBPF ejecuta programas directamente en el núcleo del sistema operativo con seguridad y latencia mínima, ideal para monitoreo en tiempo real. Se recopilan estadísticas por 5-tupla (direcciones IP, puertos, protocolo), bytes y paquetes, exportándose luego en formato NetFlow para recolectores.

Elección de mapas BPF para alto rendimiento

Los mapas BPF almacenan estadísticas como tablas clave-valor: la clave es la 5-tupla, el valor son contadores. Las pruebas revelaron problemas con BPF_MAP_TYPE_HASH:

Google AdInline article slot
  • Contención de bloqueos bajo acceso multi-hilo desde múltiples núcleos.
  • Condición de carrera que provocaba contadores inexactos.

Las operaciones atómicas (__sync_fetch_and_add) eliminan errores, pero reducen el rendimiento por la sobrecarga de sincronización.

Cambiar a BPF_MAP_TYPE_PERCPU_HASH crea un mapa separado por cada núcleo de CPU, eliminando bloqueos. La agregación ocurre en espacio de usuario. Las pruebas en 100 núcleos bajo cargas variables confirmaron que los mapas PERCPU superan a otros.

Cuando están llenos (600K 5-tuplas en un mapa de 60K entradas), BPF_MAP_TYPE_LRU_PERCPU_HASH elimina entradas antiguas, pero con un costo. El tipo PERCPU_HASH sigue siendo preferido para lecturas rápidas y puntuales.

Google AdInline article slot
// Determinar qué mapa escribir
#define SHARD_COUNT 25 // número de fragmentos
map_hash_idx = ctx->rx_queue_index % SHARD_COUNT + shard_offset;

Fragmentación de mapas y exportación multi-hilo

Un solo mapa con 10M registros se convertía en cuello de botella para un exportador mono-hilo. Fragmentarlo en 25 mapas (basado en rx_queue_index mediante RSS) permitió lectura paralela, acelerando el procesamiento 3 veces.

Ventajas de la fragmentación:

  • Escalabilidad: añadir mapas sin reiniciar.
  • Paralelismo: sensores leen múltiples mapas simultáneamente.
  • Eficiencia de caché: mapas pequeños caben en L1/L2.

El sensor escrito en Go (con bibliotecas Cilium) aprovecha BPF_MAP_LOOKUP_AND_DELETE_BATCH para leer y vaciar mapas cada minuto, minimizando pérdidas durante desbordamientos.

Google AdInline article slot

Muestreo y adaptación dinámica de carga

Para equilibrar el rendimiento de reenvío con las necesidades de telemetría, se implementa muestreo. Un segundo stats_map (BPF_MAP_TYPE_HASH, max_entries=128) rastrea paquetes por fragmento:

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 128);  // Número máximo de fragmentos
    __type(key, __u32);        // ID del fragmento
    __type(value, __u64);      // Contadores de paquetes/bytes
    __uint(pinning, LIBBPF_PIN_BY_NAME);
} stats_map SEC(".maps");

Los temporizadores de eBPF calculan periódicamente el throughput (paquetes/segundo) y activan el muestreo cuando se superan umbrales por fragmento. Los temporizadores ejecutan tareas en segundo plano fuera del contexto de paquetes: agregan datos y reinician contadores.

Esto mantiene la estabilidad durante picos de tráfico (como DDoS) preservando la telemetría a nivel de sesión.

Adaptación a virtualización y Kubernetes

La arquitectura bare metal se escala sin problemas a entornos virtualizados y Kubernetes. En clústeres K8s, eBPF/XDP se ejecuta como DaemonSet, capturando tráfico de pods mediante CNI. La fragmentación se adapta a la afinidad de nodos; PERCPU_HASH se alinea con vCPUs.

La exportación de NetFlow agrega metadatos (namespace, IP del pod), mejorando la observabilidad de microservicios.

Conclusiones clave:

  • PERCPU_HASH elimina la contención de bloqueos, aumentando el rendimiento 2–3x frente a HASH.
  • La fragmentación acelera la exportación 3x gracias al paralelismo.
  • Temporizadores eBPF + muestreo equilibran la carga sin sacrificar el reenvío.
  • La variante LRU conviene en escenarios dinámicos con desbordamientos.
  • El sensor en Go con bibliotecas Cilium destaca en análisis de alto rendimiento.

— Editorial Team

Advertisement 728x90

Leer después