bpf_trace_printk 生产环境禁用,因限频1024次/秒、触发vprintk导致延迟和加载失败;应改用bpf_perf_event_output;其格式串上限128字节且不报错;bpf_probe_read_kernel需检查返回值并用btf/co-re避免硬编码偏移。

为什么 bpf_trace_printk 在生产环境几乎没用
它会把日志打到内核 ring buffer,但默认只允许每秒最多 1024 次调用,超了就静默丢弃;更关键的是,它会强制触发内核的 vprintk 路径,带来不可控延迟,eBPF 程序可能被内核直接拒绝加载(报错 invalid bpf_context access 或 too many instructions)。真正上线必须换路。
- 调试阶段可用,但建议加条件:只在特定 PID、特定函数入口打一次,比如
if (pid == target_pid && !printed) { bpf_trace_printk(...); printed = 1; } - 生产环境一律改用
bpf_perf_event_output+ 用户态perf_event_open读取,吞吐高、可控性强 - 注意
bpf_trace_printk的格式字符串长度上限是 128 字节(含终止符),超长截断不报错,容易漏信息
用 bpf_probe_read_kernel 读内核结构体总 panic?
不是函数写错了,是没判断地址有效性。eBPF 不允许直接解引用任意指针,bpf_probe_read_kernel 只负责“尝试拷贝”,但若源地址根本不在当前上下文可访问的内核内存页上(比如进程已退出、模块卸载、或字段偏移随内核版本变化),就会触发 -EFAULT,而你没检查返回值——程序继续往下跑,访问未初始化内存,最终触发 verifier 拒绝或运行时 crash。
- 每次调用后必须检查返回值:
if (bpf_probe_read_kernel(&val, sizeof(val), &src->field) != 0) return 0; - 别硬编码结构体偏移,优先用
BTF(如bpftool btf dump查)或libbpf的bpf_object__find_map_by_name+ CO-RE - 对链表遍历类操作(如遍历
task_struct->children),务必限制最大循环次数(比如for (int i = 0; i ),否则 verifier 会因无法验证循环边界而拒绝加载
tc exec bpf 加载后没流量经过?
最常见原因是挂载点(ingress/egress)和网络命名空间不匹配。eBPF 程序绑定在某个 netns 的某块网卡上,但你的测试流量根本没走那条路径——比如容器里跑的程序,实际出口是 veth peer,而不是宿主机 eth0。
- 先确认目标接口是否启用:运行
ip link show dev <code>ens3,看 state 是否为 UP - 用
tc qdisc show dev <code>ens3检查是否真挂上了,输出应包含bpf和对应 prog id - 如果绑的是 ingress,注意:ingress qdisc 是逻辑设备,不处理本地生成包(即本机 curl 自己不算),只处理进入该接口的外部流量
- 抓包交叉验证:
tcpdump -i <code>ens3port 80 看是否有原始流量,再对比 eBPF 输出,才能确定是没触发还是逻辑写错了
为什么 libbpf 加载失败,报 failed to load program: Permission denied
不是权限不够,而是内核配置没开全。现代发行版(尤其是 RHEL/centos 8+、ubuntu 20.04+)默认禁用部分 eBPF 功能,或者启用了 lockdown mode,导致即使 root 也无法加载某些类型的程序。
- 检查
/proc/sys/kernel/unprivileged_bpf_disabled:值为2表示完全禁止非特权加载(包括 root),需设为0或1(后者仅限 root) - 确认内核编译选项:
CONFIG_BPF_SYSCALL=y、CONFIG_BPF_JIT=y、CONFIG_HAVE_EBPF_JIT必须启用;若用 tracepoint,还需CONFIG_TRACING - Secure Boot 启用时,部分系统(如 Fedora)会强制 kernel lockdown,此时需临时关掉:
sudo mokutil --disable-validation(重启生效)
CO-RE 和 BTF 是现在绕过内核版本碎片的唯一靠谱路径,但前提是目标机器有完整 BTF 信息——别信 /usr/lib/debug 下的 vmlinux,得用 bpftool btf dump file /sys/kernel/btf/vmlinux format c 验证能否成功解析。