4. eBPF 观测工具链入门:安装与基本使用

在 Kubernetes 网络观测实践中,eBPF 本身是内核子系统,用户需要通过前端工具链来编写、加载和交互。本章聚焦四类主流工具链:bpftrace(快速动态追踪)、BCC(Python/Lua 前端)、libbpf(C 库/CO-RE)以及 cilium/ebpf(Go 库)。掌握它们的安装与基本用法,是构建 K8s 网络观测制品库的基础。

选型建议: 生产环境优先选择 libbpf + CO-RE 或 cilium/ebpf(Go);快速调试用 bpftrace;BCC 适合原型验证但依赖内核头文件。

4.1 工具链全景对比

工具链 语言 内核依赖 CO-RE 支持 典型场景
bpftrace 脚本语言 BTF / 内核头文件 部分(需 BTF) 单次诊断、快速追踪
BCC Python / Lua 内核头文件(必需) 否 原型验证、教学
libbpf C BTF(推荐) 原生支持 生产级 Agent、网络观测
cilium/ebpf Go BTF(推荐) 原生支持 K8s 网络策略、可观测性

4.2 bpftrace:快速动态追踪

bpftrace 是 eBPF 的“awk”,适合在 K8s 节点上快速排查网络延迟、丢包、系统调用异常。

4.2.1 安装

# Ubuntu / Debian
sudo apt-get install -y bpftrace

# CentOS / Rocky Linux 8+
sudo dnf install -y bpftrace

# 验证安装
bpftrace --version

4.2.2 基本使用:追踪 TCP 连接

# 追踪所有 connect() 系统调用,打印目标 IP 和端口
bpftrace -e 'kprobe:tcp_connect { printf("%s:%d -> %s:%d\n", comm, pid, ntop(2, args->sk->__sk_common.skc_daddr), ntohs(args->sk->__sk_common.skc_dport)); }'
实战提示: 在 K8s 节点上运行 bpftrace 需要 CAP_BPF 或 root 权限。建议在 DaemonSet 中以 privileged 容器运行,或使用 securityContext.capabilities.add: ["BPF"]。

4.3 BCC:Python 前端与工具集

BCC 提供丰富的现成工具(如 tcplife、tcpconnect、runqlat),适合快速获取网络和性能指标。

4.3.1 安装

# Ubuntu 20.04+
sudo apt-get install -y bpfcc-tools linux-headers-$(uname -r)

# CentOS 8+
sudo dnf install -y bcc-tools kernel-devel

# 验证工具列表
ls /usr/share/bcc/tools/ | head -20

4.3.2 基本使用:监控 TCP 连接生命周期

# 追踪 TCP 连接建立和关闭,输出 PID、端口、时长
sudo /usr/share/bcc/tools/tcplife

# 输出示例:
# PID   COMM       LADDR           LPORT RADDR           RPORT TX_KB RX_KB MS
# 12345 nginx      10.0.0.1        80    10.0.0.2        54321 2    1     45.2
注意: BCC 在编译 eBPF 程序时需要内核头文件。如果内核版本升级或头文件缺失,工具会报错。生产环境建议迁移到 libbpf + CO-RE。

4.4 libbpf:CO-RE 生产级 C 库

libbpf 是内核官方推荐的 eBPF 库,支持 CO-RE(一次编译,到处运行),无需内核头文件,是 K8s 网络观测 Agent 的首选基础库。

4.4.1 安装

# 从源码编译(推荐)
git clone https://github.com/libbpf/libbpf.git
cd libbpf/src
make
sudo make install

# 或通过包管理器(版本可能较旧)
sudo apt-get install -y libbpf-dev

4.4.2 基本使用:编写最小 eBPF 程序

// trace_open.c — 追踪 open() 系统调用
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

char LICENSE[] SEC("license") = "GPL";

SEC("tracepoint/syscalls/sys_enter_open")
int trace_open(struct trace_event_raw_sys_enter *ctx) {
    char comm[16];
    bpf_get_current_comm(&comm, sizeof(comm));
    bpf_printk("PID %d (%s) called open()\n", bpf_get_current_pid_tgid() >> 32, comm);
    return 0;
}
# 编译并加载
clang -O2 -g -target bpf -c trace_open.c -o trace_open.o
sudo bpftool prog load trace_open.o /sys/fs/bpf/trace_open
sudo bpftool prog attach /sys/fs/bpf/trace_open tracepoint syscalls sys_enter_open

# 查看输出
sudo cat /sys/kernel/debug/tracing/trace_pipe

4.5 cilium/ebpf:Go 语言生态

cilium/ebpf 是 Cilium 项目维护的纯 Go eBPF 库,无需 CGo,完美融入 K8s Operator、Controller 等 Go 应用。它是构建 K8s 网络观测制品库的核心依赖。

4.5.1 安装

# Go 1.21+ 项目
go get -u github.com/cilium/ebpf
go get -u github.com/cilium/ebpf/cmd/bpf2go

4.5.2 基本使用:Go 程序加载 eBPF 统计网络包

//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g" bpf net_stats.c

package main

import (
    "log"
    "net"
    "github.com/cilium/ebpf/link"
    "github.com/cilium/ebpf/rlimit"
)

func main() {
    // 允许当前进程锁定内存
    if err := rlimit.RemoveMemlock(); err != nil {
        log.Fatal(err)
    }

    // 加载编译好的 eBPF 对象
    objs := bpfObjects{}
    if err := loadBpfObjects(&objs, nil); err != nil {
        log.Fatal(err)
    }
    defer objs.Close()

    // 挂载到 lo 网卡
    iface, _ := net.InterfaceByName("lo")
    link, err := link.AttachXDP(link.XDPOptions{
        Program:   objs.XdpStats,
        Interface: iface.Index,
    })
    if err != nil {
        log.Fatal(err)
    }
    defer link.Close()

    log.Println("eBPF XDP 程序已加载,开始统计 lo 网卡流量...")
    select {}
}

4.6 工具链选择决策树

eBPF 工具链选择决策树 你的场景是什么? 快速调试 / 单次诊断 bpftrace 生产级 Agent / 长期观测 你的应用语言是什么? C / C++ → libbpf Go → cilium/ebpf 原型验证 / 教学实验 BCC(Python) 决策要点 • 生产环境优先选择 libbpf(C)或 cilium/ebpf(Go),支持 CO-RE • 快速排障用 bpftrace,一行命令即可追踪内核函数 • BCC 适合快速原型,但依赖内核头文件,不推荐用于生产 • K8s 网络观测制品库推荐 cilium/ebpf + libbpf 混合架构

4.7 安装验证清单

工具链 验证命令 预期输出
bpftrace bpftrace --version bpftrace v0.20.x
BCC sudo /usr/share/bcc/tools/tcplife 实时 TCP 连接事件流
libbpf pkg-config --modversion libbpf 1.4.x
cilium/ebpf go list -m github.com/cilium/ebpf github.com/cilium/ebpf v0.16.x
K8s 环境特别提醒: 在容器中运行 eBPF 程序需要 --privileged 或特定 capabilities(BPF、PERFMON、NET_ADMIN)。建议在 DaemonSet 的 securityContext 中显式声明,避免安全策略冲突。