Introduction to BPF Manager (bpfman)
Original Article: https://www.ebpf.top/post/bpfman_fedora_40
1. Background
Fedora 40 proposes bpfman as the default program manager. The open-source project bpfman provides a deeper understanding of the eBPF runtime state, making it easier to manage eBPF programs (including loading, unloading, and viewing runtime status). This proposal requires approval from the Fedora Engineering Steering Committee (FESCo), but if successful, bpfman is likely to appear in Fedora 40 in April to enhance eBPF management.
So, what exactly is bpfman? This article will give you a brief introduction to bpfman and its working principles.
2. Introducing bpfman
Originally named bpfd
, bpfman is developed based on the Rust Aya library, using the Rust programming language. The bpfman project is designed to simplify the loading, unloading, modification, and monitoring of eBPF programs on Kubernetes clusters or single hosts. The bpfman project consists of the bpfman daemon, eBPF CRD (Custom Resource Definition), bpfman-agent, and bpfman-operator. Among them, CRDs, bpfman-agent, and bpfman-operator are components deployed in a distributed manner around the Kubernetes environment:
- bpfman: A system daemon running on a single host, it provides a gRPC API for loading, unloading, modifying, and monitoring eBPF programs.
- eBPF CRDs: Provides two types of CRDs: deployment CRDs and BPF program status view CRDs. Deployment-related CRDs (such as XdpProgram and TcProgram) are used to load different types of eBPF programs. Program status view CRDs (BpfProgram) are used to manage the runtime status of eBPF programs loaded into the kernel.
- bpfman-agent: Runs in a container within the bpfman daemon and ensures that the selected node’s eBPF programs are in the desired state.
- bpfman-operator: An Operator built using the Operator SDK, it manages the installation and lifecycle of bpfman-agent and CRDs in the Kubernetes cluster.
3. Standalone Deployment Process
When deploying bpfman in a standalone environment, the workflow is as follows. The bpfman binary can be deployed as both a server and a client program. In addition to using the bpfman client program, users can also interact with the bpfman server for various management operations in user space programs:
- When the go-xdp-counter user space program starts, it sends a gRPC request to bpfman through a Unix socket to request the loading of the go-xdp-counter eBPF bytecode (bpfman/examples/go-xdp-counter/bpf_bpfel.o) located on the disk, with a priority of 50, and the program applies to the ens3 interface.
- Upon receiving the request, bpfman loads the corresponding eBPF program (go-xdp-counter) and returns the UUID of the running program.
- Users can use the
bpfman list
command to display the eBPF programs managed by the system. - After the eBPF bytecode (go-xdp-counter) is successfully loaded, the running eBPF program will count the packets and bytes and write them into a shared map structure.
- The corresponding user space program (go-xdp-counter) periodically reads the counters from the shared map and records the values.
The loaded bytecode can also be a remote image, such as
sudo ./go-xdp-counter -iface ens3 -image quay.io/bpfman-bytecode/go-xdp-counter:latest
. The bytecode image needs to follow certain specifications.
4. Kubernetes Cluster Deployment Process
Deploying and managing eBPF programs in a distributed environment like a Kubernetes cluster can be more complex. bpfman focuses on addressing the following challenges:
- Managing the permissions and capabilities required for enabling eBPF applications.
- Resolving the issue of multiple eBPF programs on the same hook function and their lifecycle management (especially multiple mounts under xdp mode, which is not supported by the kernel by default).
- Simplifying the complexity of deployment and program lifecycle in Kubernetes.
- Aimed at optimization in terms of security, visibility, multi-program support, and productivity.
Deploying and managing eBPF programs with bpfman in a Kubernetes environment can be divided into two stages:
- Managing eBPF bytecode programs running in the kernel.
- Deploying and reading data from user space programs corresponding to the kernel space (usually used to read runtime data or load configurations), which need to be deployed separately (mounted and read data through CSI).
The deployment and management process of bpfman in Kubernetes is shown in the following diagram:
1. Write a CR resource type XdpProgram
, define parameters related to deployment machine labels and eBPF bytecode (such as interface, priority, and BPF bytecode image). In this example, the resource name of XdpProgram
is go-xdp-counter-example
. Then, you can use kbueclt apply -f bytecode.yaml
to submit it to the cluster to take effect. The complete yaml file is as follows:
|
|
-
bpfman-agent
runs on the expected nodes and monitors the corresponding CR resource objectXdpProgram
. The bpfman-agent ensures that a correspondingBpfProgram
object is generated for the created or modifiedXdpProgram
object. The name of theBpfProgram
object is a combination of theXdpProgram
name, node name, interface, and connection point information.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ kubectl get xdpprogram NAME PRIORITY DIRECTION go-xdp-counter-example 55 $ kubectl get xdpprograms go-xdp-counter-example -o yaml apiVersion: bpfman.io/v1alpha1 kind: XdpProgram ... status: conditions: - lastTransitionTime: "2023-11-06T21:05:21Z" message: bpfProgramReconciliation Succeeded on all nodes reason: ReconcileSuccess status: "True" type: ReconcileSuccess
In the above
XdpProgram
object’sstatus
field, we can see that the program has been successfully distributed to the target nodes. -
bpfman-agent
loads or unloads eBPF bytecode programs as needed by making gRPC calls tobpfman
. The behavior ofbpfman
is the same as described in the single-machine running example. -
Finally,
bpfman-agent
updates the status of theBpfProgram
object.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$ kubectl get bpfprograms NAME AGE go-xdp-counter-example-bpfman-deployment-control-plane-eth0 60m $ kubectl get go-xdp-counter-example-bpfman-deployment-control-plane-eth0 -o yaml apiVersion: bpfman.io/v1alpha1 kind: BpfProgram .... spec: type: xdp status: conditions: - lastTransitionTime: "2023-11-06T21:05:21Z" message: Successfully loaded bpfProgram reason: bpfmanLoaded status: "True" type: Loaded
-
bpfman-operator
monitors allBpfProgram
objects and updates the status ofXdpProgram
objects to show whether the eBPF program has been applied to the corresponding nodes.
However, attentive readers may have noticed that the above process only completes the loading of eBPF bytecode into the kernel (with bpfman acting as the eBPF loader), but the runtime-exposed data and metrics have not yet been collected. Therefore, a separate userspace program needs to be deployed to read the data generated by the eBPF counter program (as shown in the above diagram using a map data structure).
Here, we need to deploy a separate userspace program to consume the map data generated by the eBPF counter program. bpfman provides a Container Storage Interface (CSI) driver to expose eBPF maps to userspace containers. To avoid having to mount the host directory containing the fixed files of the map into the container and forcing the container to have access to that host directory, the CSI driver mounts the map to a specified location inside the container.
|
|
Here, we introduced the complete process of deploying xdp-type programs using bpfman in a Kubernetes environment. Compared to deploying on a single machine, management in a distributed environment is more complex.
5. Summary
Here we provided a brief introduction to bpfman. For more details, please refer to https://bpfman.io/. Based on my personal use and testing experience, here are a few points I would like to share:
-
bpfman is developed using Rust and is somewhat niche in the cloud-native field.
-
In the K8s environment, eBPF loading and data reading are separate processes, mounted through the CSI interface. Both deployment installation and usage are not very smooth, and there may be better solutions in the future.
-
The project uses the libxdp library to implement the loading of multiple XDP programs on a single interface and deployment without a daemon, which can be considered as a special feature.
In any case, bpfman provides a complete architectural implementation for managing and distributing eBPF programs in a single machine or Kubernetes distributed environment, which is worth learning.
Appendix: bpfman Single Machine Verification
It can be directly installed via the rpm package in the Fedora distribution. In the Ubuntu system, it needs to be installed from source code.
Development Environment Setup
|
|
Code Download and Compilation of bpfman
|
|
Compile and load eBPF programs
|
|
Test program management functionality
|
|
In addition to running user space programs, you can also load them using bpfman load
(supports loading from images).
You can check the loaded logs in the bpfman process log:
|
|
To view the loaded programs, you can use bpfman list
:
|
|
To uninstall, simply run bpfman unload 1872
.
Or you can use bpfman get pid
to view specific execution details:
|
|
Note: The translation provided is a colloquial, professional, elegant, and fluent interpretation of the text.
- Author: DavidDi
- Link: https://www.ebpf.top/en/post/bpfman_fedora_40/
- License: This work is under a Attribution-NonCommercial-NoDerivs 4.0 International. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.
- Last Modified Time: 2024-02-04 13:17:14.579554444 +0800 CST