Cilium + ebpf 系列文章-什么是ebpf?(一)

前言:

这篇非常非常干,很有可能读不懂。

这里非常非常推荐,建议使用Cilium官网的lab来辅助学习!!!
Resources Library - IsovalentExplore Isovalent's Resource Library, your one-stop destination for insightful videos, case studies, blogs, books, labs, analyst reports, and more.https://isovalent.com/resource-library/?solution=networking
一、为什么需要新的ebpf技术?

在对吞吐量、延迟敏感的业务生产场景中,容器网络的类型选择显的格外重要:

Docker Networking Tutorial(Mac-vlan vs Bridge vs overlay)-CSDN博客文章浏览阅读147次。一、We Create a container be a Server.二、We Create a container be a Client.三、Them link at a Bridge.四、 Do test.一、Test-tools。二、Test-step。https://blog.csdn.net/weixin_46510209/article/details/142424382?spm=1001.2014.3001.5501 上面为我编写的博客,来对比不同类型网络速率对比。

直接说结论:

Mac_vlan > Bridge > overlay

Mac_vlan 性能为Bridge的3倍、8倍于overlay网络。

约接近物理网络越快,只要过了任何虚拟NIC或者隧道,性能都会大大折扣。

但越接近物理网络则会凸显物理网络的弊端,10多年没有更新的网络协议栈,很多业务场景大大受限制。

那么有没有一种技术,即可以实现高性能、又可以封装隧道、又可以监控系统调用,并且支持k8s.

ebpf!

二、什么是ebpf?

ebpf(扩展的伯克利数据包过滤器)

这是在运行Linux 5.x+内核的顶级子程序。

他运行用户在 Linux用户空间对在运行在内核空间对ebpf程序进行编程.

实现网络数据包处理、性能监控、故障排除和安全策略等多种任务。

ebpf之所以可以实现上述的能力,是因为ebpf支持多种类型挂载点(即将你编写的ebpf程序挂载到相应类型的能力的挂载点上)。

比如网络(XDP),系统调用(内核函数)(Kprobe 和 Kretprobe),系统调用(用户空间程序)Uprobe 和 Uretprobe等等。

三、ebpf的工作原理

编写 eBPF 程序 编译 eBPF 程序 加载 eBPF 程序 运行eBPF 程序 收集和分析eBPF 程序

别慌,完事都可以用Python.

BCC库,提供了一个Python接口。意思就是虽然ebpf是C语言写的,但是你可以用Python的代码机构来实现。

接下来是代码了:

这里为了方便你能继续读懂,必须要补充和复习一下系统调用的碎片知识。

1、用户空间是无能直接操作、编程内核函数的!

2、用户空间的所有操作都是由很多很多系统调用 来具体实现的。比如:你cat 、ls 一个文件,那么背后就是open,write,read,close 等系统调用来实现!

简单的说系统调用是用户空间于内核空间访问的通道,他是一个标准的接口,一个抽象层。

3、当你执行l s操作时,会调用open的系统调用,然后open的系统调用具体是使用do_sys_open这个内核函数来具体执行!

4、接下来代码中你看不到系统调用open,但你能看到do_sys_open这个内核函数.因为ebpf是运行在内核层!

下面为例子,来方便理解:

这个 Python 脚本使用 BCC (BPF Compiler Collection) 来编写和加载一个简单的 eBPF 程序,该程序在来追踪每次文件打开操作,并记录文件名。

open 系统调用用于打开文件。

Linux命令: ls cat touch vim 都会调用open系统调用。

do_sys_open:这个内核函数对应系统调用的open

复制代码
#!/usr/bin/python3
from bcc import BPF

program = r"""
#include <uapi/linux/ptrace.h>
#include <linux/fs.h>

BPF_HASH(counter, u64);

int trace_open(struct pt_regs *ctx, const char __user *filename, int flags) {
    u64 uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
    u64 *count = counter.lookup(&uid);
    u64 zero = 0;

    if (count) {
        (*count)++;
    } else {
        counter.update(&uid, &zero);
    }

    bpf_trace_printk("File opened: %s\\n", filename);
    return 0;
}
"""

b = BPF(text=program)
b.attach_kprobe(event="do_sys_open", fn_name="trace_open")

print("Tracing file open... Ctrl-C to end.")
b.trace_print()

**上面的代码的简单解释:

##编写ebpf程序:这一块语言是C语言,但是不用你自己写,你可以用ai帮助你完成,你只需要告诉他你想做什么。

复制代码
BPF_HASH(counter, u64);

int trace_open(struct pt_regs *ctx, const char __user *filename, int flags) {
    u64 uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
    u64 *count = counter.lookup(&uid);
    u64 zero = 0;

    if (count) {
        (*count)++;
    } else {
        counter.update(&uid, &zero);
    }

    bpf_trace_printk("File opened: %s\\n", filename);
    return 0;
}
"""

##加载 eBPF 程序并附加到 open 系统调用:这一段代码是Python。

复制代码
b = BPF(text=program)
b.attach_kprobe(event="do_sys_open", fn_name="trace_open")

将上面的代码放置在一个脚hello.py的文件中,执行 eBPF 程序(请提前安装BCC工具集)

复制代码
./hello.py

收集和分析数据

在另一个终端中执行一些命令(如 ls touch vim等等都可以),触发 open系统调用.

下面为演示效果:

验证成功加载:

复制代码
bpftool prog show

##上面的实验是为了证明你在用户空间编写的ebpf程序可以在内核中运行,并且监控系统调用和内核函数。

相关推荐
赖small强42 分钟前
【Linux 网络基础】HTTPS 技术文档
linux·网络·https·tls
写代码的学渣1 小时前
ubuntu 22.04 新装的系统 xshell 连不上
linux·运维·ubuntu
序属秋秋秋2 小时前
《Linux系统编程之进程环境》【环境变量】
linux·运维·服务器·c语言·c++·操作系统·系统编程
云计算练习生2 小时前
linux shell编程实战 10 Git工具详解与运维场景实战
linux·运维·git
虚伪的空想家5 小时前
KVM的ubuntu虚机如何关闭安全启动
linux·安全·ubuntu
t1987512810 小时前
在Ubuntu 22.04系统上安装libimobiledevice
linux·运维·ubuntu
skywalk816310 小时前
linux安装Code Server 以便Comate IDE和CodeBuddy等都可以远程连上来
linux·运维·服务器·vscode·comate
晚风吹人醒.11 小时前
缓存中间件Redis安装及功能演示、企业案例
linux·数据库·redis·ubuntu·缓存·中间件
Hard but lovely11 小时前
linux: pthread库的使用和理解
linux
这儿有一堆花13 小时前
Kali Linux:探测存活到挖掘漏洞
linux·运维·服务器