Cilium系列-9-主机路由切换为基于 BPF 的模式
系列文章
前言
将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, 可以进一步提升 Cilium 的网络性能. 具体调优项包括不限于:
- 启用本地路由(Native Routing)
- 完全替换 KubeProxy
- IP 地址伪装(Masquerading)切换为基于 eBPF 的模式
- Kubernetes NodePort 实现在 DSR(Direct Server Return) 模式下运行
- 绕过 iptables 连接跟踪(Bypass iptables Connection Tracking)
- 主机路由(Host Routing)切换为基于 BPF 的模式 (需要 Linux Kernel >= 5.10)
- 启用 IPv6 BIG TCP (需要 Linux Kernel >= 5.19)
- 禁用 Hubble(但是不建议, 可观察性比一点点的性能提升更重要)
- 修改 MTU 为巨型帧(jumbo frames) (需要网络条件允许)
- 启用带宽管理器(Bandwidth Manager) (需要 Kernel >= 5.1)
- 启用 Pod 的 BBR 拥塞控制 (需要 Kernel >= 5.18)
- 启用 XDP 加速 (需要 支持本地 XDP 驱动程序)
- (高级用户可选)调整 eBPF Map Size
- Linux Kernel 优化和升级
CONFIG_PREEMPT_NONE=y
- 其他:
- tuned network-* profiles, 如:
tuned-adm profile network-latency
或network-throughput
- CPU 调为性能模式
- 停止
irqbalance
,将网卡中断引脚指向特定 CPU
- tuned network-* profiles, 如:
在网络/网卡设备/OS等条件满足的情况下, 我们尽可能多地启用这些调优选项, 相关优化项会在后续文章逐一更新. 敬请期待.
今天我们来调优 Cilium, 启用 Host-Routing(主机路由) 以完全绕过 iptables 和上层主机堆栈,并实现比常规 veth 设备操作更快的网络命名空间切换。
测试环境
- Cilium 1.13.4
- K3s v1.26.6+k3s1
- OS
- 3 台 Ubuntu 23.04 VM, Kernel 6.2, x86
- 3 台 Debian 10 开发板, Kernel 4.19, arm64
eBPF Host-Routing
即使 Cilium 使用 eBPF 执行网络路由,默认情况下,网络数据包仍会穿越节点常规网络堆栈的某些部分。这就导致了所有数据包仍能通过所有 iptables 钩子。不过,这些钩子会增加大量开销。有关测试环境的确切数据,请参阅 TCP 吞吐量 (TCP_STREAM),并比较 "Cilium "和 "Cilium(传统主机路由)"的结果。
具体如下:
Single-Stream:
Multi-Stream:
在 Cilium 1.9 中引入了基于 eBPF 的主机路由,以完全绕过 iptables 和上层主机堆栈,并实现比常规 veth 设备操作更快的网络命名空间切换。如果内核支持该选项,它将自动启用。要验证您的安装是否使用了 eBPF 主机路由,请在任何 Cilium pod 中运行 cilium status
,并查找报告 "Host Routing(主机路由)"状态的行,其中应显示 "BPF"。
如下, 在 Cilium 1.9 中引入了基于 eBPF 的主机路由后的性能提升:
从初始结果可以看出,当在 v5.10 内核上使用 Cilium 1.9(及更新版本) 的 eBPF 扩展时,直接路由下 Pod 到远程 Pod 会话的单流 TCP 吞吐量会翻倍,而不是由主机堆栈转发处理两个方向。同样,在避开主机堆栈时,测试中的 Pod 的 TCP 请求/响应事务性能提高了近 3 倍。
要求
- Kernel >= 5.10
- 直接路由(Direct-routing)配置或隧道
- 基于 eBPF 的 kube-proxy 替换
- 基于 eBPF 的伪装(masquerading)
实施
如上所述, "如果内核支持该选项,它将自动启用".
我们查看 Kernel >= 5.10 的情况:
Kernel >= 5.10
$ kubectl -n kube-system exec ds/cilium -- cilium status |grep "Host Routing"
Host Routing: BPF
如上所示, 在 Kernel >= 5.10 的环境: "3 台 Ubuntu 23.04 VM, Kernel 6.2, x86" 中, 已经自动启用 Host-Routing 基于 BPF 的功能
Notes
根据上一篇文章 - 绕过 IPTables 连接跟踪: 在无法使用 eBPF 主机路由 (Host-Routing) 的情况下,网络数据包仍需在主机命名空间中穿越常规网络堆栈,iptables 会增加大量成本。
所以, 在"3 台 Ubuntu 23.04 VM, Kernel 6.2, x86" 中, 其实是没必要设置"绕过 IPTables 连接跟踪" 的.
Kernel < 5.10
$ kubectl -n kube-system exec ds/cilium -- cilium status |grep "Host Routing"
Host Routing: Legacy
如上所示, 在 Kernel < 5.10 的环境: "3 台 Debian 10 开发板, Kernel 4.19, arm64" 中, Host-Routing 功能为 Legacy.
Notes
根据上一篇文章 - 绕过 IPTables 连接跟踪: 在无法使用 eBPF 主机路由 (Host-Routing) 的情况下,网络数据包仍需在主机命名空间中穿越常规网络堆栈,iptables 会增加大量成本。通过禁用所有 Pod 流量的连接跟踪 (connection tracking) 要求,从而绕过 iptables 连接跟踪器(iptables connection tracker),可将这种遍历成本降至最低。
所以, 在"3 台 Debian 10 开发板, Kernel 4.19, arm64" 中, 是有必要设置"绕过 IPTables 连接跟踪" 的.
总结
本文调优 Cilium, 启用 Host Routing(主机路由) 以完全绕过 iptables 和上层主机堆栈,并实现比常规 veth 设备操作更快的网络命名空间切换。
但是前提条件是 Kernel >= 5.10. (在没有条件启用 Host-Routing 的环境中, 可以设置"绕过 iptables 连接跟踪"以提升性能.)
至此,性能调优已完成:
- ️ 启用本地路由 (Native Routing)
- ️ 完全替换 KubeProxy
- ️ IP 地址伪装 (Masquerading) 切换为基于 eBPF 的模式
- ️ Kubernetes NodePort 实现在 DSR(Direct Server Return) 模式下运行
- ️ 绕过 iptables 连接跟踪 (Bypass iptables Connection Tracking)
- ️ 主机路由 (Host Routing) 切换为基于 BPF 的模式 (需要 Linux Kernel >= 5.10)
- 启用 IPv6 BIG TCP (需要 Linux Kernel >= 5.19)
- 修改 MTU 为巨型帧 (jumbo frames) (需要网络条件允许)
- 启用带宽管理器 (Bandwidth Manager) (需要 Kernel >= 5.1)
- 启用 Pod 的 BBR 拥塞控制 (需要 Kernel >= 5.18)
- 启用 XDP 加速 (需要 支持本地 XDP 驱动程序)
️参考文档
- Host-Routing - Tuning Guide — Cilium 1.13.4 documentation
- CNI Performance Benchmark — Cilium 1.13.4 documentation
- Cilium 1.9: Maglev, Deny Policies, VM Support, OpenShift, Hubble mTLS, Bandwidth Manager, eBPF Node-Local Redirect, Datapath Optimizations, and more
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
Cilium系列-9-主机路由切换为基于 BPF 的模式的更多相关文章
- vue3.x移动端页面基于vue-router的路由切换动画
移动端页面切换一般都具有动画,我们既然要做混合开发,做完之后还是不能看起来就像一个网页,所以我们基于vue-router扩展了一个页面切换push和pop的动画.这是一篇比较硬核的帖子,作者花了不少精 ...
- vue 2.0 路由切换以及组件缓存源代码重点难点分析
摘要 关于vue 2.0源代码分析,已经有不少文档分析功能代码段比如watcher,history,vnode等,但没有一个是分析重点难点的,没有一个是分析大命题的,比如执行router.push之后 ...
- Linux添加主机路由
Linux添加主机路由:参考:http://zhidao.baidu.com/link?url=50qQ232ZiJqq1iftHvBdPzZh-JlQGi1DZ8wvF-j9dvQYsKiNgc-6 ...
- ionic-native-transitions调用原生页面切换实现ionic路由切换
废话不多说:ionic-native-transitions调用原生页面切换实现ionic路由切换,从而大大提升ionic应用的性能. ionic-native-transitions是一个ionic ...
- AngularJS路由系列(1)--基本路由配置
本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● 路由的Big Picture ● $routeProvider配置路由 ● 使用template属性 ● 使用temp ...
- OSGi 系列(十八)之 基于注解的 Blueprint
OSGi 系列(十八)之 基于注解的 Blueprint 1. 注解实现 blueprint 第一步:bundle 添加 Bundle-Blueprint-Annotation <plugin& ...
- 继承Spring AbstractRoutingDataSource实现路由切换
继承Spring AbstractRoutingDataSource实现路由切换 原创 2016年05月11日 16:50:08 标签: mybatis / AbstractRoutingDataS ...
- Bing Maps进阶系列四:路由功能服务(RouteService)
Bing Maps进阶系列四:路由功能服务(RouteService) Bing Maps提供的路由功能服务(RouteService)可以实现多方位的计算地图上的路线指示,路径行程等功能,比如说实现 ...
- vue动画理解,进入、离开、列表过度和路由切换。
vue的动画对于很多初学者,甚至对很多老鸟来说也是很费劲,不容易控制的. 这篇文章讲vue动画的理解.其实没那么难. 动画理解 一个元素从A状态变成B状态,如果这个过程通过某种方式反应在视图上了,那么 ...
- vue路由切换时内容组件的滚动条回到顶部
在使用vue的时候会出现切换路由的时候滚动条保持在原来的位置,要切换路由的时候滚动条回到顶部才有更好的用户体验 1.当页面整体都要滚动到顶部的情况 router.afterEach(() => ...
随机推荐
- Python Requets库学习总结
快速开始 发送请求 >>> import requests >>> r = requests.get('https://api.github.com/events' ...
- 考前必备fa宝——对拍
2022.11.24:晚上zxs学长发来了他的博客,所以我仿照写一篇. https://www.cnblogs.com/Dita/p/duipai.html 对拍 对拍这个东西,就是可以比较两份代码跑 ...
- 一文梳理z-index和层叠上下文
前言 最近参与某前端项目架构改造,发现项目中滥用z-index,设置的值有几十种并且不统一.在对项目的z-index进行梳理和统一过程中也深入学习了一下z-index,并撰写成文,希望也能帮助到陌生的 ...
- 2023-03-29:如何高效计算三条线路选择方案?小A的旅行线路规划问题
2023-03-29:第一行有一个正整数n(3<=n<=100000),代表小A拟定的路线数量 第二行有n个正整数,第i个代表第i条路线的起始日期 第三行有n个正整数,第i个代表第i条路线 ...
- 2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达彼此的代价都是7。 求,允许施展一次魔法
2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7.施展魔法之后,A和B通过该边到达彼此的代价都是7. 求,允许施展一次魔法 ...
- .NET6项目连接数据库方式方法
前言 接上一篇Linux系统下创建dotnet项目,这一篇我们聊聊.NET6环境下dotnet项目连接数据库的方式方法,包括数据库字符串该如何配置.看了很多博主写的文章,连接数据库字符串配置的方式和位 ...
- ET介绍——组件式设计(优化版的ECS)
组件式设计 在代码复用和组织数据方面,面向对象可能是大家第一反应.面向对象三大特性继承,封装,多态,在一定程度上能解决不少代码复用,数据复用的问题.不过面向对象不是万能的,它也有极大的缺陷: 1. 数 ...
- springboot 项目国际化+登录拦截器
项目页面国际化 1.语言配置文件 需要下载插件Resource Bundle Editor 新建国际目录i18n 在properties配置文件中自定义 2.前端index页面要设置语言参数传递给后端 ...
- js 获取系统yyyyMMdd时间
var myDate = new Date(); var Time1 = myDate.toLocaleDateString()//yyyy/MM/dd 这个方法如果是1月份,会显示yyyy/M/dd ...
- Java(数组声明创建、初始化、特点、内存分析、边界)
数组的定义 数组是相同类型数据的有序集合 数组描述的是相同类型的若干数据,按照一定先后次序排序组合而成 其中,每一个数据称作一个数组元素,每个数组元素可以通过下标访问它们 1.数组声明和创建 声明 d ...