【Linux内核】eBPF基础篇

系列综述:
💞目的:本系列是个人整理为了学习ebpf机制的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于–知乎ebpf专栏文章–进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!

请先收藏!!!,后续继续完善和扩充👍(●’◡’●)


文章目录

    • 一、eBPF介绍
      • 简介
      • eBPF特性
    • 二、eBPF程序
      • 基础
      • eBPF程序生命周期
    • 三、SEC程序类型(未完待续)
      • SEC概述
      • XDP类型程序
      • 用户与内核的交互
    • 参考博客


😊点此到文末惊喜↩︎

前言

  1. eBPF提升内核的能效是目标,它要发挥的是瑞士军刀的作用,如果只是为了eBPF而eBPF,那它就是狗皮膏药,你只是为了把它贴到身体的某个地方而已,并且你也会一直找这样的地方,找准机会就贴上去。另一句意思相同的话,大概是如果你有个锤子,那么眼里什么都是钉子
  2. eBPF应该慎用,其会增加系统的复杂度,从而导致故障概率的提升

一、eBPF介绍

简介

  1. eBPF概述
    • 背景:eBPF(extended Berkeley Packet Filter)是一种扩展的伯克利包过滤器,由原来的网络过滤器BPF 演进成的一个可插拔可编程的内核模块eBPF,可基于此开发性能分析工具、软件定义网络等诸多场景。
    • 定义:处于内核中的一个高效与灵活的虚拟机组件,以一种安全的方式在许多内核 hook 点执行字节码。
    • 作用
      • 内核可编程:eBPF不需要重新编译内核,并实现动态注入内核运行并随时卸载
      • 嵌入内核:直接与内核进行交互,避免了用户态和内核态的切换开销
      • 内核监控:追踪内核中的各种事件或资源使用情况,从而进行调试或性能优化
      • 安全加载:通过Verifier验证器和其他安全检查,以及helper API的能力限制,实现安全的加载到内核
      • 功能直达:绕过内核中非必要的子系统,直接进行数据包的处理和转发
    • 特点
      • bpf_helpers:eBPF 程序不能调用任意的内核参数,只限于内核模块中列出的 BPF Helper API函数
      • 有界循环:eBPF 程序中循环次数限制且必须在有限时间内结束,防止系统运行出现死锁
      • 一旦进入内核,eBPF便拥有了上帝视角,既可以监控内核,也可以管窥用户态程序。并且eBPF技术提供的一系列工具(Verifier)可以检测eBPF的代码安全,避免恶意程序进入到内核态中执行。
  2. eBPF的组成
    • 用户态程序:负责加载 BPF 字节码至内核,如需要也会负责读取内核回传的统计信息或者事件详情
    • 内核态BPF字节码程序: 负责在内核中执行特定事件,如需要也会将执行的结果通过 maps 或者 perf-event 事件发送至用户空间
    • 其中用户空间程序与内核 BPF 字节码程序可以使用 map 结构实现双向通信
  3. eBPF的执行流程
    • 用户态
      • 编译:使用 LLVM 或 GCC 工具将编写的 eBPF 程序编译成 eBPF 字节码
      • 加载:调用 bpf()系统调用把 eBPF 字节码加载到内核。
    • 内核态
      • Verfier验证与JIT编译:内核使用验证器验证字节码安全性,通过JIT(Just In Time)将 eBPF 字节码编译成机器码(Native Code)
      • Kernel Helper API:内核会根据eBPF功能将机器码挂载到内核对应的Hook,当运行到某个Hook就会执行对应的eBPF程序
        在这里插入图片描述
  4. eBPF中用户态与内核态的通信方式
    • maps方式:将数据存储在内核键值对数据结构中,数据由内核eBPF字节码程序更新,并共享给用户态程序进行周期性查询
    • perf-event方式:可用于捕获内核中的多种软硬件事件,并将这些事件实时发送给用户空间程序
  5. eBPF应用实践
    • cilium: 将eBPF技术应用于Kubernetes中,提供高性能网络和安全功能。
    • Falco: 基于eBPF技术的云原生安全运行时,用于在Kubernetes环境中检测威胁。
    • Katran: 使用eBPF实现的高性能四层负载均衡器,用于处理网络流量。
    • pixie: 一种可观察性工具,使用eBPF技术提供对Kubernetes应用程序的详细监控和调试能力。
      在这里插入图片描述

eBPF特性

  1. eBPF中的Hook
    • 定义:hook是指内核中特定函数(事件)的发生,包括系统调用、函数进入/退出、网络事件等
    • 原理:
      • tracepoint机制:基于内核标记点tracepoint来追踪内核中的特定事件
      • kprobes机制:可以在内核函数的入口或出口处插入Hook
      • uprobes机制:可以在用户空间函数的入口或出口处插入Hook
        在这里插入图片描述
  2. eBPF的Verification
    • 过程:每一个 eBPF 程序加载到内核前,都要经过 Verification来保证 eBPF 程序的安全性
    • 加载对象:除非节点开启了 unpriviledged 特性,否则只有高特权级的程序才能够加载 eBPF 程序
    • 作用:
      • 核心:保证 eBPF 程序不会崩溃或者使得系统出故障
      • 时间:保证 eBPF 程序不能陷入死循环
      • 空间:保证 eBPF 程序必须满足系统要求的大小,过大的 eBPF 程序不允许被加载进内核
  3. JIT Compilation
    • 作用:Just-In-Time(JIT) 编译用来将通用的 eBPF 字节码翻译成与机器相关的指令集,从而极大加速 BPF 程序的执行
    • 特点:
      • 与解释器相比,可以降低每个指令的开销
      • 减少生成的可执行镜像的大小
      • 针对CISC 指令集(例如 x86),JIT 做了很多特殊优化
  4. BPF Map
    • 定义:驻留在内核空间中高效的键值存储结构,用于实现用户态程序、内核态BPF程序以及其他内核态程序间的通信
    • 作用:
      • 由于安全原因 BPF 程序不允许访问全局变量,可以使用 map 来充当全局变量
      • 通过BPF Tail call实现BPF程序间的跳转,主要是通过map获取其他BPF的程序指针实现的
    • 注意
      • 多对多:一个map可以共享给多个不同的BPF程序,而一个 BPF 程序也可以访问多个不同的map(目前最多64个)
      • 多CPU架构:基于 per-cpu类型,每个CPU在同一个map中的数据被相互隔离,从而实现更高效的查找和聚合操作
      • 解耦:eBPF 程序不能够随意调用内核函数,避免 eBPF 程序与特定的内核版本的绑定
        -在这里插入图片描述
  5. BPF辅助函数
    • 所有的 BPF 辅助函数都是核心内核的一部分,无法通过内核模块(kernel module)来扩展或添加。
    • BPF辅助函数的参数列表和底层系统调用约定相匹配
  6. Tail Calls(尾调用机制)
    • 使用长跳转(long jump)实现的,复用原来的栈帧 ,调用开销小
    • 相同类型的程序才可以尾调用,而且它们还要与 JIT 编译器相匹配
  7. BPF to BPF calls
    • 减小了生成的 BPF 代码大小,因此 对 CPU 指令缓存(instruction cache,i-cache)更友好。
  8. Object Pinning(钉住对象)
    • 定义:用于将eBPF程序的map数据固定在内核指定位置,以便快速访问,从而避免eBPF生命周期结束导致map数据的丢失。

通过下面网站进行完善ebpf基础知识https://developer.aliyun.com/search?k=ebpf&scene=community&page=1


二、eBPF程序

基础

  1. 基本环境
    • eBPF需要Linux 4.9以上,最好5.xx的版本才能较好的支持eBPF特性
  2. eBPF程序由两部分组成
    • 内核态源代码xxx_bpf_kern.c:包含 eBPF 程序的实际逻辑
    • 用户态辅助代码xxx_bpf_user.c:负责加载、运行和与内核BPF程序交互,从而实现用户处理逻辑
  3. eBPF程序的本质
    • BPF目标文件(bpf_program.o)实质上也是一个ELF格式的文件,其中的bpf_prog字段的内容是BPF程序编译后的字节码(byte code))
  4. eBPF程序的执行流程
    • 编写:基于C语言编写成的eBPF程序,如bpf_xxx.c。
    • 编译:通过LLVM编译器将 eBPF 程序编译成eBPF 目标文件(BPF 字节码及符号表等其他元数据),如bpf_function_name.o。
    • 验证:使用内核的验证器对 eBPF 目标文件进行安全性和正确性验证,确保不会对内核造成不良影响。这一步骤会检查程序是否存在非法内存访问、循环是否会导致死循环等问题。
    • JIT 编译(可选):如果内核支持即时编译(JIT),可以将 BPF 字节码编译成本地机器码,以提高执行效率。JIT 编译可以根据具体的硬件架构进行优化,使得程序执行更快。
    • 加载:通过 BPF 的相关库或工具将 BPF 程序加载到内核。加载过程中,会根据程序的类型和目的,将其关联到特定的内核事件或数据结构上。
    • 执行:当满足特定的触发条件时,内核执行 BPF 程序。例如,对于跟踪系统调用的 BPF 程序,当有系统调用发生时,程序会被触发执行。
    • 交互:BPF 程序可以通过 BPF 映射与用户空间程序进行交互。用户空间程序可以读取和修改映射中的数据,从而实现对 BPF 程序的控制和获取运行状态信息。
      在这里插入图片描述
  5. eBPF程序以字节码形式加载到内核的优点
    • 安全性:字节码是一种中间表示形式,方便在加载到内核之前进行验证和审查
    • 跨平台性:字节码是一种与平台无关的格式,可以在不同的架构和操作系统上运行
    • 灵活性:字节码程序可以在无需重新编译内核的情况下,通过动态链接在内核运行时进行加载或卸载
    • 高性能:虽然eBPF程序是以字节码的形式加载到内核,但在执行时可以被即时编译(JIT)成机器码,以获得最佳的性能。
    • 可维护性:字节码格式使得eBPF程序更容易维护和调试。开发者可以使用工具来分析和优化字节码,从而提高程序的效率和可靠性
  6. eBPF的可移植性
    • 原因:Linux内核在快速演进中,依赖于内核数据结构的BPF程序可能因版本更新而出现无效依赖问题
    • 解决
      • BTF(BPF Type Format):提供结构信息以避免对Clang和内核头文件的依赖
      • CO-RE(Compile Once – Run Everywhere):一次编译到处执行,解决了内核数据结构在不同版本差异导致的兼容性问题。使得编译出的BPF字节码是可重定位(relocatable)的,避免了LLVM重新编译的需要。
  7. eBPF程序的开发方式
    • Go/Rust+libbpf:具有高度的灵活性和性能,libbpf是用于创建BPF用户态程序的内核依赖库,GitHub镜像仓库地址
    • Go+cilium/ebpf:可使用高级语言进行开发,并能与容器编排平台的集成。
    • Python+BBC:简单易用,适合新手,但是性能差、灵活性差

eBPF程序生命周期

  1. BPF对象
    • 定义:一个响应系统事件并在内核态和用户态间进行数据共享的内核程序抽象,从而实现流量分析和运行时检测和防止恶意行为。
    • 类型
      • BPF程序(progs):附加到内核并响应Hook事件的安全小程序,如kprobe、tracepoint等。
      • BPF映射(maps):在内核空间中存储键值对的数据结构,用于内核BPF程序和用户态主程序的数据存储和共享
      • 调试信息(debug info):与BPF程序相关的调试信息,如日志打印、函数签名和性能监控等
  2. 用户态程序通过系统调用bpf操作内核态BPF对象
    • 用于bpf_map:进行map的增删改查和创建
    • 用于bpf_prog:进行BPF程序的加载、附加、执行、固定和分离
  3. BPF对象的创建
    • bpf_map的创建:
      • 调用接口:用户态程序通过系统调用bpf(BPF_MAP_CREATE, &attr, sizeof(attr)) 来创建一个bpf_map对象
      • 分配内存:内核会给struct bpf_map对象分配内存,用于存储map的类型、键值和最大条目数等
      • 初始化:设置该对象的引用计数 refcnt=1,表示该对象当前被引用一次
      • 返回值:返回一个文件描述符fd,以供用户态进程对map的进行访问操作
    • bpf_prog的创建
      • 用户空间程序通过系统调用 bpf(BPF_PROG_LOAD, ...) 来加载一个bpf_prog对象
      • 校验BPF:将该BPF对象相关联的每个map的refcnt++,设置该程序本身的 refcnt=1
      • JIT编译:eBPF 字节码被转换为底层机器指令,从而提高了程序的执行效率
      • attach:将机器指令附着在指定的内核Hook点上下文中
      • 返回值:返回一个BPF对象的文件描述符fd
        在这里插入图片描述
  4. BPF对象的关闭(类似cpp智能指针)
    • 基础:BPF对象通过文件描述符(FD)进行索引和访问,通过引用计数器进行生命周期的管理
    • 文件描述符(File Descriptor):用户态程序通过bpf()系统调用来创建eBPF对象后,该调用会返回一个用于索引对应BPF对象文件描述符
    • 引用计数器:
      • 每个BPF对象都有一个引用计数器(ref_cnt),用于追踪对象被引用的次数,从而使多个不同类型能够访问同一个BPF对象
      • BPF对象的引用计数大于0,内核将保持其活动状态。当引用计数等于零时,内核会释放相关资源
    • 计数原理
      • 初始化为1:当对象被创建时,其引用计数器会被初始化为1。
      • 访问则+1:其他进程通过FD访问BPF对象时,该对象的引用计数器会+1
      • 访问关闭则-1:若对BPF对象的访问关闭 ,则相应的引用计数器会-1。
      • 为0则释放:当引用计数器为0时,内核会在经过grace period(宽限期)后释放对象所占用的内存
    • 注意:若引用BPF对象的进程崩溃内核会主动清理进行该进程相关资源,其中包括了对于其相关联的引用计数器-1操作
  5. BPF对象attach到的Hook类型?
    • 全局类型Global:通常与整个系统活动有关,是内核定义的通用跟踪点
      • Tracepoints:开发者预先静态编写在常用系统调用入口或出口的跟踪点。
      • Kprobes:在动态插入任意内核函数的入口或出口,性能较差且可能影响内核稳定性
    • 本地类型Local:通常与特定的网络接口、文件描述符或进程相关
      • cgroup_skb:用于特定 cgroup 范围内的网络流量管理和分析
      • XDP:在数据包到达网络驱动并进入内核网络栈之前触发 BPF 程序,用于快速处理网络数据包。
      • TC Classifier:在网络流量的入口和出口点进行流量分类和过滤,可以用于实现防火墙规则、流量整形等。
      • Socket Filter:在 socket 级别对网络流量进行过滤,可以用于捕获或修改经过特定 socket 的数据包。
  6. BPF对象的如何实现持久化运行
    • BPF文件系统(BPFFS):BPF对象可以被“固定”(pin)到BPF文件系统中,这样它们就独立于创建它们的用户空间进程。通过将BPF对象固定到BPFFS中的某个路径,可以增加其引用计数,从而使得BPF对象在用户空间进程退出后仍然保持活动状态。当需要解除固定时,只需从BPFFS中删除相应的文件,内核会相应地减少引用计数。
    • Attach BPF程序到全局挂钩点:某些BPF程序可以附加到全局挂钩点,如XDP、tc clsact、cgroup-based hooks等。这些全局类型的BPF对象即使在创建它们的用户空间进程退出后,仍然可以保持活动状态,因为它们被设计为全局可访问的。例如,一个XDP程序可以附加到网络设备的ingress或egress qdisc,并且会一直处理数据包,直到显式地从qdisc上删除。
  7. 特点:
    • 上下文依赖:eBPF程序是在特定的内核事件触发时执行的,例如当一个网络数据包到达时,或者一个系统调用被执行时。这些事件为eBPF程序提供了执行的上下文。
    • 加载和附加:eBPF程序通常由用户空间程序加载和附加到内核的特定挂钩点上。这个用户空间程序负责设置eBPF程序的执行环境,而不是通过main函数来启动。
    • 生命周期管理:eBPF程序的生命周期是由加载它们的用户空间程序管理的。用户空间程序可以控制何时加载、卸载eBPF程序,以及何时将它们附加到内核的特定事件上。
    • 沙箱环境:为了安全起见,eBPF程序在内核中运行在一个受限的沙箱环境中。这意味着它们不能像普通用户程序那样执行任意操作,而是只能执行内核允许的操作。
    • 与内核交互:eBPF程序通过内核提供的BPF系统调用来与内核交互,例如创建BPF Maps、加载eBPF程序、附加eBPF程序到挂钩点等。
    • 事件驱动:eBPF程序是事件驱动的,它们响应内核中的事件,而不是通过一个主循环来驱动程序的执行。
  8. eBPF程序基本结构
    • 基础库文件:
      • <linux/bpf.h>:eBPF编程的必须头文件,定义了eBPF相关的数据结构和函数原型。
      • <bpf/bpf_helpers.h>:用于简化eBPF程序开发的辅助功能函数,例如用于内存映射、打印日志等。
    • 许可协议类型:当eBPF程序的许可证与内核模块的许可证兼容时,才能加载和运行该程序。
    • eBPF程序类型及代码:
      • SEC宏:指定eBPF程序的类型,每种类型对应不同内核挂载点(eBPF程序所执行的上下文位置)
      • BPF中的函数:可以指定多个SEC类型函数,和辅助功能函数
    // 1.eBPF必须的库文件
    #include <linux/bpf.h>			
    #include <bpf/bpf_helpers.h>	
    // 2. 许可协议类型
    char _license[] SEC("license") = "GPL";
    // 3. eBPF程序类型及代码
    SEC("socket")
    int bpf_prog(struct __sk_buff *skb) {bpf_trace_printk("Hello, World!\n");return 0;
    }
    

三、SEC程序类型(未完待续)

SEC概述

  1. SEC关键字
    • 概述:是一个宏定义,定义了BPF的程序类型,是 “Section” 的缩写
    • 作用
      • 对 BPF 程序中的函数或变量进行分组和分类,以便在加载和执行时进行控制。
      • 不同的 SEC 关键字可将 BPF 程序挂钩到特定的内核机制上,实现特定的功能。
    • 类型
      • SEC(“kprobe/”):挂钩到内核的 kprobe,在内核函数入口点执行自定义 BPF 程序
      • SEC(“kretprobe/”):挂钩到内核的 kretprobe,在内核函数返回点执行自定义 BPF 程序。
      • SEC(“tracepoint/”):挂钩到内核的 tracepoint,跟踪内核预定义事件。
      • SEC(“perf_event/”):挂钩到内核性能事件,测量和跟踪系统性能指标。
      • SEC(“tracepoint”):指定函数为跟踪点,在 Linux 内核跟踪事件中插入代码。
      • SEC(“maps”):指定变量为 BPF 映射,用于在 BPF 程序和用户空间之间共享数据。
      • SEC(“license”):指定变量为 BPF 程序许可证,说明使用权限和限制。
      • SEC(“xdp_sock”):指定 BPF 程序类型为 XDP 套接字型,挂钩到 Linux 内核的 XDP 处理路径,从而在在网络数据包进入内核协议栈之前进行处理

XDP类型程序

  1. XDP(eXpress Data Path)
    • 定义: Linux 内核中的一种高性能可编程数据路径,专为网络接口级的数据包处理而设计。
    • 作用:
      • 高性能:eBPF 程序在网络设备驱动程序的软中断上下文中执行,从而实现高性能的数据包处理
      • 绕过内核:能够在数据包到达内核网络栈前进行拦截并处理,相比 iptables等有更大的灵活性和细粒度控制。
      • 安全性:eBPF 虚拟机确保用户定义的 XDP 程序是被隔离的,不会对内核造成不稳定影响。
    • 应用实践
      • Cilium :云原生环境(尤其是 Kubernetes)设计的开源网络、安全和可观测性工具
      • Katran:是由 Facebook 开发的负载均衡器,优化了高可扩展性和性能,使用 XDP 处理数据包转发,开销极小。
      • Cloudflare:实现了基于 XDP 的实时 DDoS 缓解。通过在 NIC 级别处理数据包,过滤掉攻击流量,最小化 DDoS 攻击的影响。
  2. cgroup_skb
    • 定义:Linux内核中用于控制和限制网络数据包传输的机制,与控制组(cgroup)相关。
    • 作用:
      • 流量控制:可以限制特定控制组的网络流量。
      • 资源分配:确保关键任务的网络资源不被非关键任务过度占用。
    • 应用实践
      • 容器化环境:在Docker或Kubernetes中,用于限制容器的网络带宽和数据包传输速率。
  3. fentry
    • 定义:Linux内核中的一个函数入口点,用于在函数执行前进行拦截。
    • 作用:
      • 函数跟踪:允许在函数执行前获取调用信息。
      • 性能分析:用于性能分析工具,如perf,以获取函数调用的详细情况。
    • 应用实践
      • 性能监控:在系统性能调优中,用于监控关键函数的调用次数和时间。
  4. kprobe
    • 定义:Linux内核中用于动态跟踪内核函数执行的工具。
    • 作用:
      • 函数监控:允许监控内核函数的执行。
      • 错误诊断:用于内核错误和性能问题的诊断。
    • 应用实践
      • 内核调试:在开发和测试阶段,用于调试内核代码。
  5. kprobe_percpu
    • 定义:针对每个CPU核心的kprobe,用于在多核系统中进行函数跟踪。
    • 作用:
      • 多核优化:确保每个核心的函数调用都能被跟踪。
      • 性能分析:用于分析多核系统中的函数调用性能。
    • 应用实践
      • 高并发系统:在需要精确监控每个核心性能的系统中使用。
  6. kprobepin
    • 定义:一种特殊的kprobe,用于在内核函数执行时进行固定位置的跟踪。
    • 作用:
      • 精确跟踪:允许在内核函数的特定位置进行跟踪。
      • 性能分析:用于分析特定函数调用的性能影响。
    • 应用实践
      • 性能调优:在需要精确控制跟踪点的位置时使用。
  7. ringbuffer
    • 定义:一种循环缓冲区,用于在生产者和消费者之间传递数据。
    • 作用:
      • 数据传递:用于在不同组件之间传递数据。
      • 性能优化:通过减少锁的使用,提高数据传递的效率。
    • 应用实践
      • 日志系统:用于内核日志的收集和传输。
  8. tracepoint in_c
    • 定义:跟踪点,用于在内核中跟踪特定事件的发生。
    • 作用:
      • 事件监控:允许监控内核中的特定事件。
      • 性能分析:用于分析内核事件对性能的影响。
    • 应用实践
      • 内核调试:在开发和测试阶段,用于调试内核事件。
  9. uretprobe
    • 定义:用户态返回探针,用于跟踪用户态函数的返回路径。
    • 作用:
      • 函数监控:允许监控用户态函数的返回。
      • 性能分析:用于分析用户态函数的性能。
    • 应用实践
      • 用户态程序调试:在开发和测试用户态程序时使用。

用户与内核的交互

  1. BPF MAP为BPF程序的内核态与用户态提供了一个双向数据交换的通道。
  2. 由于bpf map存储在内核分配的内存空间,处于内核态,可以被运行于在内核态的多个BPF程序所共享,同样可以作为多个BPF程序交换和共享数据的机制。
  3. MAP就是BPF中代表抽象数据容器(abstract data container)的一个概念
  4. 支持多种MAP类型,具体在 【libbpf库中的bpf头文件中】
  5. BPF_MAP_TYPE_HASH类型是BPF支持的第一种MAP数据结构,这个类型可以理解为我们日常接触的hash映射表,通过键值对的形式索引数据
  6. bpf其实是一个“富调用”,即不止能干一件事,通过cmd传入的值不同,它可以围绕BPF完成很多事情。最主要的功能是加载bpf程序(cmd=BPF_PROG_LOAD),其次是围绕MAP的一系列操作,包括创建MAP(cmd=BPF_MAP_CREATE)、MAP元素查询(cmd=BPF_MAP_LOOKUP_ELEM)、MAP元素值更新(cmd=BPF_MAP_UPDATE_ELEM)等。当cmd=BPF_MAP_CREATE时,即bpf执行创建MAP的操作后,bpf调用会返回一个文件描述符fd,通过该fd后续可以操作新创建的MAP。通过fd访问map,这个很unix!
  7. MAP本质上也是由bpf系统调用创建的,bpf程序只需要声明map的key、value、type等组成信息即可。用户态可以通过bpf系统调用返回的fd操作map,libbpf和cilium/ebpf等封装了对fd的操作,这样简化了API的使用。

🚩点此跳转到首行↩︎

参考博客

  1. cilium ebpf:使用go开发ebpf程序
  2. Getting Started with eBPF in Go
  3. x大规模微服务利器:eBPF + Kubernetes 介绍
  4. xx cilium ebpf:使用go开发ebpf程序
  5. xxxxxx eBPF 核心技术与实战
  6. bfp笔记
  7. eBPF 入门实践教程二十一: 使用 XDP 进行可编程数据包处理
  8. 聊聊对 BPF 程序至关重要的 vmlinux.h 文件
  9. !!!!待查看的ebpf程序编译执行方式
  10. 待学习
  11. 深入理解 ebpf loader

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python获取当前鼠标位置的RGB值

效果 依赖 pip install Pillow pyautoguisudo apt install gnome-screenshot代码 import pyautogui import timedef get_rgb_at_mouse():try:while True:# 获取当前鼠标的位置x, y pyautogui.position()# 截取当前屏幕图像screenshot pyautogui.screenshot()# 获取鼠标位置…

小O睡眠省电调研

摘要 AI 预测睡眠 断网 杀应用为主的策略 UI 睡眠识别 AI 识别 将亮灭屏、音频、上传下载、运动状态数据存到xml中&#xff0c;供预测分析 睡眠策略 OPPO 睡眠省电 1. sOSysNetControlManagerNewInstance&#xff1a;断网&#xff08;wifi\mobiledata&#xff09;2. S…

【D3.js in Action 3 精译_036】4.1 DIY 实战:在 Observable 平台实现 D3折线图坐标轴的绘制

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

百度统计提示:为了满足法律法规最新规定和要求,您的网站由于存在合规风险将被暂停使用百度统计服务

今天打开百度统计后看到提示&#xff1a; 为了满足法律法规及政府监管的最新规定和要求&#xff0c;保护广大网民的合法权益&#xff0c;您的网站由于存在合规风险将被暂停使用百度统计服务。 请您在10日内完成整改&#xff0c;否则将删除违规站点及数据&#xff0c;有问题可发…

使用dotnet-counters和dotnet-dump 分析.NET Core 项目内存占用问题

在.NET Core 项目部署后&#xff0c;我们往往会遇到内存占用越来越高的问题&#xff0c;但是由于项目部署在Linux上&#xff0c;因此无法使用VS的远程调试工具来排查内存占用问题。那么这篇文章我们大家一起来学习一下如何排查内存占用问题。 首先&#xff0c;我们来看一下应用…

手机数据恢复技巧:适用于手机的恢复应用程序

发现自己意外删除了 Android 设备上的照片&#xff0c;这让人很痛苦。这些照片可能是值得纪念的文件&#xff0c;会让您想起一些难忘的回忆。删除它们后&#xff0c;您知道如何恢复它们。在这种情况下&#xff0c;您需要使用 Android 的照片恢复应用程序。 无论您需要直接从 A…

【控制系统】深入理解反步控制(Backstepping) | 反步法控制器原理与应用实例解析(附Matlab/Simulink仿真实现)

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

使用Airtest自动化某云音乐爬取歌曲名称

简介 本文将介绍如何使用Airtest自动化工具来模拟用户操作&#xff0c;从某云音乐中爬取与特定关键词相关的歌曲名称。我们将以搜索“文字”相关的歌曲为例&#xff0c;并将结果保存到本地文件。 准备工作 安装Airtest并配置好Android设备或模拟器。确保你的设备上已安装某云…

【独家:AI编程助手Cursor如何revolutionize Java设计模式学习】

【独家:AI编程助手Cursor如何revolutionize Java设计模式学习】 导语 在Java高级编程的世界里,设计模式是每个开发者必须掌握的利器。但是,如何快速理解并灵活运用这些模式呢?让我们一起探索如何借助AI编程助手Cursor,轻松掌握设计模式,提升Java编程技能! 正文 设计模式:J…

QUIC(Quick UDP Internet Connections)与 RTMP(Real Time Messaging Protocol)

QUIC&#xff08;Quick UDP Internet Connections&#xff09;和 RTMP&#xff08;Real Time Messaging Protocol&#xff09;是两种不同的网络传输协议&#xff0c;它们在一些方面有不同的特点和应用场景。 QUIC 协议 特点 基于 UDP&#xff1a;QUIC 建立在 UDP 之上&#xff…

探索 Jupyter 核心:nbformat 库的神秘力量

文章目录 探索 Jupyter 核心&#xff1a;nbformat 库的神秘力量1. 背景介绍&#xff1a;为何选择 nbformat&#xff1f;2. nbformat 是什么&#xff1f;3. 如何安装 nbformat&#xff1f;4. 简单的库函数使用方法4.1 读取 Notebook 文件4.2 修改 Notebook 中的单元格4.3 添加 M…

灵当CRM index.php 任意文件上传漏洞复现

0x01 产品描述&#xff1a; 灵当CRM是一款专为中小企业量身定制的智能客户关系管理工具&#xff0c;由上海灵当信息科技有限公司开发和运营。该系统广泛应用于多个行业&#xff0c;包括金融、教育、医疗、IT服务及房地产等领域&#xff0c;旨在满足企业对客户个性化管理的需求&…

【2024版】sql-liabs靶场前十关解题过程和思路----适合入门小白

在你们看到这个靶场之前&#xff0c;你们可以先去听一下课&#xff0c;然后再来做这个靶场你们的感悟就会比较深&#xff0c;当你听过课再来做就不会觉得这么懵了&#xff0c;重庆橙子科技-sql注入&#xff0c;我之前学习是听的他的课&#xff0c;我觉得是全网讲的最好的一个师…

vue2使用pdfjs-dist实现pdf预览(iframe形式,不修改pdfjs原来的ui和控件,dom层可以用display去掉一部分组件)

前情提要 在一开始要使用pdf预览的时候&#xff0c;第一次选的是vue-pdf&#xff0c;但是vue-pdf支持的功能太少&#xff0c;缺少了项目中需要的一项-复制粘贴功能 之后我一顿搜搜搜&#xff0c;最终貌似只有pdfjs能用 但是网上支持text-layer的貌似都是用的2.09那个版本。 使…

MySQL同步到ES的方案选型

文章目录 1. 同步双写优点缺点实现方式 2. 异步双写优点缺点实现方式 3. 另起应用 SQL 查询写入优点缺点实现方式 4. Binlog 实时同步优点缺点实现方式 5. 应用场景 本文参考: https://www.bilibili.com/video/BV13hvZeaErr/?vd_sourceb7e4d17fd13ffa91c4da6d37c08a6c7c 最近在…

【题解】—— LeetCode一周小结42

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结41 14.鸡蛋掉落 题目链接&#xff1a;887. 鸡蛋掉落 给你 k 枚…

c++迷宫游戏

1、问题描述 程序开始运行时显示一个迷宫地图&#xff0c;迷宫中央有一只老鼠&#xff0c;迷宫的右下方有一个粮仓。游戏的任务是使用键盘上的方向健操纵老鼠在规定的时间内走到粮仓处。 基本要求: 老鼠形象可以辨认,可用键盘操纵老鼠上下左右移动&#xff1b;迷宫的墙足够结…

Springboot指定扫描路径

方式一&#xff1a;通过在启动类的SpringbootApplication中指定包扫描或类扫描 指定需要扫描的包 scanBasePackages{"待扫描包1","待扫描包2", . . . ," "} 指定需要扫描的类 scanBasePackageClasses{类1.class,类2.class,...} 方式二&#xff…

C语言函数实现:深入理解strcpy

文章目录 一、strcpy函数的基本用法二、strcpy函数的实现原理三、strcpy函数的应用场景四、strcpy函数的安全性问题五、结论 C语言函数实现&#xff1a;深入理解strcpy 在C语言编程中&#xff0c;字符串处理是一项基础且重要的任务。 strcpy函数作为C标准库中的一个基本函数&a…

CDC变更数据捕捉技术是什么?和ETL有什么不同?

一、什么是CDC技术? 变更数据捕获&#xff08;Change Data Capture&#xff0c;简称 CDC&#xff09;是一种用于识别和跟踪数据源中发生变化的数据的技术。 工作原理&#xff1a; 1.监测数据源&#xff1a;CDC 工具会持续监测指定的数据源&#xff0c;如数据库表、文件系统…