使用ebpf来自定义探针
使用 Cloudflare 的 ebpf_exporter 创建自定义 eBPF 监控探针
ebpf_exporter 是由 Cloudflare 开发的一个 Prometheus 导出器,允许用户编写自定义的 eBPF 程序以监控和检测系统指标。本文将介绍如何使用 ebpf_exporter 创建包括 CPU 错误率和 IO 错误率在内的自定义探针,并提供完整的项目创建流程。
项目概述
ebpf_exporter 使得用户能够通过编写 eBPF 程序来收集内核级别的自定义指标,并将这些指标以 Prometheus 兼容的格式导出。其主要功能包括:
- 支持自定义 eBPF 探针
- 集成 Prometheus 进行指标收集
- 提供丰富的配置选项以定义和管理指标
- 支持从内核读取 eBPF 程序的 BTF 信息
创建自定义探针的完整流程
以下是创建包含 CPU 错误率和 IO 错误率监控的自定义 eBPF 探针的完整流程。
1. 克隆仓库并构建项目
首先,克隆 ebpf_exporter 仓库并构建项目。
git clone https://github.com/cloudflare/ebpf_exporter.git
cd ebpf_exporter
make build
该命令将构建一个静态链接的二进制文件 ebpf_exporter。
2. 编写自定义 eBPF 程序
在 cmd/ebpf_exporter 目录下编写自定义的 eBPF 程序,以捕获 CPU 错误率和 IO 错误率。以下是一个示例:
// cmd/ebpf_exporter/cpu_io_errors.bpf.c
#include <vmlinux.h>
#include <bpf/bpf_tracing.h>
#include "maps.bpf.h"
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u64);
__type(value, u64);
} cpu_errors_total SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u64);
__type(value, u64);
} io_errors_total SEC(".maps");
SEC("tp_btf/sched_process_exit")
int BPF_PROG(cpu_error_monitor, struct task_struct *task)
{
u64 key = 0;
u64 *count;
// 假设通过某种方式检测到 CPU 错误
count = bpf_map_lookup_elem(&cpu_errors_total, &key);
if (count) {
__sync_fetch_and_add(count, 1);
}
return 0;
}
SEC("tp_btf/block_rq_insert")
int BPF_PROG(io_error_monitor, struct request *req)
{
u64 key = 0;
u64 *count;
// 假设通过某种方式检测到 IO 错误
count = bpf_map_lookup_elem(&io_errors_total, &key);
if (count) {
__sync_fetch_and_add(count, 1);
}
return 0;
}
char LICENSE[] SEC("license") = "GPL";
3. 配置 ebpf_exporter
创建一个配置文件 config.yaml 来定义如何导出这些指标。
# config.yaml
metrics:
counters:
- name: cpu_errors_total
help: CPU 错误总数
labels:
- name: cpu
size: 8
decoders:
- name: ksym
- name: io_errors_total
help: IO 错误总数
labels:
- name: device
size: 8
decoders:
- name: string
4. 编译 eBPF 程序
编译自定义的 eBPF 程序。
make -C cmd/ebpf_exporter build
这将在 cmd/ebpf_exporter 目录下生成相应的 ELF 文件。
5. 运行 ebpf_exporter
启动 ebpf_exporter 并指定配置文件。
sudo ./ebpf_exporter --config.dir=./configs --config.names=cpu_io_errors
6. 配置 Prometheus 采集指标
编辑 Prometheus 配置文件 prometheus.yml,添加 ebpf_exporter 作为一个新的抓取目标。
# prometheus.yml
scrape_configs:
- job_name: 'ebpf_exporter'
static_configs:
- targets: ['localhost:9435']
重新启动 Prometheus 以应用新的配置。
7. 可视化指标
使用 Grafana 等工具连接 Prometheus,创建仪表盘以可视化 CPU 错误率和 IO 错误率。
详细代码示例
以下是项目中关键文件的示例代码。
自定义 eBPF 程序
#include <vmlinux.h>
#include <bpf/bpf_tracing.h>
#include "maps.bpf.h"
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u64);
__type(value, u64);
} cpu_errors_total SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u64);
__type(value, u64);
} io_errors_total SEC(".maps");
SEC("tp_btf/sched_process_exit")
int BPF_PROG(cpu_error_monitor, struct task_struct *task)
{
u64 key = 0;
u64 *count;
// 假设通过某种方式检测到 CPU 错误
count = bpf_map_lookup_elem(&cpu_errors_total, &key);
if (count) {
__sync_fetch_and_add(count, 1);
}
return 0;
}
SEC("tp_btf/block_rq_insert")
int BPF_PROG(io_error_monitor, struct request *req)
{
u64 key = 0;
u64 *count;
// 假设通过某种方式检测到 IO 错误
count = bpf_map_lookup_elem(&io_errors_total, &key);
if (count) {
__sync_fetch_and_add(count, 1);
}
return 0;
}
char LICENSE[] SEC("license") = "GPL";
配置文件
metrics:
counters:
- name: cpu_errors_total
help: CPU 错误总数
labels:
- name: cpu
size: 8
decoders:
- name: ksym
- name: io_errors_total
help: IO 错误总数
labels:
- name: device
size: 8
decoders:
- name: string
参考资源
结论
通过 ebpf_exporter,您可以创建高度自定义的 eBPF 探针来监控系统的各种指标,如 CPU 错误率和 IO 错误率。该工具结合了 eBPF 的强大功能和 Prometheus 的灵活性,适用于需要深度系统监控和性能分析的场景。
License
MIT
资源链接
贡献者
感谢所有贡献者的努力!
标签
performance, linux-kernel, prometheus, tracing, prometheus-exporter, ebpf, bpf, libbpf
结束语
通过以上步骤,您可以成功创建并部署自定义的 eBPF 监控探针,实时监控系统的 CPU 和 IO 错误率,提升系统的可观测性和稳定性。
参考链接
完整项目创建流程示例
以下是一个示例项目结构及其关键文件:
ebpf-monitoring/
├── cmd/
│ └── ebpf_exporter/
│ ├── cpu_io_errors.bpf.c
│ └── Makefile
├── configs/
│ └── cpu_io_errors.yaml
├── Dockerfile
├── prometheus.yml
├── README.md
└── scripts/
└── build.sh
示例 Makefile
CC = clang
CFLAGS = -O2 -g -Wall -target bpf -c
cpu_io_errors.bpf.o: cpu_io_errors.bpf.c
$(CC) $(CFLAGS) $< -o $@
示例 Dockerfile
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
clang \
llvm \
make \
git \
&& rm -rf /var/lib/apt/lists/*
COPY . /ebpf-monitoring
WORKDIR /ebpf-monitoring
RUN make -C cmd/ebpf_exporter build
CMD ["./cmd/ebpf_exporter/ebpf_exporter", "--config.dir=./configs", "--config.names=cpu_io_errors"]
示例 prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'ebpf_exporter'
static_configs:
- targets: ['ebpf_exporter:9435']
示例 README.md
# eBPF Monitoring 项目
本项目使用 Cloudflare 的 `ebpf_exporter` 创建自定义 eBPF 探针,用于监控 CPU 错误率和 IO 错误率。
## 项目结构
- `cmd/ebpf_exporter/`: 包含自定义的 eBPF 程序和构建文件。
- `configs/`: 包含 Prometheus 配置文件。
- `Dockerfile`: 用于构建包含 eBPF 探针的 Docker 镜像。
- `prometheus.yml`: Prometheus 配置文件。
- `scripts/`: 包含辅助脚本。
## 构建和运行
### 使用 Makefile 构建 eBPF 程序
```bash
cd cmd/ebpf_exporter
make
构建 Docker 镜像
docker build -t ebpf-monitoring .
运行 Docker 容器
docker run --privileged -p 9435:9435 ebpf-monitoring
配置 Prometheus
将 prometheus.yml 配置文件挂载到 Prometheus 容器中,并启动 Prometheus。
docker run -d -p 9090:9090 -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
可视化
使用 Grafana 连接到 Prometheus,创建仪表盘以显示 CPU 错误率和 IO 错误率。
更多推荐
所有评论(0)