为什么我的BPF_PROG_TYPE_CGROUP_SKB程序在容器中不起作用?

时间:2019-04-12 07:57:09

标签: linux docker linux-kernel bpf ebpf

我编写了以下eBPF程序来对数据包进行计数:

np.float16

我还有一个用户空间组件,该组件将程序作为def import_processing(filepath, cols, null_cols): result = pd.read_csv(filepath, header = None, names = cols.keys()) result.drop(null_cols, axis = 1, inplace = True) for c in null_cols: cols.pop(c, None) result[result.columns] = result[result.columns].apply(pd.to_numeric, errors='coerce') result = result.astype(cols) return result 加载,使用附加类型#include <linux/version.h> #include <uapi/linux/bpf.h> #include "include/bpf_map.h" #include "include/bpf_helpers.h" struct bpf_map_def SEC("maps/count") count_map = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), .value_size = sizeof(__u64), .max_entries = 1024, }; SEC("cgroup/skb") int count_packets(struct __sk_buff *skb) { char debug[] = "count_packets\n"; bpf_trace_printk(debug, sizeof(debug)); int packets_key = 0; __u64 *packets = 0; packets = bpf_map_lookup_elem(&count_map, &packets_key); if (packets == 0) return 0; *packets += 1; // allow access return 1; } char _license[] SEC("license") = "GPL"; u32 _version SEC("version") = LINUX_VERSION_CODE; 将其附加到v2 cgroup(BPF_PROG_TYPE_CGROUP_SKB),并为其添加PID cgroup并开始创建网络流量。

当我在容器外部运行此用户空间组件时,它可以按预期工作,并且我看到通过执行/sys/fs/cgroup/unified/foo来调用程序。

但是,当我在容器中运行程序时,看不到任何输出。

我正在如下运行容器:

BPF_CGROUP_INET_EGRESS

我正在使用主机网络和PID名称空间来避免它们可能引起的任何潜在问题。

为什么我的程序似乎无法在容器中运行?

cat /sys/kernel/debug/tracing/trace_pipe:Linux ubuntu-bionic 4.18.0-16-generic#17〜18.04.1-Ubuntu SMP Tue Feb 12 13:35:51 UTC 2019 x86_64 x86_64 x86_64 GNU / Linux

1 个答案:

答案 0 :(得分:1)

这是因为docker使用net_prionet_cls控制器,它们会覆盖用于cgroup2匹配的数据。来自here

  

尽管userland可以随时开始使用net_prio或net_cls,但是一旦使用了它们,则cgroup2匹配将不再起作用。

我的解决方案是使用引导标志cgroup_no_v1=net_prio,net_cls禁用这些控制器。更好的解决方案是停止docker使用它们,但我不知道该怎么做。