BPF 管理器 bpfman 简介

1. 背景

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

img
img

那么 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 服务端交互完各种管理操作:

image-20240130154830668
image-20240130154830668
  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 中部署和管理的流程图如下所示:

go-xdp-counter On Kubernetes
go-xdp-counter On 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 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/363548.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AIGC专题:从0到1精益创新 AIGC产品应用及商业化落地实践

今天分享的是AIGC系列深度研究报告&#xff1a;《AIGC专题&#xff1a;从0到1精益创新 AIGC产品应用及商业化落地实践》。 &#xff08;报告出品方&#xff1a;易点天下&#xff09; 报告共计&#xff1a;38页 企业内部增效-AI知识库 企业内部IT、运维、人力资源、行政等等日…

Unity 模板方法模式(实例详解)

文章目录 简介示例1&#xff1a;游戏关卡流程示例2&#xff1a;测试试卷类示例3&#xff1a;游戏场景构建流程示例4&#xff1a;游戏动画序列示例5&#xff1a;游戏对象初始化过程 简介 Unity中的模板方法模式是一种行为设计模式&#xff0c;它在父类中定义了一个算法的框架&a…

微软新的内部开发部门发现了第一个 Windows 12 版本

Windows 11 被证明让很多人有点失望&#xff0c;很多 Windows 10 用户认为没有理由升级。 这意味着有大量用户渴望一些大而令人印象深刻的东西——而这正是 Windows 12 所希望的。 无论您是 Windows 10 的忠实拥趸&#xff0c;还是渴望更新、更闪亮的 Windows 11 采用者&#x…

笔记本电脑Win11重装系统教程

在笔记本电脑Win11操作过程中&#xff0c;用户如果遇到很严重的系统问题&#xff0c;就可以重新正常的Win11系统&#xff0c;快速解决Win11系统问题。但是&#xff0c;部分新手用户不知道不知道如何操作才能给Win11笔记本电脑重装系统&#xff1f;以下小编分享笔记本电脑Win11重…

分布式事务(五)——基于本地消息和可靠消息的解决方案

系列目录&#xff1a; 《分布式事务&#xff08;一&#xff09;—— 事务的基本概念》 《分布式事务&#xff08;二&#xff09;—— CAP和Base理论》 《分布式事务&#xff08;三&#xff09;—— 两阶段提交解决方案&#xff08;2PC&#xff09;》 《分布式事务&#xff0…

安卓滚动视图ScrollView

<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:orientatio…

mybatisplus-多数据源配置

1. 流程 pom文件yml配置多数据源具体服务添加注解DS(“***”) 1.pom文件 <!--mybatis plus 起步依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</vers…

《苍穹外卖》电商实战项目实操笔记系列(P123~P184)【下】

史上最完整的《苍穹外卖》项目实操笔记系列【下篇】&#xff0c;跟视频的每一P对应&#xff0c;全系列10万字&#xff0c;涵盖详细步骤与问题的解决方案。如果你操作到某一步卡壳&#xff0c;参考这篇&#xff0c;相信会带给你极大启发。 上篇&#xff1a;P1~P65《苍穹外卖》项…

JavaWeb前端——HTML/CSS

HTML/CSS概述 HTML&#xff1a;学习标签&#xff0c;CSS&#xff1a;学习样式 HTML 1. 不区分大小写。 2. 属性可以使用单引号/双引号 3. 在记事本/编辑器中编写html语言&#xff0c;通过浏览器解析渲染语言 4. 语法结构松散&#xff08;编写时要尽量严谨&#xff09; VSc…

Vulnhub-RIPPER: 1渗透

文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、rips的使用三、获取密码文件四、日志审查五、提权 一、前言 由于在做靶机的时候&#xff0c;涉及到的渗透思路是非常的广泛&#xff0c;所以在写文章的时候都是挑重点来写&#xff0c;尽量的不饶…

Ant Design Mini - 支付宝小程序官方推出的免费开源 UI 组件库,新增支持微信小程序,实用性大大增加

支付宝小程序官方的 UI 组件库开始支持运行在微信小程序上了&#xff0c;如果要开发这两家小程序平台&#xff0c;这套组件很合适。 Ant Design Mini 也简称 antd-mini &#xff0c;是一套运行在支付宝小程序的 UI 组件库&#xff0c;UI 设计遵循 Ant Design 规范&#xff0c;…

前端Vue select 下拉框详解以及监听事件

目录 简介 使用详解 演示示例 :key"option.value" :value"option.value" 区别 监听事件 简介 在 Vue 中&#xff0c;下拉框通常通过 <select> 元素与一系列的 <option> 元素来创建。Vue 的数据绑定和指令&#xff08;如 v-model 和 v-for…

color - 让你的输出带点颜色

color color 是一个可以让你输出带颜色文本的库。 安装 go get github.com/fatih/color示例 输出到控制台 // 这会直接输出到控制台 color.Cyan("Prints text in cyan.")// 每个调用末尾会自动加上换行 color.Blue("Prints %s in blue.", "text&…

composer常用命令

查看全局配置信息 composer config -gl 设置镜全局像地址 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 去掉-g&#xff0c;即表示只有当前项目使用该镜像 批量安装composer项目依赖 composer install 执行该命令后&#xff0c;会读取当…

1295584-83-6,NOTA 马来酰亚胺,可通过与铁离子结合增强MRI信号

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;1295584-83-6&#xff0c;NOTA Maleimide&#xff0c;NOTA Mal&#xff0c;NOTA马来酰亚胺 一、基本信息 产品简介&#xff1a;NOTA Maleimide has good water solubility and stability, which enables it to main…

不移其志,踏浪前行 | 北京智和信通召开2023年度工作总结大会

岁聿云暮&#xff0c;新元肇启&#xff0c;2024年1月24日&#xff0c;北京智和信通技术有限公司&#xff08;以下简称“北京智和信通”&#xff09;召开2023年度年终总结大会。会上&#xff0c;各部门负责人全面分析公司业务发展态势&#xff0c;各部门员工依次汇报主要工作情况…

Javaweb实现的学生宿舍管理系统

Javaweb实现的学生宿舍管理系统 文章目录 Javaweb实现的学生宿舍管理系统系统介绍技术选型成果展示源码获取账号地址及其他说明 系统介绍 Javaweb实现的学生宿舍管理系统采用jspservlet技术实现了如下功能模块&#xff0c;分别是宿舍管理员管理、学生管理、宿舍楼管理、缺勤记…

Solidworks 与 MATLAB 联合仿真

本文主要讲解了“MATLAB与SolidWorks的联合仿真怎么实现”&#xff0c;文中的讲解内容简单清晰&#xff0c;易于学习与理解&#xff0c;下面请大家跟着小编的思路慢慢深入&#xff0c;一起来研究和学习“MATLAB与SolidWorks的联合仿真怎么实现”吧&#xff01; 下载插件。 1、…

基于 LLM+LlamaIndex+NebulaGraph,构建大模型知识图谱的检索(RAG)方法

最近&#xff0c;围绕着利用 LLM&#xff08;Language Model&#xff09;和知识图谱&#xff08;KG&#xff0c;Knowledge Graphs&#xff09;构建RAG&#xff08;Retrieval Augmented Generation&#xff09;流程引起了很多关注。 在本文中&#xff0c;让我们通过利用 LlamaI…

leetcode189.轮转数组|超简单易于理解方法

题目 https://leetcode.cn/problems/rotate-array/description/https://leetcode.cn/problems/rotate-array/description/ 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输…