我编写了以下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
答案 0 :(得分:1)
这是因为docker使用net_prio
和net_cls
控制器,它们会覆盖用于cgroup2匹配的数据。来自here
尽管userland可以随时开始使用net_prio或net_cls,但是一旦使用了它们,则cgroup2匹配将不再起作用。
我的解决方案是使用引导标志cgroup_no_v1=net_prio,net_cls
禁用这些控制器。更好的解决方案是停止docker使用它们,但我不知道该怎么做。