[](#understanding-cilium-network-performance)git
原文连接:https://cilium.io/blog/2021/0...github
做者:Thomas Graf
译者:罗煜、张亮,均来自KubeSphere 团队
Thomas Graf 是 Cilium 的联合创始人,同时也是 Cilium 母公司 Isovalent 的 CTO 和联合创始人。此前 Thomas 曾前后在 Linux 内核的网络、安全和 eBPF 领域从事了 15 年的开发工做。
注:本文已取得做者本人的翻译受权编程
你们好!👋安全
随着愈来愈多的关键负载被迁移到 Kubernetes 上,网络性能基准测试正在成为选择 Kubernetes 网络方案的重要参考。在这篇文章中,咱们将基于过去几周进行的大量基准测试的结果探讨 Cilium 的性能特色。应广大用户的要求,咱们也将展现 Calico 的测试结果,以便进行直接对比。服务器
除了展现测试的结果数据外,咱们还将对容器网络基准测试这一课题进行更深刻的研究,并探讨如下几个方面的问题:网络
在详细分析基准测试及其数据以前,咱们先展现汇总的测试结论。若是您但愿直接了解测试细节并得出本身的结论,也能够跳过这一节的内容。数据结构
eBPF 起决定性做用:Cilium 在某些方面优于 Calico 的 eBPF 数据路径(Data Path),例如在 TCP_RR
和 TCP_CRR
基准测试中观察到的延迟。此外,更重要的结论是 eBPF 明显优于 iptables。在容许使用 eBPF 绕过 iptables 的配置环境中,Cilium 和 Calico 的性能都明显优于不能绕过 iptables 的状况。架构
在研究具体细节后,咱们发现 Cilium 和 Calico 利用 eBPF 的方式并不彻底相同。虽然两者的某些概念是类似的(考虑到开源的性质,这也并不奇怪),CPU 火焰图显示 Cilium 利用了额外的上下文切换节省功能。这或许能够解释 TCP_RR
和 TCP_CRR
测试结果的差别。socket
整体而言,从基准测试结果来看,eBPF 无疑是解决云原生需求挑战的最佳技术。tcp
对比 WireGuard 和 IPsec:有些使人意外,尽管 WireGuard 在咱们的测试中可以实现更高的最大吞吐量,但 IPsec 在相同的吞吐量下 CPU 使用效率更高。这颇有可能得益于 AES-NI CPU 指令集。该指令集支持卸载 IPsec 的加密工做,但 WireGuard 不能从中受益。当 AES-NI 指令集不可用时,结果就明显反转了。
好消息是,从 Cilium 1.10 开始,Cilium 不只支持 IPsec 还支持 WireGuard。您能够选择其中之一来使用。
免责声明:
基准测试难度很大。测试结果很大程度上依赖于运行测试的硬件环境。除非是在相同的系统上收集的结果,不然不该直接用绝对的数值进行比较。
让咱们从最多见和最明显的 TCP 吞吐量基准测试开始,测量运行在不一样节点上的容器之间的最大数据传输速率。
上图显示了单个 TCP 链接可实现的最大吞吐量,最优的几个配置性能恰好超过了 40 Gbit/s。以上结果由 netperf
的 TCP_STREAM
测试得出,测试环境使用了速率为 100 Gbit/s 的网口以确保网卡不会成为瓶颈。因为运行单个 netperf
进程经过单个 TCP 链接传输数据,大部分的网络处理是由单个 CPU 核心完成的。这意味着上面的最大吞吐量受到单个核心的可用 CPU 资源限制,所以能够显示当 CPU 成为瓶颈时每一个配置能够实现的吞吐量。本文后面将会进一步扩展测试,使用更多的 CPU 核心来消除 CPU 资源的限制。
使用高性能 eBPF 实现的吞吐量甚至略高于节点到节点的吞吐量。这使人很是意外。一般广泛认为,相较于节点到节点的网络,容器网络会带来额外的开销。咱们暂时先把这个疑惑搁置一旁,进一步研究以后再来分析这个问题。
TCP_STREAM
基准测试的结果已经暗示了哪些配置能够最有效地实现高传输速率,但咱们仍是看一下运行基准测试时系统总体的 CPU 消耗。
上图显示了达到 100 Gbit/s 吞吐量整个系统所需的 CPU 使用率。请注意,这不一样于前一个图中吞吐量对应的 CPU 消耗。在上图中,全部的 CPU 使用率都已折算为传输速率稳定在 100 Gbit/s 时的数值以即可以直接对比。上图中的条形图越短,对应的配置在 100 Gbit/s 传输速率时的效率越高。
注意:TCP 流的性能一般受到接收端的限制,由于发送端能够同时使用 TSO 大包。这能够从上述测试中服务器侧增长的 CPU 开销中观察到。
虽然大多数用户不太可能常常遇到上述的吞吐量水平,但这样的基准测试对特定类型的应用程序有重要意义:
在本文后面的章节,咱们将继续深刻讨论测量延迟:每秒请求数和新链接处理速率,以更好地展现典型微服务工做负载的性能特色。
在第一个基准测试的分析中咱们提到,与节点网络相比,容器网络会带来一些额外开销。这是为何呢?让咱们从架构的角度来对比这两种网络模型。
上图代表容器网络也须要执行节点到节点网络的全部处理流程,而且这些流程都发生在容器的网络命名空间中(深蓝色部分)。
因为节点网络的处理工做也须要在容器网络命名空间内进行,在容器网络命名空间以外的任何工做本质上都是额外开销。上图显示了使用 Veth 设备时,Linux 路由的网络路径。若是您使用 Linux 网桥或 OVS,网络模型可能略有不一样,但它们基本的开销点是相同的。
在上面的基准测试中,您也许会疑惑 Cilium eBPF 和 Cilium eBPF 传统主机路由(Legacy Host Routing)两种配置的区别,以及为何原生的 Cilium eBPF 数据路径会比主机路由快得多。原生的 Cilium eBPF 数据路径是一种被称为 eBPF 主机路由的优化数据路径,以下图所示:
eBPF 主机路由容许绕过主机命名空间中全部的 iptables 和上层网络栈,以及穿过 Veth 对时的一些上下文切换,以节省资源开销。网络数据包到达网络接口设备时就被尽早捕获,并直接传送到 Kubernetes Pod 的网络命名空间中。在流量出口侧,数据包一样穿过 Veth 对,被 eBPF 捕获后,直接被传送到外部网络接口上。eBPF 直接查询路由表,所以这种优化彻底透明,并与系统上运行的全部提供路由分配的服务兼容。关于如何启用该特性,请参阅调优指南中的 eBPF 主机路由。
Calico eBPF 正在将一些相似的绕过方法用于 iptables,但这与 Cilium 的原理并不彻底相同,文章后面会进一步介绍。无论如何,测试结果证实绕过缓慢的内核子系统(例如 iptables)能够带来极大的性能提高。
在上文中,咱们分析了只涉及一个 CPU 核心的基准测试结果。接下来咱们将放开单核的限制,将 TCP 流并行化以运行多个 netperf
进程。
注意:因为硬件有 32 个线程,咱们特地选择了 32 个进程,以确保系统可以均匀地分配负载。
上图并无提供十分有价值的信息,仅仅代表若是投入足够多的 CPU 资源,全部测试配置都能达到接近 100 Gbit/s 的线速率。然而,从 CPU 资源来看,咱们仍然能够发现效率上的差别。
请注意,上图中的 CPU 使用率涵盖了所有的 CPU 消耗,包括正在运行的 netperf
进程的消耗,也包括工做负载执行网络 I/O 所需的 CPU 资源。然而,它并不包括应用程序一般须要执行的任何业务逻辑所带来的 CPU 消耗。
每秒请求数与吞吐量指标几乎彻底相反。它能够衡量单个 TCP 持久链接上按顺序的单字节往返的传输速率。此基准测试能够体现网络数据包的处理效率。单个网络数据包的延迟越低,每秒可处理的请求就越多。吞吐量和延迟的共同优化一般须要进行权衡。为了得到最大的吞吐量,较大的缓冲区是理想的选择,可是较大的缓冲区会致使延迟增长。这一现象被称为缓冲区膨胀。Cilium 提供了一个称为带宽管理器(Bandwidth Manager)的功能,该功能能够自动配置公平队列,可实现基于最先发出时间的 Pod 速率限制,并为服务器工做负载优化 TCP 栈设置,使吞吐量和延迟之间达到最佳平衡。
这个基准测试常常被忽视,但它对用户来讲一般比想象的重要得多,由于它模拟了一种十分常见的微服务使用模式:使用持久化的 HTTP 或 gRPC 链接在 Service 之间发送请求和响应。
下图显示单个 netperf
进程执行 TCP_RR
测试时,不一样配置的性能表现:
在这个测试中表现更好的配置也实现了更低的平均延迟。然而,这并不足以让咱们对 P95 或 P99 延迟得出结论。咱们将在将来的博客文章中探讨这些问题。
咱们进一步测试运行 32 个并行的 netperf
进程以利用全部可用的 CPU 核心。能够看到,全部配置的性能都有所提高。然而,与吞吐量测试不一样的是,在本测试中投入更多的 CPU 资源并不能弥补效率上的欠缺,由于最大处理速率受延迟而非可用 CPU 资源限制。即使网络带宽成为瓶颈,咱们也会看到相同的每秒请求数值。
整体而言,结果很是鼓舞人心,Cilium 能够在咱们的测试系统上经过 eBPF 主机路由实现近 1,000,000 请求每秒的处理速率。
整体而言,Cilium eBPF 和 Calico eBPF 的性能基本相同。这是由于它们使用了相同的数据路径吗?并非。并不存在预约义的 eBPF 数据路径。eBPF 是一种编程语言和运行时引擎,它容许构建数据路径特性和许多其余特性。Cilium 和 Calico eBPF 数据路径差别很大。事实上,Cilium 提供了不少 Calico eBPF 不支持的特性。但即便是在与 Linux 网络栈的交互上,二者也有显著的差别。咱们能够经过两者的 CPU 火焰图来来进一步分析。
Cilium 的 eBPF 主机路由提供了很好的免上下文切换的数据传送途径(从网卡到应用程序的套接字)。这就是为何在上面的火焰图中整个接收端路径可以很好地匹配到一张火焰图中。火焰图也显示了 eBPF、TCP/IP 和套接字的处理块。
Calico eBPF 接收端看起来却不太同样。虽然有着相同的 eBPF 处理块执行 eBPF 程序,但 Calico eBPF 接收路径穿过了额外的 Veth,这在 Cilium eBPF 数据路径接收端并不须要。
上图中的处理仍然在主机的上下文中执行。下面的这火焰图显示了 Pod 中被 process_backlog
恢复执行的工做。虽然这与 Cilium 场景下的工做同样(都是 TCP/IP+套接字数据传送),但由于穿过了 Veth 从而须要额外的上下文切换。
若是您但愿本身进行更进一步的研究,能够点击如下连接打开交互式的火焰图 SVG 文件查看细节:
链接处理速率基准测试基于每秒请求数的基准测试,但为每一个请求都创建了新的链接。此基准测试的结果显示了使用持久链接和为每一个请求建立新链接两种方式的性能差异。建立新 TCP 链接须要涉及系统中的多个组件,因此这个测试是目前对整个系统压力最大的测试。经过这个基准测试,咱们能够看到,充分利用系统中大多数的可用资源是可能的。
这个测试展现了一个接收或发起大量 TCP 链接的工做负载。典型的应用场景是由一个公开暴露的服务处理大量客户端请求,例如 L4 代理或服务为外部端点(例如数据抓取器)建立多个链接。这个基准测试可以在卸载到硬件的工做最少的状况下尽量地压测系统,从而显示出不一样配置的最大性能差别。
首先,咱们运行一个 netperf
进程来进行 TCP_CRR
测试。
在单个进程下不一样配置的性能差别已经十分巨大,若是使用更多的 CPU 核心差别还将进一步扩大。同时也能够明显看出,Cilium 再次可以弥补网络命名空间额外开销形成的性能损失并达到和基线配置几乎相同的性能。
后续计划:这个 CPU 资源使用率让咱们很惊讶并促使咱们在接下来 1.11 的开发周期作进一步研究。彷佛只要涉及到网络命名空间的使用,发送端的资源开销老是必不可少的。这一开销在全部涉及网络命名空间的配置中都存在,因此颇有多是由 Cilium 和 Calico 都涉及的内核数据路径形成的。咱们会及时更新这部分研究的进展。
当并行运行 32 个进行 TCP_CRR
测试的 netpert
进程以利用全部 CPU 核心时,咱们观察到了一个很是有意思的现象。
基线配置的链接处理速率显著降低。基线配置的性能并无随着可用 CPU 资源的增多而进一步提高,尽管链接跟踪状态表大小发生了相应变化而且咱们确认并无发生因链接跟踪表记录达到上限而致使的性能下降。咱们重复进行了屡次相同的测试,结果仍然相同。当咱们手动经过 -j NOTRACK
规则绕过 iptables 链接跟踪表时,问题马上解决了,基线配置性能恢复到 200,000 链接每秒。因此很明显,一旦链接数超过某个阈值,iptables 链接跟踪表就会开始出现问题。
注意:在这个测试中,Calico eBPF 数据路径的测试结果一直不是很稳定。咱们目前还不清楚缘由。网络数据包的传输也不是很稳定。咱们没有将测试结果归入考虑,由于测试结果不必定准确。咱们邀请 Calico 团队和咱们一块儿研究这个问题并从新进行测试。
鉴于咱们使用的是未经修改的标准应用程序来处理请求和传输信息,每秒处理 200,000 链接是一个很是优秀的成绩。不过,咱们仍是看一下 CPU 的消耗。
这个基准测试结果显示了不一样配置的最大性能差别。为了达到每秒处理 250,000 新链接的目标,整个系统必须消耗 33% 到 90% 的可用资源。
因为发送端 CPU 资源消耗一直高于接收端,咱们能够确信相同资源下每秒能接收的链接数要大于每秒能发起的链接数。
可能全部人都会认为 WireGuard 的性能会优于 IPsec,因此咱们先测试 WireGuard 在不一样的最大传输单元(MTU)下的性能。
不一样的配置之间有一些差别。值得注意的是,Cilium 与 kube-proxy 的组合比单独 Cilium 的性能更好。然而,这个性能差别相对较小而且基本能够经过优化 MTU 弥补。
如下是 CPU 资源的消耗:
上述结果代表在 MTU 相同的状况下,不一样配置之间的 CPU 使用率差别很小,于是能够经过优化 MTU 配置得到最佳性能。咱们还对每秒请求数进行了测试,获得的结果也相同。感兴趣的读者能够参阅 Cilium 文档的 CNI 性能基准测试章节。
对 Wireguard 和 IPsec 的性能进行比较更加有趣。Cilium 支持 IPsec 已经有一段时间了。从 1.10 开始,Cilium 也开始支持 WireGuard。在其余方面相同的状况下,把这两个加密方案放在一块儿进行对比,结果必定会很是有趣。
不出所料,WireGuard 的吞吐量更高,而且在两种 MTU 配置下,WireGuard 的最大传输速率更高。
下面继续测试当吞吐量达到 10 Gbit/s 时,WireGuard 和 IPsec 在不一样的 MTU 配置下的 CPU 使用率。
虽然 WireGuard 的最大吞吐量更高,但 IPsec 在吞吐量相同的状况下 CPU 开销更小从而更有效率,这个差别很是巨大。
注意:为了实现 IPsec 的高效率,须要使用支持 AES-NI 指令集的硬件来卸载 IPsec 的加密工做。
后续计划:目前咱们还不清楚为何 IPsec 的高效率没有带来更高的吞吐量。使用更多的 CPU 核心也没有明显提高性能。这极可能是因为 RSS 不能很好地跨 CPU 核心处理加密流量,由于一般用于哈希和跨 CPU 核心分配流量的 L4 信息是加密的,没法解析。所以,从哈希的角度来看,全部的链接都是同样的,由于在测试中只利用了两个 IP 地址。
这是否会影响延迟?让我进一步研究。延迟基准测试最能准确地描述微服务工做负载的实际情况,微服务工做负载一般都会使用持久链接来交换请求和响应。
CPU 效率与观察到的每秒请求数相符。然而,每一个配置总共消耗的 CPU 资源都不是很高。相比 CPU 消耗方面的差别,延迟方面的差别更为显著。
如下是咱们使用的裸机配置。咱们搭建了两套彻底同样的互相直连的系统。
CONFIG_PREEMPT_NONE
)除非特别说明,全部测试都使用了标准的 1500 字节 MTU。虽然 MTU 的值越高,测试结果的绝对数值会越好,但本文的基准测试的目的在于比较相对差别,而不是测试最高或最低性能的绝对数值。
应广大用户的要求,咱们展现了 Calico 的测试结果以便进行对比。为了尽量清晰地进行对比,咱们使用了如下配置类型进行测试:
netperf
。一般状况下此配置的性能最优。测试所用的所有脚本都已经上传到 GitHub 仓库 cilium/cilium-perf-networking 中,可用于复现测试结果。
咱们在性能调优方面已经取得了很多结果,但咱们还有许多其余的想法并将进一步优化 Cilium 各方面的性能。
Service 和 NetworkPolicy 基准测试:当前的基准测试结果并不涉及任何 Service 和 NetworkPolicy。咱们没有对两者进行测试以控制本文的内容范围。咱们将进一步对使用 NetworkPolicy 的用例进行测试,除此以外还将对东西向(east-west)和南北向(north-south)的 Service 进行测试。若是您已经等不及了,Cilium 1.8 的发布博客已经公布了一些基准测试结果,而且展现了 XDP 和 eBPF 对性能的显著提高。
目前,咱们仍然对 NetworkPolicy 在 CIDR 规则方面的性能不太满意。咱们当前的架构针对少许复杂的 CIDR 进行了优化,但并无覆盖使用 LPM 来实现的一些特例。一些用户可能但愿对单独 IP 地址的大型放行和阻止列表进行基准测试。咱们会把这个用例放在优先事项中,而且提供基于哈希表的实现。
为了跟社区新老朋友们零距离交流,咱们将联合 CNCF 和其余合做伙伴,从五月到七月,在上海、杭州、深圳、成都这四个城市分别为你们带来技术的交流与碰撞。2021 年继上海站首次 Meetup 火爆全场以后,咱们将依旧延续 KubeSphere and Friends 的主题,于 5 月 29 日杭州为你们带来 Kubernetes and Cloud Native Meetup。
咱们特别定制了 KubeSphere 全套记念周边礼品:T恤、马克杯、记念徽章、帆布袋、口罩等。除此以外还有各类云原生硬核书籍等你来拿!
怎么样,心动了么?报名参与即将到来的杭州站便可得到定制周边记念品!
本文由博客一文多发平台 OpenWrite 发布!