searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

ebpf调研(3)

2023-04-06 06:19:13
107
0

Cilium调研(1)

  1. Cilium组件

https://docs.cilium.io/en/stable/concepts/overview/

Cilium的部署包括以下组件,运行在容器集群中的每个Linux容器节点上:

  1. Cilium代理(cilium-agent, Daemon)在每个Linux容器主机上运行。
  2. Cilium CLI Client是一个与Cilium Agent一起安装的命令行工具。
  3. Linux Kernel BPF: 集成Linux内核的功能,用于接受内核中在各种钩子/跟踪点运行的已编译字节码。

 

  1. Cilium关键特性

Cilium 是一个基于 eBPF 技术的云原生网络、安全和可观测项目。下面简单列举一些特性。

网络功能

  1. 通过 CNI 集成到 Kubernetes。
  2. 基于 BPF 实现了 Pod-to-Pod 数据转发路径(datapath)。
  3. 支持直接路由(direct routing)、overlay络模式。
  4. 支持 IPv4、IPv6、NAT46 ( IPv4 到 IPv6 数据包互相转换)。
  5. 支持多集群路由(multi-cluster routing)。
  6. 集成BGP协议, 实现AS自治。

 

负载均衡

  1. 实现了高度可扩展的 L3-L4(XDP)负载均衡。Maglev 一致哈希值。
  2. 能完全替代 kube-proxy,提供 K8s Service 功能。
  3. 支持多集群(multi-cluster)。

https://cloudnativeto.netlify.app/blog/deep-dive-into-cilium-multi-cluster/

通过隧道或直接路由,以本地性能对多个Kubernetes集群进行Pod IP路由,而无需任何网关或代理。

 网络安全

  1. 支持基于身份的(identity-based)L3-L7 网络安全,CiliumNetworkPolicy。
  2. API-aware (API感知的安全性, HTTP、gRPC 等)
  • 允许所有带有方法GET和路径/public/.*的HTTP请求。拒绝所有其他请求。
  • 允许service1在Kafka topic上生成topic1,service2消费topic1。拒绝所有其他Kafka消息。
  • 要求HTTP标头X-Token: [0-9]+出现在所有REST调用中。
  1. 支持WireGuard透明加密(Transparent Encryption) ,对集群中 Pod 之间的流量进行加密, 作为现有 IPsec 实现的替代方案,性能更高。典型应用场景云边通信(边缘计算,私网到公网,私网到私网),UDP打洞 。https://docs.cilium.io/en/stable/gettingstarted/encryption-wireguard/

 

Cilium Service Mesh ( Beta 版本)

可观测性

  1. Metrics: 也是通过 BPF 收集观测数据包含:网络、DNS、安全、延迟、HTTP 等方面的数据。
  2. 提供流日志服务(flow log),并支持设置聚合粒度(datapath aggregation)。 流日志场景: 实时性高,监控吞吐量,优化网络。
  3. 基于 eBPF 的 L7 追踪和度量(无 Sidecar)。
  4. 基于eBPF 加速的per-node 模型。
  5. TLS 终止(外部https + 内部http)、金丝雀发布。
  6. Mesh 和APP耦合在一块。
  7. Mesh和APP解耦,但是每个APP上都有一个Mesh , Mesh数量 = 节点×容器数,Mesh多了即占用很多内存,也影响访问性能。
  8. Mesh下沉到Kernel,每个节点上只有一个Mesh。

 

补充 <Why use Flow Logs ?> 

https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-nsg-flow-logging-overview

You can use it for optimizing network flows, monitoring throughput, verifying compliance, detecting intrusions and more.

 

由于cilium特性很多,先集中讲下cilium在网络的优势。

Cilium 支持以下多节点的网络模型:

  1. Overlay 网络,当前支持 Vxlan 和 Geneve ,也可以启用 Linux 支持的所有封装格式。

网络虚拟化协议:

  • VLAN (12bit) , 可对应 2048个 租户
  • VXLAN (24bit),可以对应1600万 租户
  • GENEVE , 不再由固定的bit数组成,而是可变长,可扩展的。本质是使用TLV类型的数据(Type-Length-Value), 可层层嵌套,不断递归。

 

  1. Native Routing, 当前支持BGP(边界网关协议) , 直接使用主机路由,并且在主机上也容器的 IP 地址,calico网络插件底层就是基于BGP协议组网。

 

  1. 基于Cilium 实现的容器网络方案

下面我们将看看 Cilium 是如何用 eBPF 实现容器网络方案的

https://static.sched.com/hosted_files/kccnceu20/8f/Aug19_eBPF_and_Kubernetes_Little_Helper_Minions_for_Scaling_Microservices_Daniel_Borkmann.pdf

Cilium 中的eBPF 流程

如上图所示,几个步骤:

  1. Cilium agent 生成 eBPF 程序
  2. 用 LLVM 编译 eBPF 程序,生成 eBPF 对象文件(object file,*.o)。
  3. 用 eBPF loader 将对象文件加载到 Linux 内核
  4. 校验器(verifier)对 eBPF 指令会进行合法性验证,以确保程序是安全的,例如 ,无非法内存访问、不会 crash 内核、不会有无限循环等。
  5. 对象文件被即时编译(JIT)为能直接在底层平台(例如 x86)运行的 native code。
  6. 如果要在内核和用户态之间共享状态,BPF 程序可以使用 BPF map,这种一种共享存储,BPF 侧和用户侧都可以访问。
  7. BPF 程序就绪,等待事件触发其执行。对于这个例子,就是有数据包到达网络设备时,触发 BPF 程序的执行。
  8. BPF 程序对收到的包进行处理,例如 mangle。最后返回一个裁决(verdict)结果。
  9. 根据裁决结果,如果是 DROP,这个包将被丢弃;如果是 PASS,包会被送到更网络栈的 更上层继续处理;如果是重定向,就发送给其他设备。

 

kube-proxy 包转发路径

从网络角度看,使用传统的 kube-proxy 处理 Kubernetes Service 时,包在内核中的 转发路径是怎样的?如下图所示: 穿越整个netfilter/iptable协议栈。

步骤:

  1. 网卡收到一个包(通过 DMA 放到 ring-buffer)。
  2. 包经过 XDP hook 点。
  3. 内核给包分配内存,此时才有了大家熟悉的skb(包的内核结构体表示),然后 送到内核协议栈。
  4. 包经过 GRO 处理,对分片包进行重组。
  5. 包进入 tc(traffic control)的 ingress hook。接下来,所有橙色的框都是 Netfilter 处理点, 共8个Hook
  6. Netfilter:在PREROUTING hook 点处理 raw table 里的 iptables 规则。
  7. 包经过内核的连接跟踪(conntrack)模块。
  8. Netfilter:在PREROUTING hook 点处理 mangle table 的 iptables 规则。
  9. Netfilter:在PREROUTING hook 点处理 nat table 的 iptables 规则。
  10. 进行路由判断(FIB:Forwarding Information Base,路由转发表) 。接下来又是四个 Netfilter 处理点。
  11. Netfilter:在FORWARD hook 点处理 mangle table 里的 iptables 规则。
  12. Netfilter:在FORWARD hook 点处理 filter table 里的 iptables 规则。
  13. Netfilter:在POSTROUTING hook 点处理 mangle table 里的 iptables 规则。
  14. Netfilter:在POSTROUTING hook 点处理 nat table 里的 iptables 规则。
  15. 包到达 TC egress hook 点,会进行出方向(egress)的判断,例如判断这个包是到本 地设备,还是到主机外。
  16. 对大包进行分片。根据 step 15 判断的结果,这个包接下来可能会:
  17. 发送到一个本机 veth 设备,或者一个本机 service endpoint,
  18. 或者,如果目的 IP 是主机外,就通过网卡发出去。

 

Cilium eBPF 包转发路径

作为对比,再来看下 Cilium eBPF 中的包转发路径:

对比可以看出,Cilium eBPF datapath 做了短路(short-cut)处理:从 tc ingress 直接 shortcut 到 tc egress,节省了 9 个中间步骤(总共 17 个)。更重要的是:这个 datapath 绕过了 整个 Netfilter 框架(橘黄色的框们),Netfilter 在大流量情况下性能是很差的。去掉那些不用的框之后,Cilium eBPF datapath 长这样:

 

这里为什么可行呢? 是因为cilium使用 tc-eBPF 程序。

tc(traffic classifier,流量分类器)是 Cilium 依赖的最基础的东西,它提供了多种功 能,例如修改包(mangle,给 skb 打标记)、重路由(reroute)、丢弃包(drop),这 些操作都会影响到内核的流量统计,因此也影响着包的排队规则(queueing discipline )。Cilium 控制的网络设备,至少被加载了一个 tc eBPF 程序。

 

Cilium/eBPF 还能走的更远例如,如果包的目的端是另一台主机上的 service endpoint,那你可以直接在 XDP (如果网卡驱动支持XDP, 则offload(卸载)到网卡上执行,不走协议栈)框中完成包的重定向(收包 1->2,在步骤 2 中对包 进行修改,再通过 2->1 发送出去),将其发送出去,如下图所示:

默认转发流程:

优化后转发流程: 不走协议栈,把转发逻辑offload到网卡上执行

 

可以看到,这种情况下包都没有进入内核协议栈(准确地说,都没有创建 skb)就被转 发出去了,性能可想而知。XDP 是 eXpress DataPath 的缩写,支持在网卡驱动中运行 eBPF 代码,而无需将包送到复杂的协议栈进行处理,因此处理代价很小,速度极快。

 

  1. 基于cilium的负载均衡

Cilium 基于 eBPF/XDP 实现了所有类型的 Kubernetes Service。实现方式是:

  1. 在每个 node 上运行一个 cilium-agent;cilium-agent 监听 K8s apiserver,因此能够感知到 K8s 里 Service 的变化;
  2. 根据 Service 的变化动态更新 BPF 配置(map)。

可见,本质和k8s的默认方式没有变化,都是监听service对象CRUD,只是k8s通过iptables,而cilium则借助于ebpf的map能力,从而优化了性能。

如下图所示,Service 的实现由两个主要部分组成:

  1. 运行在 socket 层的 BPF 程序。
  2. 运行在 tc/XDP 层的 BPF 程序。

这两者共享 service map 等资源,其中存储了 service 及其 backend pods 的映射关系。

Socket 层负载均衡(东西向流量)

Socket 层 BPF 负载均衡负责处理集群内的东西向流量。实现方式是:将 BPF 程序 attach 到 socket 的系统调用 hooks,使客户端直接和后端 Pod 建连和通信 (bpf 重定向)。

TC & XDP 层负载均衡(南北向流量)

第二种是进出集群的流量(ingress/egress),称为南北向流量,在宿主机 tc 或 XDP hook 里处理。BPF 做的事情,将入向流量转发到后端 Pod,如果 Pod 在本节点,做 DNAT;如果在其他节点,还需要做 SNAT 或者 DSR( Direct Server Return ),这些都是 packet 级别的操作。

 

  1. XDP/eBPF vs kube-proxy 性能对比(cilium 官网)

网络吞吐

测试环境:两台物理节点,一个发包,一个收包,收到的包做 Service loadbalancing 转发给后端 Pods。数值越高越好。

可以看出:

  1. Cilium XDP eBPF 模式能处理接收到的全部 10Mpps (避免穿越内核协议栈,当然性能最高)。
  2. Cilium tc eBPF 模式能处理5Mpps(packets per second)。
  3. kube-proxy iptables 只能处理3Mpps,因为它的 hook 点在收发包路径上更后面的位置。充分说明了hook点越靠前,处理越快,性能越好。
  4. kube-proxy ipvs 模式这里表现更差,它相比 iptables 的优势要在 backend 数量很多的时候才能体现出来

 

CPU 利用率

我们生成了 1Mpps、2Mpps 和 4Mpps 流量,空闲 CPU 占比(可以被应用使用的 CPU)结果如下: 数值越高越好。

 

结论与上面吞吐类似。

  1. XDP 性能最好,是因为XDP BPF 在驱动层执行,不需要将包 push 到内核协议栈 , cilium tc 其次
  2. kube-proxy 不管是 iptables 还是 ipvs 模式,都在处理软中断(softirq)上消耗了大量 CPU

 

  1. 网络策略

Kubernetes 的网络策略仅能工作在 L3/4 层,对 L7 层就无能为力了。而cilium不仅支持 L3/4、还支持L7 的网络策略( method ,路径,内容TODO)。进一步,Cilium全集群网络策略(CCNP,Cilium-Clusterwide-Network-Policy资源规范与现有Cilium-Network-Policy CRD规范相同,但适用范围更广,面向整个集群中全部Pod。TODO.

 

cailico 做对比 。Kubecon大会, cilium最近发展方向,动态,cilium本身的license ,  生态圈内的license 。

 

0条评论
0 / 1000
Top123
11文章数
3粉丝数
Top123
11 文章 | 3 粉丝