基于ebpf统计docker容器网络流量

Linux下统计网络带宽的工具很多,但大部分是按网卡、进程、IP维度进行统计。统计容器维度的网络流量,虽然可在容器的namespace查看,或者由cgroup提供的net_cls做标记再配合iptable统计,但使用起来并不方便,这里介绍一种基于ebpf来统计容器维度网络流量的办法,以及使用时遇到的坑。原理与实现ebpf的原理不再介绍了,用来做流量统计,最大的优势是十分灵活,能够根据需求对统计项目进行定制。基本原理就是记录内核中各网络相关函数的参数,再按不同维度,如 cgroupID, 进程,IP地
摘要由CSDN通过智能技术生成

Linux下统计网络带宽的工具很多,但大部分是按网卡、进程、IP维度进行统计。统计容器维度的网络流量,虽然可在容器的namespace查看,或者由cgroup提供的net_cls做标记再配合iptable统计,但使用起来并不方便,这里介绍一种基于ebpf来统计容器维度网络流量的办法,以及使用时遇到的坑。

原理与实现

ebpf的原理不再介绍了,用来做流量统计,最大的优势是十分灵活,能够根据需求对统计项目进行定制。基本原理就是记录内核中各网络相关函数的参数,再按不同维度,如 cgroupID, 进程,IP地址等进行分类,统计,计算,输出。

统计流量

ebpf可通过跟踪内核函数,统计不同层次的网络流量。各层的流量差异主要在于包头,重传,控制报文等等。

L4 TCP 纯数据流量:

上行:kprobe统计  tcp_sendmsg(struct sock *sk,struct msghdr *msg, size_t size)   size 

下行:kprobe统计  tcp_cleanup_rbuf(struct sock *sk, int copied)   copied 

L4 UDP 纯数据流量:

上行:kprobe统计 udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)   len 

下行:kprobe统计 skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)   len 

L3 IP 流量

上行: kprobe统计 ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) skb->len 

下行: kprobe统计 ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,struct net_device *orig_dev) skb->len 

L2 全部网络包流量:

上行:tracepoint统计 net/net_dev_queue   args->len 

下行:tracepoint统计 net/netif_receive_skb  args->len 

获取容器ID

容器基于cgroup创建,容器内的进程生成时其 task_struct->cgroups 会记录其所属cgroup相关信息。ebpf程序运行在内核态,可直接访问进程的task_struct结构,进而获取其cgroupID, 在统计流量时即可方便的区分当前网络流量属于哪个cgroup。

static void fill_container_id(char *container_id) {
  struct task_struct *curr_task;
  struct css_set *css;
  struct cgroup_subsys_sta
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值