阅读Cilium以及bpf相关博客的笔记

eBPF技术

eBPF是一个用于访问Linux内核服务和硬件的新方法,通过eBPF用户可以动态的向操作系统子系统的某个位置动态注入定义的代码,从而改变内核原有的行为。这一新技术已经用于网络、出错、跟踪以及防火墙等领域,并且在社区中火热发展。

Cilium在实现过程中主要在以下子系统中添加了eBPF程序:

  • eXpress DataPath(XDP)
  • Traffic Control Ingress/Egress(TC)
  • cgroup socket BPF
  • sock_ops BPF

引用4详细介绍了上述eBPF程序在Linux DataPath链路中的位置。

Cilium中的 TC eBPF

Cilium在转发Pod流量时使用了大量的BPF Hook,用户需要结合Cilium的源码才能理解数据包的转发路径,引用1叙述了Pod访问Service时数据包如何从源Pod的网络空间到达后端。

作者在对容器和宿主机上的路由、IP信息进行了基本分析后,借助tc命令行工具挖掘对应网络设备上的装载的TC BPF,并结合Cilium的源码对流量进行了相关分析。

本文的内容基于引用1进行一些补充,并记录一些自己学习过程中的体会。

1.Traffic Control

TC全称Traffic Control是Linux内核的网络流量控制子系统,从Kernel 4.1开始,TC支持加载eBPF程序到子系统的Hook点,并且在之后的Kernel 4.4中引入了”direct-action“模式,Cilium、Calico等网络插件大量使用TC Hook来控制网络包的转发。

引用1基于iproute2的tc命令行工具查找网络设备上TC Hook,通过eBPF程序的名称定位到Cilium的源码,最终借助分析源代码来了解Packet的转发路径。

TC子系统包括qdisc、class、classifier(filter)、action等概念,eBPF程序可以作为classifier被挂载。

引用2 简单介绍了TC的基本概念

2.网络设备

当部署CiliumAgent后,物理机环境会创建以下网络设备。

  • cilium_net/cilium_host:cilium_net/cilium_host是一对veth,且cilium_host被分配了PodCIDR中的一个IP地址,并且该地址是该节点上Pod容器的默认网关。
  • cilium_vxlan:cilium默认安装时使用vxlan进行跨主机通信,cilium_vxlan是用于处理vxlan报文的设备。

Kubernetes创建Pod时会创建veth pair,一端作为Pod中的eth0设备,另一端在宿主机上设备名称为lxc-xxxx,进入Pod可以看到如下网络信息:

从上图可以看出,PodIp地址是30.233.0.92/32处于一个独立的子网,所有流出Pod的Packet都通过网关30.233.0.119,并且针对网关地址Pod收到的ARP应答为”06:70:4e:44:1e:8c“。

返回主机查看cilium_host和veth的对端,可以看到cilium_host即是Pod的gw,但是Pod中ARP获取的Mac地址却是lxcbaf3bb873760设备的!查看lxcbaf3bb873760的ARP Proxy配置,发现没有被开启。

Calico通过ARP Proxy功能实现了类似效果,并且将容器内所有Pod网关的Mac指定为不存在的地址!

3. TC Hook

从上面的现象可以分析出,Cilium通过某种手段劫持了Pod发出的ARP请求,并相应特定的Mac!

使用tc filter show dev #DeviceName# ingress/egress可以发现Cilium网络设备中安装了以下BPF程序:

设备 ingress egress
cilium_host to-host from-host
cilium_net to-host
cilium_vxlan to-overlay from-overlay
lxc网卡 to-container from-container
物理网卡 to-netdev from-netdev

上述表格中,ingress列表示流量进入设备时执行的ebpf程序,egress表示流量进入设备时执行的ebpf程序。

通过表格关键字,可以在cilium源码的bpf目录下搜索程序源码!

References

  1. 实地探索 Pod-to-Service 转发路径及 BPF 处理逻辑
  2. [译] 深入理解 tc ebpf 的 direct-action (da) 模式(2020)
  3. [译] 大规模微服务利器:eBPF + Kubernetes(KubeCon, 2020)
  4. [译] 深入理解 Cilium 的 eBPF 收发包路径