BPF 管理器 bpfman 简介

2024-02-01 23:04
文章标签 简介 管理器 bpf bpfman

本文主要是介绍BPF 管理器 bpfman 简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 背景

Fedora 40 提案建议将 bpfman 作为默认的程序管理器 ,开源项目 bpfman 可以实现对 eBPF 运行状态的深入了解,从而实现更轻松地管理 eBPF 程序(包括加载、卸载、运行状态查看等)。该提案还需要 Fedora 工程和指导委员会 (FESCo) 的批准,如果顺利很可能会在 4 月份出现在 Fedora 40 中以增强 eBPF 管理。

那么 bpfman 到底是一个什么样的项目呢?本文将带你简单了解 bpfman 及其工作原理。

2. bpfman 介绍

bpfman 早期名字为 bpfd,基于 Rust Aya 库开发,开发语言是 Rust。bpfman 项目用于简化 Kubernetes 集群或单主机上的 eBPF 程序的加载、卸载、修改和监控等。bpfman 项目由单机系统守护进程 bpfman、eBPF CRD、bpfman-agent 和 bpfman-operator 等构成,其中 CRD、bpfman-agent 和 bpfman-operator 都是围绕 Kubernetes 环境分布式部署的相关组件:

  • bpfman:单主机的系统守护进程,对外提供 gRPC API,可支持 eBPF 程序加载、卸载、修改和监控;
  • eBPF CRDS:提供两种类别的 CRD :部署 CRD 和 BPF 程序状态查看 CRD。部署相关 CRD (如 XdpProgram、TcProgram 等),用于加载不同类型的 eBPF 程序。程序状态查看类 CRD (BpfProgram),用于管理加载到内核的 eBPF 程序的运行状态;
  • bpfman-agent:运行在 bpfman 守护进程的容器中,用于确保选择节点 eBPF 程序处于声明的状态;
  • bpfman-operator:使用 Operator SDK 构建的 Operator,用于管理 Kubernetes 集群中 bpfman-agent 和 CRD 的安装和生命周期。

3. 单机部署流程

单机上部署 bpfman,其工作流程如下,其中 bpfman 二进制既可作为服务端部署也作为客户端程序使用。除了使用 bpfman 客户端程序外,用户也可以在用户空间的程序代码与 bpfman 服务端交互完各种管理操作:

  1. 当 go-xdp-counter 用户空间启动时,其通过 unix 套接字向 bpfman 发送 gRPC 请求,请求 bpfman 加载位于磁盘上的 go-xdp-counter eBPF 字节码(bpfman/examples/go-xdp-counter/bpf_bpfel.o), 优先级为 50,程序作用与 ens3 接口;
  2. bpfman 接收到请求后,将加载对应的 eBPF 程序(go-xdp-counter),并返回运行的程序的 UUID;
  3. 用户可以通过 bpfman list 可用于显示系统管理的 eBPF 程序;
  4. 完成 eBPF 字节码(go-xdp-counter)加载工作后,触发运行的 eBPF 程序就会将数据包计数和字节计数写入共享 map 结构;
  5. go-xdp-counter 对应的用户空间程序定期从共享 map 中读取计数器并记录该值。

加载的字节码也可以是远程镜像的,如 sudo ./go-xdp-counter -iface ens3 -image quay.io/bpfman-bytecode/go-xdp-counter:latest,字节码的镜像需要有一定规范。

4. Kubernetes 集群部署架构和流程

在 Kubernetes 集群分布式环境中部署和管理 eBPF 程序将更加复杂,bpfman 重点解决了以下挑战:

  • 管理 eBPF 启用应用所需的权限和能力;
  • 解决同一挂钩函数上多个 eBPF 程序的问题以及生命周期管理(特别是 xdp 模式下的多次挂载,内核默认不支持);
  • 简化 Kubernetes 中的部署和程序生命周期的复杂性;
  • 旨在安全性、可视性、多程序支持和生产力方面实现优化。

bpfman 在 Kubernetes 环境中管理 eBPF 程序可分为两个阶段:

  1. 运行在内核中的 eBPF 字节码程序管理;
  2. 与内核空间对应的 eBPF 用户空间程序的部署和数据读取,用户空间程序通常用于读取运行时数据或加载配置,需要单独部署用户空间程序(通过 CSI 方式挂载并读取数据)。

bpfman 在 Kubernetes 中部署和管理的流程图如下所示:

  1. 编写 CR 资源类型 XdpProgram ,定义部署机器标签、 eBPF 字节码相关的参数(例如接口、优先级和 BPF 字节码镜像等 )。本例中的 XdpProgram 资源名称是 go-xdp-counter-example。然后可使用 kbueclt apply -f bytecode.yaml 提交到集群生效。完整的 yaml 文件如下所示:

    # cat examples/config/base/go-xdp-counter/bytecode.yaml
    apiVersion: bpfman.io/v1alpha1
    kind: XdpProgram
    metadata:
      labels:
        app.kubernetes.io/name: xdpprogram
      name: go-xdp-counter-example
    spec:
      name: xdp_stats
      # Select all nodes
      nodeselector: {}
      interfaceselector:
        primarynodeinterface: true
      priority: 55
      bytecode:
        image:
          url: quay.io/bpfman-bytecode/go-xdp-counter:latest
  2. bpfman-agent 运行在预期的节点上,监听对应的 CR 资源对象 XdpProgram。bpfman-agent 确保创建或修改的 XdpProgram 对象会生成一个对应 BpfProgram 对象。 BpfProgram 对象的名称是 XdpProgram 附加节点名称/接口/连接点信息的组合。

    $ 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

    在上述对象 XdpProgram 的 staus 字段中,我们可以看到已经将程序成功分发到了目标节点。

  3. bpfman-agent 通过 gRPC 调用 bpfman 来根据需要加载或卸载 eBPF 字节码程序。 bpfman 行为与单机运行示例中描述的相同。

  4. 最后,由 bpfman-agent 更新 BpfProgram 对象的状态。

    $ 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
  5. bpfman-operator 监视所有 BpfProgram 对象,并更新 XdpProgram 对象的状态,用户展示 eBPF 程序是否已应用于所对应的节点。

但是细心的读者有可能已经注意到,上述流程只是完成了 eBPF 字节码在内核中的加载(bpfman 充当了 eBPF 加载器),但是运行时暴露的数据和指标还未完成采集,因此还需要单独部署一个用户空间程序完成数据读取(上述图中为 map 数据结构)。

这里,我们需要单独部署了一个用户空间程序来消费 eBPF 计数器程序生成的 map 数据。bpfman 提供容器存储接口 (CSI) 驱动程序,用于将 eBPF map 暴露到用户空间容器中。为了避免必须将包含 map 固定文件的主机目录装载到容器中并强制容器具有访问该主机目录的权限,CSI 驱动程序将 map 装载到容器中的指定位置。

#cat config/base/go-xdp-counter/deployment.yaml
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: go-xdp-counter-ds
  namespace: go-xdp-counter
  labels:
    k8s-app: go-xdp-counter
spec:
  :
  template:
    :
    spec:
       :
      containers:
      - name: go-xdp-counter
        :
        volumeMounts:
        - name: go-xdp-counter-maps                        <==== 2) VolumeMount in container
          mountPath: /run/xdp/maps                         <==== 2a) Mount path in the container
          readOnly: true
      volumes:
      - name: go-xdp-counter-maps                          <==== 1) Volume describing the map
        csi:
          driver: csi.bpfman.io                             <==== 1a) bpfman CSI Driver
          volumeAttributes:
            csi.bpfman.io/program: go-xdp-counter-example   <==== 1b) eBPF Program owning the map
            csi.bpfman.io/maps: xdp_stats_map               <==== 1c) Map to be exposed to the container

至此,我们介绍了在 Kubernetes 环境中使用 bpfman 部署 xdp 类型程序的完整流程,相对于单机部署,分布式环境中的管理更加复杂。

5. 总结

这里我们针对 bpfman 进行了简单介绍,更多的细节请参考 https://bpfman.io/。从我个人的使用和测试流程来看,以下几点个人体会:

  • bpfman 采用 Rust 开发,在云原生领域中略有些小众;

  • 在 K8s 环境中 eBPF 加载和数据读取单独分离,通过 CSI 接口挂载,这里无论是从部署安装还是使用层面都有些不太流畅,未来可能会有更优的解法。

  • 项目基于 libxdp 库实现了单接口多次 XDP 程序加载和 Daemonless 化的部署也算一个特色功能。

无论如何,bpfman 还是为单机或 Kubernetes 分布式环境管理分发 eBPF 程序提供了一个完整的架构实现,值得学习。

附录:bpfman 单机验证

在 Fedora 发行版中可直接通过 rmp 包安装。在 Ubuntu 系统中需要通过源码方式安装。

开发环境搭建

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  stable-x86_64-unknown-linux-gnu installed - rustc 1.75.0 (82e1608df 2023-12-21)

.....
Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, run:
source "$HOME/.cargo/env"

$
  source "$HOME/.cargo/env"

$
 rustup toolchain install nightly -c rustfmt,clippy,rust-src
...
info: installing component 'rustfmt'

  nightly-x86_64-unknown-linux-gnu installed - rustc 1.77.0-nightly (5518eaa94 2024-01-29)

info: checking for self-update

下载代码和编译 bpfman

$ git clone https://github.com/bpfman/bpfman.git && cd bpfman
$ cargo xtask build-ebpf --libbpf-dir=/home/dave/test/libbpf-bootstrap-1/libbpf

#
 构建 bpfman,编译成功后位于 ./target/debug/bpfman 
$ cargo build

$
 file ./target/debug/bpfman
./target/debug/bpfman: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e3028a97943b1dafcadbd7c9e9c99d9fb49aa5fe, for GNU/Linux 3.2.0, with debug_info, not stripped


$
 ./target/debug/bpfman --help
An eBPF manager focusing on simplifying the deployment and administration of eBPF programs.

Usage: bpfman <COMMAND>

Commands:
  load    Load an eBPF program from a local .o file
  unload  Unload an eBPF program using the program id
  list    List all eBPF programs loaded via bpfman
  get     Get an eBPF program using the program id
  image   eBPF Bytecode Image related commands
  system  Run bpfman as a service
  help    Print this message or the help of the given subcommand(s)

Options:
  -h, --help
          Print help (see a summary with '-h')
  
#
 单机进程运行  
$ RUST_LOG=info ./target/debug/bpfman system service --timeout 0

#
 或者安装为系统服务
$ sudo ./scripts/setup.sh install
Copy CLI TAB Completion files:
  CLI TAB Completion files not generated yet. Use "cargo xtask build-completion" to generate.
Copy Manpage files:
  CLI Manpage files not generated yet. Use "cargo xtask build-man-page" to generate.
Copy binaries:
  Copying "../target/debug/bpfman" to "/usr/sbin"
Copy service files:
  Copying "bpfman.socket"
  Copying "bpfman.service"
  Starting "bpfman.socket"
Created symlink /etc/systemd/system/sockets.target.wants/bpfman.socket → /lib/systemd/system/bpfman.socket.


$
 sudo  systemctl start bpfman
$ sudo systemctl status bpfman
● bpfman.service - Run bpfman as a service
     Loaded: loaded (/lib/systemd/system/bpfman.service; static)
     Active: active (running) since Tue 2024-01-30 16:10:28 CST; 2s ago
TriggeredBy: ● bpfman.socket
   Main PID: 1563623 (bpfman)
      Tasks: 23 (limit: 18814)
     Memory: 25.4M
        CPU: 237ms
     CGroup: /system.slice/bpfman.service
             └─1563623 /usr/sbin/bpfman system service

1 月 30 16:10:28 dave systemd[1]: Started Run bpfman as a service.
1 月 30 16:10:28 dave bpfman[1563623]: Log using journald
1 月 30 16:10:28 dave bpfman[1563623]: Has CAP_BPF: true
1 月 30 16:10:28 dave bpfman[1563623]: Has CAP_SYS_ADMIN: true
....

编译和加载 eBPF 程序

$ sudo apt-get install libbpf-dev
$ sudo go install github.com/cilium/ebpf/cmd/bpf2go@master

$
 cd bpfman/examples/
$ make generate
$ make build

测试程序管理功能

# cd bpfman/examples/go-xdp-counter
# ./go-xdp-counter -iface lo
2024/01/31 19:28:25 Using Input: Interface=lo Priority=50 Source=/home/dave/bpfman/examples/go-xdp-counter/bpf_bpfel.o
2024/01/31 19:28:30 Program registered with id 1872
2024/01/31 19:28:33 153212 packets received
2024/01/31 19:28:33 9993784 bytes received
...

除了运行用户空间程序外,也可以使用 bpfman load 的方式加载(支持从镜像加载)。

我们可以在 bpfman 进程运行日志中查看到加载的日志:

# RUST_LOG=info ./target/debug/bpfman system service --timeout 0
[INFO  bpfman::cli::system] Log using env_logger
[INFO  bpfman::cli::system] Has CAP_BPF: true
[INFO  bpfman::cli::system] Has CAP_SYS_ADMIN: true
[INFO  bpfman::serve] Using no inactivity timer
[INFO  bpfman::serve] Using default Unix socket
[INFO  bpfman::serve] Listening on /run/bpfman/sock/bpfman.sock
[INFO  bpfman::oci_utils::cosign] Starting Cosign Verifier, downloading data from Sigstore TUF repository

....
[INFO  bpfman::command] Loading program bytecode from file: /home/dave/bpfman/examples/go-xdp-counter/bpf_bpfel.o
[INFO  bpfman::oci_utils::cosign] The bytecode image: quay.io/bpfman/xdp-dispatcher:v2 is signed
[INFO  bpfman::bpf] Added xdp program with name: xdp_stats and id: 1872

可以使用 bpfman list 查看加载的程序:

# bpfman list
 Program ID  Name       Type  Load Time
 1872        xdp_stats  xdp   2024-01-31T19:28:30+0800

如果需要卸载则直接运行 bpfman unload 1872

或通过 bpfman get pid 查看具体的执行详情:

# bpfman get 1872
 Bpfman State
 Name:          xdp_stats
 Path:          /home/dave/bpfman/examples/go-xdp-counter/bpf_bpfel.o
 Global:        None
 Metadata:      None
 Map Pin Path:  /run/bpfman/fs/maps/1872
 Map Owner ID:  None
 Maps Used By:  1872
 Priority:      50
 Iface:         lo
 Position:      0
 Proceed On:    pass, dispatcher_return

 Kernel State
 ID:                               1872
 Name:                             xdp_stats
 Type:                             xdp
 Loaded At:                        2024-01-31T19:28:30+0800
 Tag:                              4d23a1d7f3618653
 GPL Compatible:                   true
 Map IDs:                          [468]
 BTF ID:                           598
 Size Translated (bytes):          168
 JITted:                           true
 Size JITted:                      104
 Kernel Allocated Memory (bytes):  4096
 Verified Instruction Count:       21

本文由 mdnice 多平台发布


原文:https://www.ebpf.top/post/bpfman_fedora_40/

这篇关于BPF 管理器 bpfman 简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/668758

相关文章

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【Tools】AutoML简介

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 AutoML(自动机器学习)是一种使用机器学习技术来自动化机器学习任务的方法。在大模型中的AutoML是指在大型数据集上使用自动化机器学习技术进行模型训练和优化。

SaaS、PaaS、IaaS简介

云计算、云服务、云平台……现在“云”已成了一个家喻户晓的概念,但PaaS, IaaS 和SaaS的区别估计还没有那么多的人分得清,下面就分别向大家普及一下它们的基本概念: SaaS 软件即服务 SaaS是Software-as-a-Service的简称,意思是软件即服务。随着互联网技术的发展和应用软件的成熟, 在21世纪开始兴起的一种完全创新的软件应用模式。 它是一种通过Internet提供

【Python知识宝库】上下文管理器与with语句:资源管理的优雅方式

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、什么是上下文管理器?二、上下文管理器的实现三、使用内置上下文管理器四、使用`contextlib`模块五、总结 前言 在Python编程中,资源管理是一个重要的主题,尤其是在处理文件、网络连接和数据库

Apache Tiles 布局管理器

陈科肇 =========== 1.简介 一个免费的开源模板框架现代Java应用程序。  基于该复合图案它是建立以简化的用户界面的开发。 对于复杂的网站,它仍然最简单,最优雅的方式来一起工作的任何MVC技术。 Tiles允许作者定义页面片段可被组装成在运行一个完整的网页。  这些片段,或Tiles,可以用于为了降低公共页面元素的重复,简单地包括或嵌入在其它瓦片,制定了一系列可重复使用

LIBSVM简介

LIBSVM简介 支持向量机所涉及到的数学知识对一般的化学研究者来说是比较难的,自己编程实现该算法难度就更大了。但是现在的网络资源非常发达,而且国际上的科学研究者把他们的研究成果已经放在网络上,免费提供给用于研究目的,这样方便大多数的研究者,不必要花费大量的时间理解SVM算法的深奥数学原理和计算机程序设计。目前有关SVM计算的相关软件有很多,如LIBSVM、mySVM、SVMLight等,这些

urllib与requests爬虫简介

urllib与requests爬虫简介 – 潘登同学的爬虫笔记 文章目录 urllib与requests爬虫简介 -- 潘登同学的爬虫笔记第一个爬虫程序 urllib的基本使用Request对象的使用urllib发送get请求实战-喜马拉雅网站 urllib发送post请求 动态页面获取数据请求 SSL证书验证伪装自己的爬虫-请求头 urllib的底层原理伪装自己的爬虫-设置代理爬虫coo

新一代车载(E/E)架构下的中央计算载体---HPC软件架构简介

老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节能减排。 无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事.而不是让内心的烦躁、焦虑、毁掉你本就不多的热情和定力。 时间不知不觉中,快要来到夏末秋初。一年又过去了一大半,成