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 núcleo del sistema operativo Linux, "ampliando" de manera efectiva dicho núcleo.
El núcleo de un sistema operativo es una entidad extremadamente estable y así se ha diseñado intencionadamente. Proporciona soporte a todo el sistema operativo, por lo que, debido a su diseño, puede resultar complicado y laborioso modificarlo o alterarlo. Las eBPF abordan el reto de la extensibilidad permitiendo a los desarrolladores ejecutar programas en entornos aislados con privilegios de kernel.
La pila del sistema operativo se puede dividir en tres capas lógicas: la capa de hardware, la capa del núcleo y la capa de usuario. La capa del núcleo es el núcleo del sistema operativo. Se sitúa entre la capa física, que alberga todo el hardware, la memoria y los componentes de almacenamiento del sistema operativo, y la capa de usuario, que alberga los navegadores web y las aplicaciones.
Las aplicaciones y los navegadores del espacio de usuario se comunican con los componentes de la capa física para completar sus respectivas tareas, pero cada componente de esta capa tiene protocolos de comunicación y requisitos de compatibilidad específicos. Es aquí donde entra en juego la capa del núcleo (o espacio del núcleo). Interpreta las llamadas al sistema y permite que las aplicaciones se comuniquen de manera eficaz con los componentes físicos de la red.
Las herramientas eBPF permiten a los desarrolladores ampliar las características del software existente en tiempo de ejecución sin necesidad de modificar el código fuente del núcleo, cargar módulos del núcleo (fragmentos de código ejecutables que pueden ampliar las funciones del núcleo) ni alterar el espacio del núcleo de ninguna otra manera.
Las tecnologías eBPF suponen una evolución del filtro de paquetes Berkeley (BPF) original, que permitía seleccionar y analizar paquetes de red de forma sencilla desde un programa del espacio de usuario. Sin embargo, los programas BPF carecían de la flexibilidad necesaria para manejar tareas más complejas dentro del núcleo, por lo que se hizo necesario dar un paso más.
Al reconocer la necesidad de una tecnología más versátil, la comunidad Linux desarrolló eBPF, que se basaba en las características de backend de BPF pero ampliaba su programabilidad en el núcleo. Las características avanzadas de los programas eBPF y su enfoque de entorno aislado permiten a los desarrolladores implementar procesos mejorados de filtrado de paquetes, mejorar la observabilidad y las capacidades de monitorización del espacio del núcleo, realizar análisis de rendimiento de alta gama y aplicar políticas de seguridad a nivel del núcleo, tanto en centros de datos locales como en entornos nativos de la nube.
Los componentes principales de un programa eBPF son:
Los programas eBPF se escriben inicialmente en un subconjunto restringido de C y luego se compilan en código byte eBPF con herramientas como LLVM, que sirve como arquitectura back-end de eBPF para lenguajes de programación front-end (Clang, por ejemplo). El código de bytes es, esencialmente, un conjunto restringido de instrucciones que se ajustan a la arquitectura del conjunto de instrucciones eBPF y evitan errores en tiempo de ejecución.
La tecnología del kernel de Linux puede convertir el código byte eBPF en acciones ejecutables, pero los compiladores just in time (JIT) ofrecen un rendimiento superior. Estos compiladores pueden convertir el código de bytes en código máquina nativo para plataformas de hardware específicas según sea necesario.
Los cargadores del espacio de usuario son programas de este mismo espacio que cargan el código byte eBPF en el núcleo, adjuntándolo a los ganchos adecuados y gestionando cualquier mapa eBPF asociado. Entre los ejemplos de cargadores del espacio de usuario se incluyen herramientas como BPF Compiler Collection (BCC) y bpftrace.
Los mapas eBPF son estructuras de datos con pares clave-valor que proporcionan acceso de lectura/escritura y espacio de almacenamiento compartido, y facilitan la interacción entre los programas eBPF y las aplicaciones del espacio de usuario. Creados y gestionados mediante llamadas al sistema, los mapas 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, comprueba el código de bytes antes de que se cargue en el núcleo para asegurarse de que el programa no contiene ninguna operación perjudicial, como bucles infinitos, instrucciones ilegales o accesos a memoria fuera de límites. También ayuda a garantizar que todas las rutas de datos del programa se cierren correctamente.
Los ganchos son puntos del código del núcleo donde se pueden adjuntar programas eBPF. Cuando el núcleo llega a un gancho, ejecuta el programa eBPF adjunto.
Los diferentes tipos de ganchos, como los puntos de rastreo, las sondas kprobes, las sondas uprobes y las colas de recepción de paquetes de red, proporcionan a los programas eBPF un amplio acceso a datos y les permiten realizar diversas operaciones. Los puntos de rastreo permiten inspeccionar y recopilar datos sobre el núcleo u otros procesos, mientras que los ganchos de control de tráfico se pueden utilizar para inspeccionar y modificar paquetes de red. Por su parte, las sondas kprobes y uprobes facilitan el seguimiento dinámico a nivel del núcleo y del usuario.
Los XDP son rutas de datos de alto rendimiento que aceleran el procesamiento de paquetes a nivel del controlador y facilitan la transferencia entre capas de comunicación. Permiten que los sistemas eBPF tomen decisiones sobre el enrutamiento de datos antes incluso de que los paquetes de datos lleguen al núcleo.
La integración de los XDP con el núcleo de Linux a mediados de la década de 2010 permitió finalmente a los desarrolladores implementar 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.
Dado que las 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 son lo suficientemente precisos como para ejecutar operaciones avanzadas. Las funciones auxiliares cubren esta carencia.
Las funciones auxiliares son conjuntos de funciones del núcleo predefinidas y basadas en API que las eBPF pueden invocar desde dentro del sistema y que proporcionan a los programas eBPF una forma de realizar operaciones más complejas (como obtener la hora y la fecha actuales o generar números aleatorios), que no están directamente compatibles con el conjunto de instrucciones.
Por lo general, las eBPF funcionan como máquinas virtuales (VM) dentro del núcleo de Linux, trabajando en una arquitectura de conjunto de instrucciones de bajo nivel y ejecutando código byte eBPF. Sin embargo, la ejecución de un programa eBPF es un proceso complejo que sigue ciertos pasos principales.
Los desarrolladores escriben primero el programa eBPF y compilan el bytecode. El propósito del programa dictará el tipo de código apropiado. Por ejemplo, si un equipo desea monitorizar el uso de la CPU, escribirá código que incluya funciones para capturar métricas de uso.
Tras la conversión del código C de alto nivel en código de máquina de bajo nivel realizada por el compilador eBPF, un cargador de usuario generará una llamada al sistema BPF para cargar el programa en el núcleo. El cargador también es responsable de abordar los errores y configurar los mapas eBPF que el programa necesita.
Una vez que el código de bytes del programa y los mapas están en su sitio, la eBPF ejecuta un proceso de verificación para confirmar que el programa es seguro para ejecutarse en el núcleo. Si no es así, la llamada al sistema para cargar el programa fallará y el programa cargador recibirá un mensaje de error. Si el programa supera la verificación, se le permite ejecutarse.
Ya sea mediante un intérprete o un compilador JIT, la eBPF convierte el código de bytes en código máquina ejecutable. Sin embargo, la eBPF es una tecnología basada en eventos, por lo que se ejecuta en respuesta a puntos de enganche o eventos específicos dentro del núcleo, como llamadas al sistema, eventos de red, inicio de procesos o inactividad de la CPU. Cuando se produce un evento, la eBPF ejecuta el programa de código de bytes correspondiente, lo que permite a los desarrolladores inspeccionar y manipular diversos componentes del sistema.
Cuando el programa eBPF está en ejecución, los desarrolladores pueden interactuar con él desde el espacio de usuario utilizando mapas eBPF. Por ejemplo, la aplicación puede comprobar periódicamente un mapa para capturar datos del programa eBPF o actualizar un mapa para cambiar el comportamiento del programa.
La descarga del programa es el paso final de la mayoría de los procesos de ejecución de eBPF. Cuando la eBPF ha hecho su trabajo, el cargador puede volver a utilizar la llamada al sistema BPF para descargarlo del núcleo, momento en el que la eBPF deja de ejecutarse y libera sus recursos asociados. El proceso de descarga también puede incluir la iteración sobre cualquier mapa eBPF que el equipo ya no necesite, con el fin de liberar elementos individuales útiles y, a continuación, eliminar el propio mapa (utilizando la llamada al sistema "delete").
El filtro de paquetes de Berkeley (BPF) se desarrolló originalmente como un mecanismo para el filtrado de paquetes en sistemas basados en Unix, lo que permitía que el código a nivel de usuario definiera filtros que pudieran capturar y procesar paquetes de red de manera eficiente dentro del kernel. Por lo tanto, este enfoque redujo la potencia de procesamiento necesaria para transferir datos innecesarios al espacio de usuario y permitió optimizar y agilizar las redes informáticas.
La BPF utiliza un agente del núcleo para procesar paquetes en el punto de entrada de la pila de red. Una vez desarrollado, el programa BPF se carga en el espacio del núcleo mediante un agente del núcleo BPF, que verifica su precisión antes de adjuntarlo al socket correspondiente. Por tanto, en el espacio de 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 fallos del núcleo.
La eBPF apareció por primera vez en 2014, momento en que supuso una evolución significativa del concepto original del BPF. Además de los casos de uso originales en redes, las aplicaciones de la eBPF se ampliaron para incluir llamadas al sistema y otras funciones, de modo que los desarrolladores solían referirse a él como el "filtro de paquetes Berkeley totalmente ampliado".
Una de las áreas clave en las que la eBPF sobresale es la monitorización del rendimiento de la red. Permite a los equipos de TI analizar y resolver problemas en tiempo real, ya que ofrece conocimientos detallados sobre el comportamiento de la red, las métricas de rendimiento y los cuellos de botella. La eBPF desempeña un papel clave en la seguridad de la red, monitorizando 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.
La eBPF también ofrece a los desarrolladores una herramienta muy valiosa para rastrear y perfilar aplicaciones del núcleo y del espacio de usuario, así como para ejecutar acciones personalizadas y transformaciones de datos a medida que estos atraviesan el núcleo, lo que aumenta 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 no basadas en Linux puedan aprovechar las sofisticadas capacidades de rastreo, redes y monitorización de eBPF.1
De hecho, la Fundación eBPF, una extensión de la Fundación Linux 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 de eBPF, con la esperanza de ampliar eventualmente la utilidad de la programación de eBPF.2
Aunque la BPF sentó las bases para un filtrado de paquetes eficiente, es innegable que la eBPF ha ampliado su alcance. Las eBPF modernas proporcionan una herramienta completa 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 núcleo del sistema operativo abre nuevas posibilidades para la supervisión y gestión del mismo, por lo que eBPF se ha convertido en una herramienta imprescindible para desarrolladores de software y programadores informáticos.
Las tecnologías eBPF se han convertido ya en un elemento esencial de los sistemas Linux modernos, ya que permiten un control minucioso del núcleo Linux y capacitan a las empresas para crear programas más innovadores dentro de este ecosistema.
La eBPF ha facilitado avances en:
La eBPF permite a los desarrolladores instalar funciones de procesamiento de paquetes más rápidas y personalizadas, procesos de equilibrio de carga, scripts de perfilado de aplicaciones y prácticas de monitorización de redes. Plataformas de código abierto como Cilium implementan eBPF para proporcionar redes seguras, escalables y supervisables para clústeres y cargas de trabajo de Kubernetes, así como para otros microservicios en contenedores.
La eBPF también ayuda a los equipos de TI a establecer reglas sencillas y complejas en las primeras etapas del proceso de eventos para conseguir un enrutamiento del tráfico, un filtrado de contenidos y una prevención de pérdidas más eficaces. Al utilizar la lógica de reenvío de paquetes a nivel del núcleo, las eBPF pueden minimizar la latencia, optimizar los procesos de enrutamiento y conseguir una respuesta general más rápida de la red.
Dado que las aplicaciones se dividen en microservicios, garantizar la observabilidad en el espacio de usuario puede resultar complicado. Las eBPF ofrecen a las herramientas de monitorización una visión del espacio del núcleo, por lo que la observabilidad permanece intacta de extremo a extremo.
Las eBPF permiten a los desarrolladores instrumentar el núcleo y las aplicaciones de espacio de 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, y permiten la monitorización y la observabilidad en tiempo real de cada componente de la red (y sus dependencias).
Las eBPF pueden monitorizar las llamadas al sistema, el tráfico de red y el comportamiento del sistema, tanto a nivel de núcleo como de socket, para detectar y responder a posibles amenazas de seguridad en tiempo real. Por ejemplo, Falco (una herramienta de seguridad nativa en la nube) utiliza eBPF para implementar auditorías de seguridad y respuesta a incidentes en tiempo de ejecución, lo que mejora la seguridad general del sistema.
Muchas herramientas eBPF pueden rastrear llamadas al sistema, monitorizar el uso de la CPU y realizar un seguimiento del uso de recursos (por ejemplo, E/S de disco). Estas características pueden ayudar a los desarrolladores a detectar más fácilmente los cuellos de botella del rendimiento del sistema, implementar protocolos de depuración e identificar oportunidades de optimización.
Las eBPF pueden instalar y aplicar políticas de seguridad a nivel del núcleo (por ejemplo, filtros de tráfico de red, cortafuegos y restricciones de comportamiento), así como realizar comprobaciones de seguridad para impedir que los atacantes y los usuarios no autorizados accedan a la red.
En una arquitectura de microservicios, es fundamental poder ver las cargas de trabajo de producción dentro del contenedor. Sin embargo, las herramientas tradicionales de observabilidad pueden tener dificultades para hacer frente a los microservicios en contenedores.
Los contenedores tienen un diseño efímero; se crean cuando se necesitan y se destruyen tan pronto como cumplen 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 genera puede saturar fácilmente las herramientas estándar de monitorización de aplicaciones, redes e infraestructuras. Las máquinas virtuales pueden comportarse de manera similar, pero la naturaleza de ciclo rápido de los contenedores puede dificultar la captura de telemetría.
Además, los contenedores suelen implementarse en grandes cantidades en entornos de nube, lo que dificulta aún más la visibilidad.
La eBPF, que se ejecuta en el núcleo de un host o contenedor, permite a los desarrolladores recopilar datos de 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. Gracias a la eBPF, los desarrolladores pueden recopilar información sobre procesos, uso de memoria, actividad de red y acceso a archivos a nivel de contenedor, incluso si los contenedores no están implementados en la nube.
Del mismo modo, en entornos contenedorizados basados en Kubernetes, la eBPF utiliza una única interfaz y un conjunto de herramientas para recopilar datos de clústeres dispares, por lo que los equipos de TI no tienen que implementar 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 los nodos del plano de control (por ejemplo, para monitorizar el servidor API) y monitorizar los nodos de trabajo para generar conocimientos, correlacionando los puntos de datos y los conocimientos de ambos tipos de nodos, lo que permite obtener una observabilidad del clúster más precisa.
Red Hat OpenShift on IBM Cloud es una plataforma de contenedores OpenShift (OCP) totalmente gestionada.
Virtualización de almacenamiento segura, fiable y eficiente para entornos VMware con IBM Spectrum Virtualize.
Encuentre la solución de infraestructura en la nube adecuada para las necesidades de su empresa y escale los recursos según la 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.