eBPF es una tecnología de programación basada en eventos que permite a los desarrolladores escribir programas eficientes, seguros y no intrusivos que se ejecutan directamente en el espacio del kernel del sistema operativo (SO) Linux, “extendiendo” efectivamente el kernel del SO.
El kernel de un sistema operativo es una entidad extremadamente, e intencionalmente, estable. Es compatible con todo el sistema operativo, por lo que, por su diseño, puede resultar complicado y laborioso modificarlo o alterarlo. eBPF aborda este desafío de extensibilidad al permitir que los desarrolladores ejecuten programas aislados en contextos privilegiados, como un kernel de SO.
La pila del sistema operativo se puede dividir en tres capas lógicas: la capa del hardware, la capa del kernel y la capa del usuario. La capa del kernel es el núcleo de un sistema operativo. Se encuentra entre la capa física, que alberga todo el hardware físico, la memoria y los componentes de almacenamiento de un SO, y la capa del usuario, que alberga los navegadores web y las aplicaciones de un SO.
Las aplicaciones y los navegadores del espacio del usuario deben comunicarse con los componentes de la capa física para completar sus respectivas tareas, pero cada componente de la capa física tiene protocolos de comunicación y requisitos de compatibilidad específicos. Aquí es donde la capa del kernel (o espacio del kernel) entra en escena. Interpreta las llamadas al sistema y permite que las aplicaciones se comuniquen de manera efectiva con los componentes físicos de la red.
Las herramientas eBPF ayudan a los desarrolladores a ampliar más fácilmente las características del software existente en tiempo de ejecución sin modificar el código fuente del kernel, cargar módulos del kernel (piezas de código cargables que pueden ampliar las funciones del kernel) o interrumpir el espacio del kernel.
Las tecnologías eBPF representan una evolución del Berkeley Packet Filter (BPF) original, que proporcionó una forma sencilla de seleccionar y analizar paquetes de red en un programa de espacio de usuario. Pero más allá del filtrado de paquetes, los programas BPF carecían de la flexibilidad necesaria para manejar tareas más complejas dentro del kernel.
Al reconocer la necesidad de una tecnología más versátil, la comunidad Linux desarrolló eBPF, que se basó en las características de backend de BPF, pero amplió su programabilidad en el kernel. Las características avanzadas de los programas eBPF, y su enfoque de sandbox, permiten a los desarrolladores implementar procesos mejorados de filtrado de paquetes, mejorar la observabilidad del espacio del kernel y las capacidades de monitoreo, realizar análisis de rendimiento de alta gama y aplicar políticas de seguridad a nivel de kernel en entornos centros de datos on-premises y nativos de la nube.
Los componentes principales de un programa eBPF son:
Los programas eBPF se escriben inicialmente en un subconjunto C restringido y luego se compilan en bytecode eBPF mediante herramientas como LLVM, que sirve como arquitectura de backend de eBPF para lenguajes de programación frontend (Clang, por ejemplo) El bytecode es esencialmente un conjunto restringido de instrucciones que se adhieren a la arquitectura del conjunto de instrucciones de eBPF y evitan errores de tiempo de ejecución.
La tecnología del kernel de Linux puede convertir el código de bytes eBPF en acciones ejecutables, pero los compiladores justo a tiempo (JIT) ofrecen un rendimiento superior. Los compiladores JIT pueden convertir bytecode en código de máquina nativo para plataformas de hardware específicas según sea necesario.
Los cargadores de espacio de usuario son programas en el espacio de usuario que cargan el bytecode de eBPF en el kernel, lo adjuntan a los hooks adecuados y gestionan cualquier mapa de eBPF asociado. Algunos ejemplos de cargadores de espacio del usuario incluyen herramientas como BPF Compiler Collection (BCC) y bpftrace.
Los mapas de eBPF son estructuras de datos con pares clave-valor y acceso de lectura y escritura que proporcionan espacio de almacenamiento compartido y facilitan la interacción entre los programas del kernel de eBPF y las aplicaciones de espacio del usuario. Creados y gestionados a través de llamadas al sistema, los mapas de eBPF también se pueden utilizar para mantener el estado entre diferentes iteraciones de los programas eBPF.
El verificador, un componente crítico de los sistemas eBPF, verifica el bytecode antes de cargarlo en el kernel para asegurarse de que el programa no contenga ninguna operación dañina, como bucles infinitos, instrucciones ilegales o acceso a memoria fuera de los límites. También ayuda a garantizar que todas las rutas de datos del programa finalicen correctamente.
Los hooks son puntos en el código del kernel donde se pueden adjuntar programas eBPF. Cuando el kernel llega a un hook, ejecuta el programa eBPF adjunto.
Los diferentes tipos de hooks, como puntos de seguimiento, kprobes, uprobes y colas de recepción de paquetes de red, brindan a los programas eBPF un amplio acceso a los datos y les permiten completar diversas operaciones. Los puntos de seguimiento, por ejemplo, permiten que los programas inspeccionen y recopilen datos sobre el kernel u otros procesos, mientras que los hooks de control de tráfico se pueden utilizar para inspeccionar y modificar paquetes de red. Y los kprobes y uprobes facilitan el trazado dinámico a nivel de kernel y de usuario.
Los XDP son rutas de datos de alto rendimiento que aceleran el procesamiento de paquetes a nivel de controlador y facilitan la transferencia a través de las capas de comunicación. Permiten que los sistemas eBPF tomen decisiones de enrutamiento de datos antes de que los paquetes de datos lleguen al kernel.
La integración de los XDP con el kernel de Linux (a mediados de la década de 2010) finalmente permitió a los desarrolladores desplegar funciones de equilibrio de carga basadas en eBPF, capaces de gestionar el tráfico de datos incluso en los centros de datos más concurridos.
Debido a que los eBPF no pueden generar funciones arbitrarias y deben mantener la compatibilidad con todas las versiones posibles del kernel, a veces los conjuntos de instrucciones básicas de eBPF no tienen los matices suficientes para ejecutar operaciones avanzadas. Las funciones auxiliares cierran esta brecha.
Las funciones auxiliares (conjuntos de funciones del kernel predefinidas y basadas en API a las que los eBPF pueden llamar desde dentro del sistema) proporcionan una forma para que los programas eBPF completen operaciones más complejas (como obtener la hora y fecha actuales o generar números aleatorios) que no son apoyados directamente por el conjunto de instrucciones.
Generalmente, los eBPF operan como máquinas virtuales (VM) dentro del kernel de Linux, trabajando en una arquitectura de conjunto de instrucciones de bajo nivel y ejecutando bytecode de eBPF. Sin embargo, el complejo proceso de ejecutar un programa eBPF tiende a seguir ciertos pasos importantes.
Primero, los desarrolladores escriben el programa eBPF y compilan el bytecode. El propósito del programa establecerá el tipo de código apropiado. Por ejemplo, si un equipo quiere monitorear el uso de la CPU, escribirá código que incluya funciones para capturar métricas de uso.
Después de que el compilador de eBPF convierte el código C de alto nivel en bytecode de nivel inferior, un cargador de espacio de usuario generará una llamada del sistema BPF para cargar el programa en el kernel. El cargador también es responsable de abordar los errores y configurar los mapas de eBPF que el programa necesita.
Con el código de bytes y los mapas del programa implementados, el eBPF ejecutará un proceso de verificación para confirmar que el programa es seguro para ejecutarse en el kernel. Si se considera inseguro, la llamada al sistema para cargar el programa fallará y el programa del cargador recibirá un mensaje de error. Si el programa pasa la verificación, podrá ejecutarse.
Usando un intérprete o un compilador JIT, el eBPF convertirá el bytecode en código de máquina procesable. Sin embargo, el eBPF es una tecnología basada en eventos, por lo que se ejecuta en respuesta a puntos de enlace o eventos específicos dentro del kernel (llamadas al sistema, eventos de red, iniciación de procesos, inactividad de la CPU, por ejemplo). Cuando ocurre un evento, el eBPF ejecuta el programa de bytecode correspondiente, lo que permite a los desarrolladores inspeccionar y manipular varios componentes del sistema.
Cuando el programa eBPF está en ejecución, los desarrolladores pueden interactuar con él desde el espacio de usuario utilizando mapas de eBPF. Por ejemplo, la aplicación puede comprobar periódicamente un mapa para recopilar datos del programa eBPF, o puede actualizar un mapa para cambiar el comportamiento del programa.
Descargar el programa es el último paso de la mayoría de los procesos de ejecución de eBPF. Cuando el eBPF ha hecho su trabajo, el cargador puede volver a utilizar la llamada al sistema de BPF para descargarlo del kernel, momento en el que el eBPF deja de ejecutarse y libera sus recursos asociados. El proceso de descarga también puede incluir la iteración sobre cualquier mapa de eBPF que el equipo ya no necesite para liberar elementos individuales útiles, y luego eliminar el propio mapa (utilizando la llamada al sistema ‘delete’).
Berkeley Packet Filter (BPF) se desarrolló originalmente como un mecanismo para el filtrado de paquetes en sistemas basados en Unix, lo que permite que el código a nivel de usuario defina filtros que puedan capturar y procesar eficientemente paquetes de red dentro del kernel. Por lo tanto, este enfoque minimizó la potencia de procesamiento necesaria para transferir datos innecesarios al espacio del usuario, y podría agilizar y optimizar las redes informáticas.
BPF utiliza un agente de kernel para procesar paquetes en el punto de entrada de la pila de red. Después de desarrollar un programa BPF, un agente de kernel BPF lo carga en el espacio del kernel, que verifica su precisión antes de adjuntarlo al socket correspondiente. En consecuencia, en el espacio del usuario, solo los paquetes que coinciden con el filtro del programa BPF pueden recibir datos de un socket determinado. Esta característica de protección limita el acceso de un programa a las áreas de memoria permitidas y evita posibles bloqueos del kernel.
eBPF surgió por primera vez en 2014, momento en el que representó una evolución significativa del concepto original de BPF. Además de los casos de uso de redes originales, las aplicaciones eBPF se ampliaron para incluir llamadas al sistema y otras funciones, razón por la cual los desarrolladores a menudo se referían a esto como "Berkeley Packet Filter completamente extendido".
Una de las áreas clave en las que eBPF sobresale es la supervisión del rendimiento de la red. Permite a los equipos de TI realizar análisis y resolución de problemas en tiempo real al proporcionar insights granulares sobre el comportamiento de la red, las métricas de rendimiento y los cuellos de botella. eBPF desempeña un papel clave en la seguridad de la red, monitoreando y filtrando las llamadas al sistema y las actividades de la red, aplicando las políticas de seguridad de la red y detectando anomalías en el sistema.
eBPF también ofrece a los desarrolladores una valiosa herramienta para rastrear y perfilar aplicaciones tanto del kernel como del espacio del usuario y ejecutar acciones personalizadas y transformación de datos a medida que los datos atraviesan el kernel, mejorando aún más su versatilidad y utilidad. Debido a estas capacidades expansivas (que van mucho más allá del filtrado de paquetes), eBPF ahora se reconoce como un término independiente, en lugar de un acrónimo de Berkeley Packet Filter extendido.
Los avances en la tecnología eBPF han obligado a los desarrolladores de software a expandir sus aplicaciones a todos los sistemas operativos, de modo que las plataformas que no están basadas en Linux puedan beneficiarse de las sofisticadas capacidades de rastreo, redes y monitoreo de eBPF.1
De hecho, eBPF Foundation— (una extensión de Linux Foundation, cuyos miembros incluyen a Google, Meta, Netflix, Microsoft, Intel e Isovalent, entre otros) ha invertido mucho en la expansión de la compatibilidad del sistema operativo para los programas eBPF, con la esperanza de ampliar eventualmente la utilidad de la programación eBPF.2
Aunque BPF sentó las bases para un filtrado de paquetes eficiente, es innegable que eBPF ha ampliado su alcance. Los eBPF modernos proporcionan una herramienta integral para optimizar la observabilidad, el rendimiento y la seguridad en los sistemas Linux. Su capacidad para ejecutar programas dinámicos definidos por el usuario dentro del kernel crea nuevas posibilidades para la supervisión y gestión del sistema, lo que convierte a eBPF en una herramienta indispensable tanto para desarrolladores de software como para programadores informáticos.
Las tecnologías eBPF ya se han convertido en una piedra angular de los sistemas Linux modernos, lo que permite un control detallado sobre el kernel de Linux y que las empresas creen programas más innovadores dentro del ecosistema Linux.
eBPF ha facilitado avances en:
eBPF permite a los desarrolladores instalar características de procesamiento de paquetes más rápidas y personalizadas, procesos de equilibrio de carga, scripts de perfilado de aplicaciones y prácticas de monitoreo de redes. Las plataformas de código abierto, como Cilium, despliegan eBPF para proporcionar redes seguras, escalables y observables para clústeres de Kubernetes y cargas de trabajo, y otros microservicios en contenedores.
eBPF también ayuda a los equipos de TI a imponer reglas simples y complejas al principio de la ruta del evento para un enrutamiento de tráfico, filtrado de contenido y prevención de pérdidas más efectivos. Mediante el uso de la lógica de reenvío de paquetes a nivel del núcleo, los eBPF pueden minimizar la latencia, optimizar los procesos de enrutamiento y permitir una respuesta general más rápida de la red.
A medida que las aplicaciones se descomponen en microservicios, la observabilidad en el espacio de usuario puede volverse un reto. Los eBPF brindan a las herramientas de monitoreo un punto de vista del espacio del kernel para que la observabilidad permanezca intacta de extremo a extremo.
Los eBPFs permiten a los desarrolladores instrumentar el kernel y las aplicaciones de espacio del usuario para recopilar datos y métricas de rendimiento detallados sin afectar significativamente el rendimiento del sistema. Estas capacidades ayudan a las organizaciones a mantenerse a la vanguardia, ya que permiten el monitoreo y observabilidad en tiempo real de cada componente de la red (y sus dependencias).
Los eBPF pueden monitorear las llamadas al sistema, el tráfico de red y el comportamiento del sistema tanto a nivel de kernel como de socket para detectar y responder a posibles amenazas de seguridad en tiempo real. Falco (una herramienta de seguridad de tiempo de ejecución nativa de la nube), por ejemplo, emplea eBPF para implementar auditorías de seguridad en tiempo de ejecución y respuesta a incidentes, mejorando así la seguridad general del sistema.
Muchas herramientas eBPF pueden rastrear llamadas al sistema, supervisar el uso de la CPU y realizar un seguimiento del uso de recursos (E/S de disco, por ejemplo). Estas características pueden ayudar a los desarrolladores a detectar más fácilmente los cuellos de botella en el rendimiento del sistema, implementar protocolos de depuración e identificar oportunidades de optimización.
Los eBPF pueden instalar y aplicar políticas de seguridad a nivel de kernel (filtros de tráfico de red, cortafuegos y restricciones de comportamiento, por ejemplo) y controles de seguridad para evitar que los actores maliciosos y los usuarios no autorizados accedan a la red.
En una arquitectura de microservicios, la visibilidad de las cargas de trabajo de producción dentro del contenedor es vital. Sin embargo, las herramientas de observabilidad tradicionales pueden tener dificultades para mantenerse al día con los microservicios en contenedores.
Los contenedores son efímeros por diseño; se crean cuando se necesitan y se destruyen tan pronto como han cumplido su propósito. Cada contenedor actúa como un host individual y, en un entorno de producción, el gran volumen de métricas que crean puede abrumar fácilmente a las herramientas estándar de monitoreo de aplicaciones, redes e infraestructuras. Las máquinas virtuales pueden comportarse de forma similar, pero la naturaleza de ciclo rápido de los contenedores puede complicar la captura de telemetría.
Además, los contenedores a menudo se despliegan en grandes cantidades en entornos de nube, lo que hace que la visibilidad sea aún más difícil.
eBPF, que se ejecuta a nivel de kernel de un host o contenedor, permite a los desarrolladores recopilar telemetría de entidades de datos de corta duración. Ayuda a integrar la visibilidad de la red, las aplicaciones y la infraestructura en un servicio unificado basado en eBPF. Con eBPF, los desarrolladores pueden capturar datos sobre procesos, uso de memoria, actividad de red y acceso a archivos a nivel de contenedor, incluso si los contenedores no están desplegados en la nube.
Del mismo modo, en entornos contenedorizados basados en Kubernetes, eBPF utiliza una única interfaz y conjunto de herramientas para recopilar datos de clústeres dispares, de modo que los equipos de TI no tengan que desplegar agentes de espacio de usuario individuales para completar las tareas de recopilación de datos en toda la red. Las herramientas eBPF pueden ejecutarse en nodos del plano de control (para el monitoreo del servidor API, por ejemplo) y monitorear los nodos de trabajo para generar insights, correlacionando puntos de datos e insights de ambos tipos de nodos para una observabilidad del clúster ajustada.
Red Hat OpenShift on IBM Cloud es una plataforma de contenedores OpenShift (OCP) totalmente gestionada.
Virtualización de almacenamiento segura, confiable y eficiente para entornos VMware con IBM Spectrum Virtualize.
Encuentre una solución de infraestructura en la nube que sea adecuada para las necesidades de su negocio y escale los recursos bajo demanda.
1 Foundation Proposes Advancing eBPF Adoption Across Multiple OSes, DevOps.com, 21 de agosto de 2021.
2 Latest eBPF Advances Are Harbingers of Major Changes to IT, DevOps.com, 13 de septiembre de 2023.