【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

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

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

相关文章

【JavaEE初阶】深入理解TCP协议中的封装分用以及UDP和TCP在网络编程的区别

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP/UDP协议的原理理解~~~ &#x1f308;上期博客在这里&#xff1a;【JavaEE初阶】入门视角-网络原理的基础理论的了解-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; …

前端算法:时间复杂度和空间复杂度

一、算法的重要性 1.为什么前端开发需要学习算法&#xff1f; 学习算法可以帮助培养逻辑思维能力&#xff0c;在面对复杂的问题时&#xff0c;能够系统性地分析问题、分解步骤并成功找到的正确的解决方案。 掌握基本的排序、查找算法和时间复杂度分析可以帮助编写更高效的代码…

移动网络知识

一、3G网络 TD-SCDMA&#xff08;时分同步码分多址接入&#xff09;、WCDMA&#xff08;宽带码分多址&#xff09;和CDMA2000三种不同的3G移动通信标准 TD-SCDMA&#xff08;时分同步码分多址接入&#xff09;&#xff1a;中国自主开发的一种3G标准主要用于国内市场&#xff…

零跑“半价平替”杀疯了,没钱别硬上问界理想

文 | AUTO芯球 作者 | 雷慢 你绝对想不到&#xff0c; 现在造车新势力的周销量榜第二名已经是零跑了 来看啊&#xff0c;十月第2周&#xff0c; 零跑周销量8700量&#xff0c;已经超过问界的7100辆&#xff0c; 放以前&#xff0c;问界也是周销量9000台左右的主&#xff0…

RHCE——时间服务器

NTP——网络时间协议&#xff0c;通过udp123端口进行网络时钟同步 chronyd chronyd——一个开源自由的网络时间协议 NTP 的客户端和服务器软件。能让计算机保持系统时钟与时钟服务器&#xff08;NTP&#xff09;同步&#xff0c;从而使计算机保持精确的时间。 Chrony由两个程…

大数据查询引擎之Tez

Apache Tez 是一个用于大数据处理的分布式计算框架&#xff0c;旨在提高 Hadoop 的 MapReduce 计算引擎的效率和性能。它是一个面向 DAG&#xff08;有向无环图&#xff09;任务执行的框架&#xff0c;主要用于大规模数据处理场景中&#xff0c;特别是在 Apache Hadoop 生态系统…

开放式耳机好不好用?盘点开放式蓝牙耳机排行榜前五名

​开放式耳机是好用的&#xff0c;目前非常流行&#xff0c;它们以时尚、美观和舒适著称&#xff0c;迅速赢得了众多用户的喜爱&#xff0c;成为了耳机市场的新宠。与传统的入耳式耳机相比&#xff0c;开放式耳机佩戴更稳固&#xff0c;对耳朵也更为温和。尽管有些人认为它们价…

C++在vscode中的code runner配置/环境配置

C在vscode中快捷运行&#xff08;code runner&#xff09; 一、配置tasks.json 在vscode中创建文件夹或打开文件夹&#xff0c;会发现文件夹下多了一个.vscode文件夹&#xff0c;在该文件夹下创建tasks.json文件&#xff0c;并添加一下内容 {"version": "2.0…

单周期处理器设计思路

目录 单周期处理器设计思路加法器的优化行波进位加法器&#xff08;RCA&#xff09;先行进位加法器&#xff08;CLA&#xff09;两种加法器的对比CLA的再优化可以用加法器实现的其他操作 编写可维护的RTL代码 单周期处理器设计思路 加法器的优化 &#xff08;用综合器综合*/等…

如何修改MAC地址破解网络无线网络限制-担心别人蹭网,路由器设置MAC地址过滤,限定了能访问无线网络的网卡地址-供大家学习参考

路由器都设置了MAC地址过滤&#xff0c;也就是限定了能访问无线网络的网卡的MAC地址。因为无线路由器不一定由自己控制&#xff0c;所以当更换了笔记本或者更换了无线网卡的时候&#xff0c;也许就上不了网了。我们可以修改网卡的MAC地址实现上网。 下载&#xff1a;https://do…

R01 vue+springboot 高考志愿推荐AI问答大数据平台

可以查看本文系统对应的视频讲解&#xff1a; vuespringboot 高考推荐AI问答志愿推荐大数据 R01 带增删改查、大屏、支持爬虫 1 系统背景 近年来&#xff0c;高考作为中国教育体系中最重要的考试之一&#xff0c;承载了无数考生和家庭的梦想。随着信息技术的迅猛发展&#xff…

Linux shell脚本文件通过shc工具加密,生成静态链接可执行文件

要使用 shc 工具对 Linux shell 脚本进行加密并生成静态链接的可执行文件&#xff0c;你可以按照以下步骤操作&#xff1a; 安装 shc 工具&#xff1a; 如果你的系统中还没有安装 shc&#xff0c;可以通过包管理器安装&#xff0c;例如在 Ubuntu 系统中&#xff0c;可以使用以下…

YOLOv11模型改进-模块-引入空间池化模块StripPooling 解决遮挡、小目标

本篇文章将介绍一个新的改进机制——空间池化模块StripPooling&#xff0c;并阐述如何将其应用于YOLOv11中&#xff0c;显著提升模型性能。首先&#xff0c;我们将解析StripPooling的工作原理&#xff0c;SP模块通过条带池化在水平和垂直方向上捕捉长距离依赖关系&#xff0c;增…

如何在线查看近8年的建筑覆盖变化

我们在《谷歌发布建筑数据&#xff0c;高度误差达惊人的1.5米》一文中介绍了谷歌2.5D建筑数据用途、制作方法以及数据下载方式。 现在我们演示下如何在线查看近8年的建筑物覆盖、建筑物质心和建筑物高度的变化。 历史建筑覆盖在线查看 2.5D建筑演变数据集包含2016年至2023年…

碰一碰支付怎么推广的?小白也能看懂的教程来了!

作为支付宝和微信全面力推的一个项目&#xff0c;碰一碰支付的热度可谓是节节攀升&#xff0c;连带着与之相关的话题&#xff0c;如碰一碰支付是什么和碰一碰支付怎么推广的等也因此成为了人们关注的焦点。那么&#xff0c;本期&#xff0c;我们就来详细地解答一下这两个问题。…

2024台州赛CTFwp

备注&#xff1a; 解题过程中&#xff0c;关键步骤不可省略&#xff0c;不可含糊其辞、一笔带过。解题过程中如是自己编写的脚本&#xff0c;不可省略&#xff0c;不可截图&#xff08;代码字体可以调小&#xff1b;而如果代码太长&#xff0c;则贴关键代码函数&#xff09;。…

I.MX6U 字符设备驱动开发指南

目录 一、引言 二、字符设备驱动的基本概念 1.字符设备的定义 2.字符设备驱动的作用 三、I.MX6U 字符设备驱动开发步骤 1.确定设备信息 2.编写设备驱动代码 3.编译和加载驱动 4.测试设备驱动 四、实例分析 1.确定设备信息 2.编写设备驱动代码 3.编译和加载驱动 4.…

iOS 回到主线程刷新UI

在iOS 里面,项目打开就会运行一个主线程,所有的UI都在主线程里进行.其他网络请求或者耗时操作理论上也可以在主线程运行,但是如果太耗时,那么就会影响主线程其他UI.所以需要开字线程来进行耗时操作,子线程进行完耗时操作之后,如果项目需求有需要刷新UI,或者改变UI,一定得回到主…

音频/视频提取器:Python和moviepy实现

在这篇博客中,我们将深入探讨一个使用Python和wxPython构建的音频/视频提取器应用程序。这个应用程序允许用户从视频文件中提取音频,或者从音频文件中截取特定时间段。让我们逐步分析这个程序的功能和实现。 C:\pythoncode\new\MP3towav.py 全部代码 import wx import os imp…

「iOS」——YYModel学习

iOS学习 前言优势使用方法简单的Model与JSON互转多样化的数据类型交换容器类数据交换 model中包含其他model白名单与黑名单 总结 前言 YYModel是YYKit的高效组件之一&#xff0c;在实际场景中的非常实用&#xff0c;在项目中使用MVC架构时&#xff0c;可以简化数据处理。在性能…