当 Kmesh 遇上 Ambient Mesh
Kmesh 是业内首个内核级流量治理引擎,Kmesh 创新性地将服务治理卸载到内核 eBPF 和中心代理。Kmesh 目前有两种工作模式:Kernel-Native 和 Dual-Engine 模式。
Kernel-Native 模式,Kmesh 将流量治理完全下沉操作系统内核,通过 eBPF 和可编程内核模块对流量进行治理,在整个服务访问链路上不会增加任何多余的连接跳数,提供极致的性能体验。当然 Kernel-Native 模式对操作系统内核有一定的要求,比较适合对性能有极致要求的用户。
今天重点谈的是 Dual-Engine 模式(本文后续均以 Kmesh 指代),这是一种分层的流量治理架构,它是通过 eBPF 程序拦截应用流量,并根据用户策略进行路由、负载均衡等四层的治理;七层治理则采用中心式代理,这样既可以保证七层治理需求的多样性和扩展性,又避免了 Sidecar 架构中,流量两次进出七层代理的复杂性。Kmesh Dual-Engine 的架构如下图所示:
Kmesh Dual-Engine 架构
Ambient Mesh 是 Istio 社区 2022 年推出的一种 Sidecarless 架构,其目的也是为用户提供资源开销更小的网络基础设施。Ambient 也是采用分层的流量治理,其中节点上,用户态组件 ztunnel 负责拦截进出应用的流量,并进行四层转发;中心侧通过 waypoint 进行七层流量的治理,同样可以做到灵活、按需部署。
Ambient Mesh 架构
我们可以看到 Kmesh 和 Ambient Mesh 在架构上非常相似,两者均采用了四七层分离的流量治理架构。然而不同之处在于,Ambient Mesh 流量的拦截和转发依靠节点级用户态 ztunnel,而 Kmesh 则依靠 eBPF。ztunnel 工作在用户态,因此应用发送的流量首先经过 iptables 的拦截,进入本机协议栈处理一次,发送到 ztunnel,而经过 ztunnel 处理后,再发起第二次连接。同理在服务端,流量也会先被拦截到 ztunnel,再次发起连接,然后经由本机协议栈发送到应用进程。
但是 Kmesh 对应用流量的拦截和转发,则是通过 eBPF 程序在 socket 的不同钩子点完成,整个过程没有增加多余的连接,因此每次通信过程比 Ambient Mesh 少两条连接。说到这里就不得不提一下 Kmesh 的设计初衷了。
Kmesh 设计之道
当前用户在考虑服务网格落地时最担心的几个典型问题是:
网格基础设施不够可靠,运维复杂,因为过多的中间点出现在服务的访问链路中,服务访问被不同的连接管道串联, 故障定位变得复杂
Sidecar 带来的 CPU、内存资源开销不可忽视
网格无法独立升级,它的生命周期与应用绑定,升级过程伴随着应用重启
基础设施代理额外的服务访问时延增加
Kmesh 重点考虑了以上问题并结合用户对网格的基本诉求,定义了五大设计原则:
极简运维,打造足够可靠、轻量、解耦的网络基础设施,尽量的减少用户的维护成本。
高性能,微服务架构下,服务的调用拓扑一般都很长,有的请求甚至有 10+次调用链,因此必须保证在绝大多数情况下,小于 1ms 的时延。
低开销,底层网络基础设施占用的 CPU、Memory 相对于业务容器应该足够小,并且不会随着业务容器的规模而大幅增加。
扩展性,为应对不同的协议治理,必须从架构层提供足够的扩展能力
高安全,构筑零信任安全的能力,为用户提供全链路可信保障
Kmesh 五大设计原则
Kmesh 与 Ambient Mesh 性能对比
几个月前,我们将Kmesh v0.5.0与 Ambient Mesh v1.22.1 在测试环境下(kind 集群)进行过对比,只比对了两者在处理 L7 流量治理的场景下的时延,结果显示,Kmesh 的端到端时延较 Ambient Mesh 提升 25%左右。
Kmesh 与 Ambient v1.22 对比
我们把这个结果汇报给了 CNCF TAG-Network 以及 Istio 社区,他们希望在真实的 Kubernetes 集群以及用最新的版本进行全面的测试。所以我们重新做了完整的测试。
▍测试环境
我们在华为云香港 Region 创建了一个 Kubernetes 1.30 标准版集群,并且纳管了三个 Worker 节点(Ubuntu 22.04, 规格为 4U 16G)。
集群中安装 Istio 1.24.1 Ambient 模式,以及 Kmesh 最新版本
集群中部署了 Fortio 测试工具,无资源限制,其中 Fortio-Client 与 Fortio-Server 均为单副本,分别部署在不同的节点
七层代理 waypoint 按需部署,在 Kmesh 和 Ambient 测试中,均与 Fortio-Server 部署在同一个节点,保证两者拓扑一致
waypoint 规格 2 核 1G
Fortio 测试采用连接复用,并发连接数(1,2,4,8,16,32,64,128)
▍最大吞吐量
L4 治理吞吐
四层服务治理,Kmesh 的最大吞吐与基线(没有任何治理)基本一致,Kmesh 的吞吐能力是 Ambient Mesh 的两倍左右。这里主要是因为,Kmesh 的采用 eBPF 随流治理,不会增加访问路径的长度,而 Ambient Mesh 在客户端和服务端两个节点分别多了一个 ztunnel 用户态代理,导致流量路径多了两条连接。
L7 治理吞吐
L7 治理吞吐放大图
七层服务治理,Kmesh 与 Ambient 吞吐量均比基线差,因为两者均多了一层七层 Envoy 代理。但是 Kmesh 的吞吐大概是 Ambient Mesh 的 1.3 倍,这里还是得益于 Kmesh 的治理路径上少了两次用户态代理,减少了数据的用户态和内核态拷贝次数以及协议栈处理的次数。
▍服务治理时延
我们选取了在固定 QPS 1024 下,分别测试 Kmesh 和 Ambient Mesh 的 L4 和 L7 治理的时延。
L4 服务治理时延测试
可以看到 Kmesh 的 L4 治理相比于基线,基本上没有增加额外的时延开销,而 Ambient Mesh 在并发连接数比较高的时候,增加了大概 1.5ms 的时延。可能是由于 ztunnel 在新版本引入了连接池导致。
L7 服务治理时延测试
我们可以看到在并发连接数低时,Kmesh 与 Ambient Mesh 的七层治理时延增加非常少,在小于 8 并发的时候,Kmesh 的时延小于 1ms,Ambient Mesh 的时延不可预测性更大,其 P99 时延甚至增加 8ms。
随着并发连接数增加,Kmesh 和 Ambient Mesh 的时延均增加。但是在小于 32 并发时,Kmesh 的 P99 时延比 Ambient Mesh 好两倍多。在更高 128 并发时,Ambient Mesh 的表现似乎更优一些,但是差距不大。
在笔者看来,造成以上结果的原因,主要有两点。1、Waypoint 采用 Envoy 实现,当前测试中 Envoy 均启动两个 worker 线程并发处理。Envoy 的线程间不共享任何状态和数据以避免锁冲突,但是同时带来了负载不均衡和延迟不稳定的问题。2、ztunnel 的实现中增加了连接池的优化,虽然连接复用可以在高并发时节省一些连接资源,但是也可能带来额外的不稳定时延。
CPU 和内存
Kmesh 在节点流量治理采用了 eBPF,没有用户态进程,所以引入的资源开销非常小,详细请参考:
https://kmesh.net/en/docs/performance/resource_consumption/
而在最大吞吐量测试时,ztunnel 的 CPU 占用率与 Fortio 应用基本一致,大概 100%的 CPU 占用,而通过 bpftop 工具可以查看 Kmesh 的 bpf 程序 CPU 利用大概在 10%左右,从 CPU 利用率上来说 Kmesh 优于 Ambient 10 倍
数据面内存:在测试中,ztunnel 占用的内存保持在 10M+,相对比较稳定,Kmesh 数据面的内存占用主要在 BPF Map 的内存分配,当前 Kmesh 使用的 BPF Map 已经采用按需分配,因此在测试过程占用的内存更少,小于 5M。
测试感悟与总结
本次测试,我们主要在时延和吞吐两个维度对 Kmesh 和 Ambient 进行了一定比较,总体来说 Kmesh 的性能略胜一筹。
四层流量治理场景下,Kmesh 的性能与基线基本保持一致,全面优于 Ambient Mesh。
但是在七层治理的场景下,我们看到无论是 Kmesh 还是 Ambient Mesh 性能衰减还是比较大,而且也具有一些不稳定的延时。七层代理 Waypoint 是端到端访问的性能瓶颈,受限于其多线程无锁的设计,在高并发场景下,Envoy 的资源分配以及参数调教对性能的影响很重要。
另外技术的对比不应该只局限在一些性能参数指标,还应该关注可靠性、运维的便捷性。服务访问链路就像是由多条管道连接起来的输水管,每一个接口连接就相当于一个用户态组件。输水管道中,接口连接处最容易漏水,而服务访问中同样如此,由于不同的代理组件接收、处理及发送数据的速度不一样,因此不同的代理设置不同的连接 Buffer,不同的超时,不同的连接池等等参数。越多的连接级联,意味着越多的不可靠因素和风险存在。Kmesh 在设计之初就重点考虑了极简运维和高可靠性,Kmesh 尽可能地将流量治理下沉,尽量减少连接的跳数,从下图可以看出,Kmesh 在服务访问链路上连接跳数比 Ambient Mesh 少 2 条,这大大降低了用户在故障后问题定位的复杂度。
将节点的流量治理下沉 OS 内核的另一个好处是,Kmesh 在控制面升级时或者重启时,即使 BPF 程序更新,也不会导致业务的连接中断。而节点级用户态代理,天然不具备升级重启不影响业务通信的能力。
如何使用 Kmesh/加入社区贡献
社区地址:
https://github.com/kmesh-net/kmesh
安装试用:
https://kmesh.net/en/docs/setup/quickstart/
参考链接
1. 实验步骤:
https://github.com/hzxuzhonghu/playground/tree/main/performance_test
3. https://istio.io/latest/blog/2022/introducing-ambient-mesh/
4. https://jimmysong.io/blog/introducing-kmesh-kernel-native-service-mesh/
评论