功能概述
本文介绍 TencentOS Server 4 内核的 eBPF(extended Berkeley Packet Filter)支持情况、能力矩阵、工具链安装和常用应用场景,帮助用户在性能分析、网络可观测和安全审计场景下使用 eBPF 无侵入式地获取内核运行信息。
背景信息
传统内核性能分析和网络流量监控依赖内核模块或修改内核源码,存在安全风险大、维护成本高、跨版本不兼容等问题。eBPF 提供了在内核态安全运行沙箱程序的能力,无需修改内核源码或加载内核模块,即可实现网络包处理(XDP/TC)、函数追踪(kprobe/tracepoint)、性能采样(perf_event)和安全策略(LSM BPF)。
TencentOS Server 4 基于 Linux 6.6 LTS 内核,提供完整的 eBPF 支持,包括 BTF(BPF Type Format)和 CO-RE(Compile Once – Run Everywhere)能力,使得 BPF 程序可以跨内核版本运行而无需重新编译。但使用 eBPF 需要 root 权限,且需要正确选择工具链(BCC / bpftrace / libbpf)以匹配不同使用场景。
前提条件
权限要求:加载和运行 BPF 程序需 root 权限,或容器环境下具备
CAP_BPF / CAP_SYS_ADMIN 能力。普通容器默认不支持运行 BPF 工具。内核配置确认:需确认内核已启用以下配置项:
CONFIG_BPF=y(BPF 基础支持)CONFIG_BPF_SYSCALL=y(BPF 系统调用)CONFIG_BPF_JIT=y(BPF JIT 编译)CONFIG_DEBUG_INFO_BTF=y(BTF 支持,CO-RE 必需)CONFIG_BPF_LSM=y(LSM BPF 支持,如需安全策略功能)CONFIG_XDP_SOCKETS=y(XDP socket 支持,如需 AF_XDP 高性能收包)dnf 源可用:安装 BCC、bpftrace、bpftool 需系统 dnf 源可正常访问(BCC/bpftrace 工具包的具体版本号可通过
dnf info bcc-tools bpftrace 查看当前系统可用版本。)。内核模块确认:确认
bpf 相关模块已加载(默认编译进内核,无需额外 modprobe)。内核头文件(BCC 编译场景):BCC 工具运行时编译需要安装
kernel-devel 和 kernel-headers 包匹配当前内核版本。警告:
您在使用环节,需要充分评估以下风险,务必在测试环境中充分验证后再部署到生产环境,请勿在生产环境直接运行未经测试的 BPF 程序。
内核 panic 风险:错误的 BPF 程序可能导致内核 panic,造成系统不可用。
指令数限制:eBPF 指令数限制默认为 100 万条(6.6 内核),复杂 BPF 程序如超出限制,可通过尾调用(tail call)拆分或优化程序逻辑以降低单程序指令数。
接口与参数说明
eBPF 能力矩阵
功能 | 支持状态 | 挂载点 | 典型用途 |
XDP | 支持 | 网卡驱动层 | 高性能包处理、DDoS 防护 |
TC(Traffic Control) | 支持 | 流量控制层 | 流量分类、QoS |
cgroup sock | 支持 | cgroup socket | 容器网络策略 |
kprobe/kretprobe | 支持 | 内核函数入口/出口 | 内核函数追踪 |
tracepoint | 支持 | 内核静态追踪点 | 系统调用追踪 |
perf_event | 支持 | 性能事件 | PMU 事件采样 |
uprobe/uretprobe | 支持 | 用户函数入口/出口 | 应用追踪 |
LSM(BPF) | 支持(默认未启用,需配置 lsm=tee,bpf 启动参数并重启,见操作步骤 7) | 安全挂钩点 | 安全策略 |
sock_ops | 支持 | socket 操作 | TCP 调优 |
sk_msg/sk_redirect | 支持 | socket 消息 | 代理重定向 |
struct_ops | 支持 | 结构体操作 | TCP 拥塞控制自定义 |
eBPF 限制项
限制项 | 取值 | 说明 |
指令数限制 | 100 万条(默认,可配置) | 6.6 内核默认值,可通过内核配置调整 |
栈大小 | 512 字节 | 使用堆分配规避 |
非特权用户 | 默认禁止 | unprivileged_bpf_disabled 取值:0(允许)、1(禁止可改回)、2(禁止不可改回),TencentOS Server 4 默认值为 0 |
内核版本兼容 | CO-RE 程序可跨版本;非 CO-RE 需匹配内核 | 依赖 BTF 支持 |
操作步骤
1. 确认 eBPF 内核支持
# 检查内核 BPF 基础配置grep CONFIG_BPF=y /boot/config-$(uname -r)# 预期输出:CONFIG_BPF=ygrep CONFIG_BPF_SYSCALL=y /boot/config-$(uname -r)# 预期输出:CONFIG_BPF_SYSCALL=ygrep CONFIG_BPF_JIT=y /boot/config-$(uname -r)# 预期输出:CONFIG_BPF_JIT=ygrep CONFIG_XDP_SOCKETS=y /boot/config-$(uname -r)# 预期输出:CONFIG_XDP_SOCKETS=y# 检查 BTF 支持(BPF CO-RE 必需)grep CONFIG_DEBUG_INFO_BTF=y /boot/config-$(uname -r)# 预期输出:CONFIG_DEBUG_INFO_BTF=y# 检查 LSM BPF 支持(如需安全策略功能,见操作步骤 7)grep CONFIG_BPF_LSM=y /boot/config-$(uname -r)# 预期输出:CONFIG_BPF_LSM=y# 查看 BPF 程序限制(非特权用户加载策略)cat /proc/sys/kernel/unprivileged_bpf_disabled# 预期输出:TencentOS Server 4 默认输出 0;各取值含义:0=允许非特权用户加载 BPF 程序,1=禁止且可改回,2=禁止且不可改回
2. 查看已加载 BPF 程序的指令数
# 如尚未安装 bpftool,请您先执行以下命令安装dnf install bpftool# 查看所有已加载的 BPF 程序及其指令数bpftool prog show# 预期输出:列出所有已加载程序,每行包含:# <prog_id>: <type> name <name> tag <tag> gpl# loaded_at <时间> uid 0# xlated <指令数> insns limit 1000000 insns jited <JIT指令数> bytes memlock <字节数># 查看特定程序的详细信息(JSON + 详细模式,<prog_id> 替换为实际 ID)bpftool prog show id <prog_id> -j -d# 预期输出:JSON 格式的程序详情,包含 xlated_insns 字段即指令数
说明:
bpftool prog show 输出中的 xlated <N> insns 即为该程序编译后的指令数,limit 1000000 insns 为指令数上限。指令数限制为内核编译时常量(6.6 内核默认 100 万条),运行时无法通过 sysctl 修改。
3. 安装 BCC 工具
# 安装 BCC 工具包dnf install bcc-tools# 预期输出:依赖解析完成并安装成功,无报错# 确认工具已安装ls /usr/share/bcc/tools/ | head -10# 预期输出:列出 opensnoop、execsnoop、biolatency、tcptop、profile 等工具# 运行示例:追踪文件打开/usr/share/bcc/tools/opensnoop -d 5# 预期输出:5 秒内所有进程的 open() 调用记录,包含 PID、COMM、FD、ERR、PATH 列
4. 安装和使用 bpftrace
# 安装 bpftracednf install bpftrace# 预期输出:依赖解析完成并安装成功,无报错# 确认版本bpftrace --version# 预期输出:bpftrace v0.x.x 或更高版本# 列出可用追踪点bpftrace -l 'tracepoint:syscalls:sys_enter_*' | head -10# 预期输出:列出 sys_enter_* 系列系统调用追踪点# 追踪所有 openat() 系统调用(按进程计数)bpftrace -e 'tracepoint:syscalls:sys_enter_openat { @[comm] = count(); }'# 预期输出:按进程名聚合的 openat 调用次数表,Ctrl+C 退出后输出统计# 函数延迟追踪(vfs_read 延迟直方图)bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; } kretprobe:vfs_read /@start[tid]/ { @us = hist((nsecs - @start[tid]) / 1000); delete(@start[tid]); }'# 预期输出:vfs_read 延迟直方图(微秒级),Ctrl+C 退出后输出
5. 安装和使用 bpftool
# 如尚未安装 bpftool,请您先执行以下命令安装dnf install bpftool# 预期输出:安装成功,无报错# 查看所有已加载的 BPF 程序bpftool prog show# 预期输出:列出所有已加载程序及其类型、名称、指令数# 查看所有 BPF 映射(maps)bpftool map show# 预期输出:列出所有 BPF map 及其类型、大小# 查看附加到网络接口的 BPF 程序(<网卡名> 替换为实际网卡)bpftool net show dev <网卡名># 预期输出:列出该网卡上附加的 XDP/TC 等程序,无附加则输出为空
6. 使用 libbpf + CO-RE 开发
TencentOS Server 4 内核支持 BTF,可使用 CO-RE 方式开发 BPF 程序,无需为目标内核专门编译。
# 安装 libbpf 开发包dnf install libbpf-devel# 预期输出:安装成功# 确认 BTF 信息可用ls /sys/kernel/btf/vmlinux# 预期输出:/sys/kernel/btf/vmlinux(文件存在表示 BTF 可用)# 克隆 libbpf-bootstrap 模板(需网络访问 GitHub)git clone https://github.com/libbpf/libbpf-bootstrap# 预期输出:克隆成功
7. 启用 LSM BPF 支持
# 确认内核支持 BPF LSMgrep CONFIG_BPF_LSM=y /boot/config-$(uname -r)# 预期输出:CONFIG_BPF_LSM=y# 查看当前启用的 LSM 列表cat /sys/kernel/security/lsm# 预期输出:lsm 列表(TencentOS Server 4 默认为 capability,yama,selinux,bpf——bpf 默认已启用)# 如列表中无 bpf,通过内核启动参数添加 lsm=tee,bpf(需重启生效,# 重启将导致业务中断,请在维护窗口内执行;修改 LSM 列表会影响系统安全策略行为,请先在测试环境验证)grubby --update-kernel=ALL --args="lsm=tee,bpf"# 预期输出:无报错# 重启生效reboot# 重启后确认cat /sys/kernel/security/lsm# 预期输出:包含 bpf 的 LSM 列表
说明:
LSM BPF 通过
lsm=tee,bpf 内核启动参数启用,Secure Boot 并非硬性要求。如系统已启用其他 LSM(如 SELinux),BPF LSM 可与其共存。8. 运行常用场景示例
# CPU off-cpu 分析(采样 5 秒)/usr/share/bcc/tools/offcputime 5# 预期输出:off-cpu 时间按内核栈聚合的直方图,定位阻塞热点# 内存分配追踪/usr/share/bcc/tools/memleak# 预期输出:按调用栈聚合的内存分配/释放统计,未释放的为泄漏# 系统调用延迟统计/usr/share/bcc/tools/syscount# 预期输出:按系统调用聚合的延迟统计表
预期输出均为按时间维度聚合的直方图或计数表,可据此定位热点函数或异常调用。
常见问题
Q1:加载 BPF 程序报错 Operation not permitted
原因:非 root 用户运行,或容器环境缺少
CAP_BPF / CAP_SYS_ADMIN 能力。解决:切换到 root 权限或为容器添加对应能力后重试。
# 方式1:使用 root 用户执行sudo <bpf命令># 方式2:容器运行时添加能力docker run --cap-add CAP_BPF --cap-add CAP_SYS_ADMIN ...# 方式3:确认非特权用户加载已禁止(正常状态)cat /proc/sys/kernel/unprivileged_bpf_disabled# 预期输出:0、1 或 2(1 或 2 表示已禁止非特权用户加载 BPF 程序)
Q2:BCC 工具运行报错,提示找不到内核头文件 kernel headers not found
原因:BCC 工具运行时编译需要
kernel-devel 包,且版本需与当前内核匹配。解决:安装与当前内核版本匹配的 kernel-devel 和 kernel-headers 包。
# 查看当前内核版本uname -r# 预期输出:如 6.6.0-xxx.el4.x86_64# 安装对应版本 kernel-devel 和 kernel-headersdnf install "kernel-devel-$(uname -r)" "kernel-headers-$(uname -r)"# 预期输出:安装成功# 确认头文件路径存在ls /lib/modules/$(uname -r)/build# 预期输出:该路径存在且为符号链接指向源码目录
Q3:加载 CO-RE 程序报错 BTF not found 或 failed to load BTF
原因:目标内核未启用
CONFIG_DEBUG_INFO_BTF=y,或 /sys/kernel/btf/vmlinux 文件不存在。解决:确认内核 BTF 配置与文件状态,不满足时更换启用 BTF 的内核。
# 确认内核 BTF 配置grep CONFIG_DEBUG_INFO_BTF=y /boot/config-$(uname -r)# 预期输出:CONFIG_DEBUG_INFO_BTF=y# 确认 BTF 文件存在ls -l /sys/kernel/btf/vmlinux# 预期输出:该文件存在# 若内核未启用 BTF,需更换为启用 BTF 的内核版本# TencentOS Server 4 默认启用 BTF,若缺失请确认内核来源
Q4:BPF 程序加载失败,提示 program too large 或指令数超限
原因:BPF 程序编译后指令数超过 100 万条限制(6.6 内核默认值)。
解决:查看程序实际指令数,通过拆分程序或优化逻辑降低指令数。
# 用 bpftool 查看程序实际指令数bpftool prog show# 预期输出:xlated <指令数> insns limit 1000000 insns# 若指令数接近上限,拆分为多个小 BPF 程序# 或优化程序逻辑,减少循环和分支# 检查是否有循环未展开或尾调用未使用
Q5:sysctl kernel.bpf_stats 的作用是什么
说明:
kernel.bpf_stats 是 BPF 统计信息采集开关,取值 0(关闭)或 1(开启)。开启后可查看 BPF 程序的运行时间统计。# 查看 bpf_stats 当前值sysctl kernel.bpf_stats# 预期输出:kernel.bpf_stats = 0# 开启 BPF 统计信息采集(0 关闭,1 开启)sysctl -w kernel.bpf_stats=1# 预期输出:kernel.bpf_stats = 1