在云原生平台上使用eBPF程序

简介: 【2月更文挑战第3天】

我们可以看到 eBPF 在云原生环境中进行黑盒调试的威力。不过,如何让 eBPF 程序在云原生平台上更好地被使用呢?要从两个维度来考虑,一个是纵向的,另一个是横向的。


1、纵向的深入

简单来说,就是需要不断地加深对内核的理解。


在编写 eBPF 代码的过程中,你需要运用到 Linux 内核的基本实现原理。


比如,如果我们需要追踪一个内核函数,就会发现有好几种 eBPF program 的类型可以选择,每一种 eBPF program 的输入参数还都是不一样的。如果我们需要追踪内核函数 __set_task_comm() ,想看看哪个进程的进程名字被修改了,可以用 kprobe 的方式来追踪它,也可以用 tracepoint 的方式,还能通过 raw_tracepoint 的方式来追踪。


在使用 kprobe eBPF program 的时候,它的输入参数是 struct pt_regs;在使用 tracepoint eBPF prgoram 的时候,它的输入参数是一个自定义的结构 struct task_rename;而到使用 raw tracepoint 方式的时候,输入参数又变成了 struct bpf_raw_tracepoint_args。不知道你在使用 eBPF program 的时候,有没有想过这个问题:为什么这些参数是不一样的?

void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
{
        task_lock(tsk);
        trace_task_rename(tsk, buf);
        strlcpy(tsk->comm, buf, sizeof(tsk->comm));
        task_unlock(tsk);
        perf_event_comm(tsk, exec);
}
SEC("kprobe/__set_task_comm")
int prog(struct pt_regs *ctx)
{
  return 0;
} 
 
/* from /sys/kernel/debug/tracing/events/task/task_rename/format */
struct task_rename {
__u64 pad;
__u32 pid;
char oldcomm[16];
char newcomm[16];
__u16 oom_score_adj;
};
SEC("tracepoint/task/task_rename")
int prog(struct task_rename *ctx)
{
return 0;
}
 
 
SEC("raw_tracepoint/task_rename")
int prog(struct bpf_raw_tracepoint_args *ctx)
{
return 0;
}

这个问题的答案,其实还是要从内核中 kprobe、tracepoint 等内核追踪技术里得到。比如 kprobe ,是通过把当前地址上的指令替换成 int3 中断指令来实现的。而 Linux 内核会在中断发生的时候,把当前各个寄存器的内容写入到栈内存中,而结构 pt_regs 就是用来描述这块栈内存里的内容的。因此,kprobe eBPF program 的输出参数就是 struct pt_regs,根据 Linux ABI,我们就可以知道,被追踪函数的第一个参数的值可以从 pt_regs->di 里得到了。


对于每一个 tracepoint,它都是内核中的一个特别的函数。比如上面例子中的函数 trace_task_rename(), 函数的实现是通过 tracepoint 的一个固定模板(宏)定义的。通过 bpf tracepoint 的 commit,我们看到,在 tracepoint 被调用的时候,TP_STRUCT__entry 里的变量会被赋值,tracepoint eBPF program 的输入参数就是每个 tracepoint 中 TP_STRUCT__entry 的内容。tracepoint 宏定义如下所示:

TRACE_EVENT(task_rename,
 
        TP_PROTO(struct task_struct *task, const char *comm),
 
        TP_ARGS(task, comm),
 
        TP_STRUCT__entry(
                __field(        pid_t,  pid)
                __array(        char, oldcomm,  TASK_COMM_LEN)
                __array(        char, newcomm,  TASK_COMM_LEN)
                __field(        short,  oom_score_adj)
        ),
 
        TP_fast_assign(
                __entry->pid = task->pid;
                memcpy(entry->oldcomm, task->comm, TASK_COMM_LEN);
                strlcpy(entry->newcomm, comm, TASK_COMM_LEN);
                __entry->oom_score_adj = task->signal->oom_score_adj;
        ),
 
        TP_printk("pid=%d oldcomm=%s newcomm=%s oom_score_adj=%hd",
                __entry->pid, __entry->oldcomm,
                __entry->newcomm, __entry->oom_score_adj)
);

最后看 raw tracepoint。这是 eBPF 引入的 raw tracepoint program ,其目的就是访问 tracepoint 定义里的 TP_PROTO 参数。比如在我们当前的这个例子里,用了 raw tracepoint 就可以访问到 task_struct *task 参数了,可以得到 task_struct 里的所有信息,而不是 TP_STRUCT__entry 里的那几个变量了。


上面的几个例子说明,编写 eBPF 程序首先需要理解 Linux 内核的追踪机制的实现。而在使用 eBPF 定位具体内核问题的时候,就更需要理解内核对应部分的代码了。比如,如果我们要诊断网络问题,很自然地,我们需要知道一个网络数据包从网卡驱动进入到内核网络协议栈的主要函数,然后对这些函数进行追踪。下面是内核网络协议栈数据包的接收和发送主要函数图:

image.png

2、横向的应用

纵向的问题是在一个节点上的深入,而横向的问题是在云原生平台上,如何对几千几万台机器使用 eBPF。在生产环境的云原生平台上使用 eBPF,一般有两种场景:


  • 第一种是针对生产环境中的特定问题做诊断。Client 收到异常 TCP RST 的问题,就是属于这种场景。
  • 第二种是通过 eBPF 来采集内核相关的参数,作为云平台常规监控数据的一部分,进行长期的收集。


对于第一种场景,在几千几万台机器中使用 eBPF 来定位问题,和只在一台机器上运行 eBPF 程序还是有很大不同的,它需要考虑到下面两个问题。


第一个问题是权限的问题。在生产环境的云平台上,有 root 权限登录宿主机的同学很少,用户的 pod/container 绝大多数都是 non-privileged,而运行 eBPF 程序又需要有 privileged 的权限。这样就产生了一个很大的矛盾: 如果用户的 pod 出现网络问题,希望使用 eBPF 程序来做深入的诊断,而用户自己根本就没有权限,这样一旦发生问题,只能依靠有 root 权限的同学登录到宿主机上去执行 eBPF 程序。而有 root 权限的同学寥寥无几,这也会成为瓶颈,这样就把 eBPF 在云平台上的使用门槛不必要地拉高了。


第二个问题是多节点操作的问题。在生产环境的云平台上,要诊断一个问题,往往需要同时在多个节点上执行程序或者收集数据。比如要解决网络延时的问题,就需要在 client pod 宿主机、software LB 宿主机、server pod 宿主机上同时对一个流的数据包进行追踪。类似的多节点诊断操作在生产环境的云平台上常常会发生,如果每次都是手动到各个节点上去执行 eBPF 程序,然后汇总数据,那么工作效率也是很低下的。


要解决上面的两个问题,我们需要在云平台上建立一个运行 eBPF 诊断程序的框架。这个框架至少要包含三个部分:


  • 第一部分是在每个宿主机上的 agent。这个 agent 可以用来运行各种 eBPF 诊断程序;
  • 第二部分是一个 controller。这个 controller 用于接收到用户诊断的命令,然后协调相关宿主机里的 agent 来运行 eBPF 程序并且汇总结果;
  • 第三部分是一个用户界面,包含用户认证、权限控制,让用户输入诊断指令并且输出结果。


在云平台上有了 eBPF 诊断的框架之后,它不仅可以帮助解决我们前面说的第一种场景中碰到的问题,其实也可以为第二种场景,也就是监控方面提供服务。在每个宿主机上运行的 agent 不但可以接收指令来执行特定的 eBPF 程序,也可以不断输出 metrics 与现有的监控平台相结合。比如,可以使用 eBPF_exporter 把一些内核相关的 metrics 不断地输出。开源项目 pixie 也提供了在云原生平台上的一个比较完整的 observability 框架和工具,底层的 agent 也是基于 eBPF。

相关文章
|
23天前
|
人工智能 Cloud Native 算法
|
6月前
|
监控 Cloud Native 持续交付
构建未来:云原生技术驱动的云计算平台
【5月更文挑战第52天】 随着数字化转型的不断深化,企业对于敏捷性、可扩展性和成本效益的需求日益增长。本文探讨了如何通过采纳云原生技术来构建和优化云计算平台,以支持不断变化的业务需求。文章首先概述了云原生技术的核心概念及其优势,随后详细分析了在设计云平台时应考虑的关键要素,并通过案例研究展示了云原生实践在实际中的应用效果。最后,文章提出了面向未来的云平台发展趋势和挑战。
|
7月前
|
存储 弹性计算 监控
【阿里云云原生专栏】成本优化策略:在阿里云云原生平台上实现资源高效利用
【5月更文挑战第29天】本文探讨了在阿里云云原生平台上实现资源高效利用和成本优化的策略。通过资源监控与评估,利用CloudMonitor和Prometheus等工具分析CPU、内存等使用情况,识别浪费。实施弹性伸缩策略,利用自动伸缩规则根据业务负载动态调整资源。借助容器化管理和Kubernetes编排提高资源利用率,优化存储选择如OSS、NAS,以及网络配置如VPC和CDN。示例展示了如何使用Kubernetes的HorizontalPodAutoscaler进行弹性伸缩,降低成本。
243 4
|
7月前
|
边缘计算 Cloud Native 数据管理
【阿里云云原生专栏】云原生背景下的AIoT布局:阿里云Link平台解析
【5月更文挑战第29天】阿里云Link平台,作为阿里云在AIoT领域的核心战略,借助云原生技术,为开发者打造一站式物联网服务平台。平台支持多协议设备接入与标准化管理,提供高效数据存储、分析及可视化,集成边缘计算实现低延时智能分析。通过实例代码展示,平台简化设备接入,助力智能家居等领域的创新应用,赋能开发者构建智能生态系统。
189 3
|
2月前
|
人工智能 自然语言处理 关系型数据库
阿里云云原生数据仓库 AnalyticDB PostgreSQL 版已完成和开源LLMOps平台Dify官方集成
近日,阿里云云原生数据仓库 AnalyticDB PostgreSQL 版已完成和开源LLMOps平台Dify官方集成。
|
3月前
|
Kubernetes 监控 Cloud Native
Cluster Optimizer:一款云原生集群优化平台
**Cluster Optimizer** 是一款云原生集群优化平台,旨在通过自动化和智能化工具帮助企业降低云成本,解决云原生架构中的成本管理难题。面对资源闲置、配置不当和缺乏自动化优化机制等挑战,Cluster Optimizer能够深入分析云资源、应用和用户行为,精准识别优化机会,并给出具体建议,涵盖节点组、节点、GPU 节点、磁盘、持久卷和应用等多个维度。通过优化实例类型、自动扩缩容和资源分配,帮助企业降低成本、提升性能和效率。[点击此处](https://www.wiseinf.com.cn/docs/setup/) 免费安装和试用 **Cluster Optimizer 社区版**。
102 9
|
4月前
|
存储 边缘计算 Kubernetes
边缘计算问题之边缘计算平台建设中业务应用践行云原生体系如何解决
边缘计算问题之边缘计算平台建设中业务应用践行云原生体系如何解决
63 1
|
4月前
|
Kubernetes 监控 Cloud Native
eBPF技术大揭秘:一张全景图彻底改变Kubernetes问题排查,助你成为云原生时代的超级英雄!
【8月更文挑战第8天】在云原生时代,Kubernetes作为容器编排的标准,其问题排查变得日益复杂。eBPF技术无需改动内核即可编写高效、安全的内核程序,实现系统细粒度观测与控制。近期发布的基于eBPF的Kubernetes问题排查全景图,展示了如何利用eBPF监控资源使用、网络性能及调度策略等,例如通过eBPF程序监控CPU使用率。此全景图有助于快速定位如高CPU使用率等问题所在Pod,进而优化配置或调整调度。
118 8
|
5月前
|
人工智能 运维 Cloud Native
|
5月前
|
Java Serverless API
云原生应用问题之将文档中的代码部署在函数计算平台上会提升用户体验如何解决
云原生应用问题之将文档中的代码部署在函数计算平台上会提升用户体验如何解决
45 0