Cilium系列-11-启用带宽管理器
系列文章
- Cilium 系列文章
前言
将 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, 启用带宽管理器, 以更有效地管理网络流量,改善整体应用的延迟和吞吐量。
测试环境
- Cilium 1.13.4
- K3s v1.26.6+k3s1
- OS
- 3 台 Ubuntu 23.04 VM, Kernel 6.2, x86
带宽管理器
Cilium 的带宽管理器(Bandwidth Manager)负责更有效地管理网络流量,目的是改善整体应用的延迟和吞吐量。
除了原生支持 Kubernetes Pod bandwidth annotations 外,带宽管理器(首次在 Cilium 1.9 中引入)还在所有面向外部的网络设备上设置公平队列(FQ)队列规则,以支持 TCP 堆栈步调(例如 EDT/BBR),并为网络堆栈设置最佳的服务器级 sysctl 设置。
带宽管理器的功能主要集中在两个方面,即从上层协议和从队列规范的角度。
带宽管理器启用后,默认情况下会将 TCP 拥塞控制算法切换为 BBR,从而实现更高的带宽和更低的延迟,尤其是面向互联网的流量。它将内核网络堆栈配置为更面向服务器的 sysctl 设置,这些设置已在生产环境中证明是有益的。它还重新配置了流量控制队列规则(Qdisc)层,以便在 Cilium 使用的所有面向外部的网络设备上使用多队列 Qdiscs 和公平队列(FQ)。切换到公平队列后,带宽管理器还在 eBPF 的帮助下实现了对最早出发时间 Earliest Departure Time(EDT)速率限制的支持,并且现在原生支持 kubernetes.io/egress-bandwidth
Pod 注释。
这也消除了对带宽 CNI 插件链的需求,因为该插件使用了 TBF(Token Bucket Filter, 令牌桶过滤器),在可扩展性方面受到限制。通过基于 EDT 的模型,可以避免 Qdisc 层的全局锁定,尤其是在多队列网卡的情况下。Cilium 的 eBPF 数据路径会将网络流量分类到每个节点的聚合中,然后在将数据包传递到 FQ leaf Qdiscs 前不久,通过在出口的网络数据包上设置最早离开时间戳,执行用户定义的 kubernetes.io/egress-bandwidth
速率。Qdiscs 维护每个流的状态,并根据数据包的时间戳来安排数据包的离开时间,确保数据包不会在时间戳规定的时间之前被发送出去。通过 eBPF 的灵活性,对 Pod 聚合体的分类不仅适用于直接路由,也适用于隧道或使用 L7 代理的情况。
与 eBPF 和 FQ 相比,在使用 HTB(Hierarchical Token Bucket, 分层令牌桶)进行速率限制的情况下,对应用延迟进行的评估表明,在改善传输延迟的同时,CPU 利用率也能显著降低。当 eBPF 和 FQ 结合使用时,第 95 百分位的延迟降低了约 20 倍,第 99 百分位的延迟降低了约 10 倍。
需求
- Kernel >= 5.1
- Direct-routing 配置 或 隧道
- 基于 eBPF 的 kube-proxy 替换
实战: 启用带宽管理器
要启用带宽管理器:
helm upgrade cilium cilium/cilium --version 1.13.4 \--namespace kube-system \--reuse-values \--set bandwidthManager.enabled=true
验证
状态验证
要验证您的安装是否与带宽管理器一起运行,请在任何 Cilium pod 中运行 cilium status
,并查找报告 "BandwidthManager"状态的行,该行应显示 "EDT with BPF"。
具体如下:
$ kubectl -n kube-system exec ds/cilium -- cilium status | grep BandwidthManager
BandwidthManager: EDT with BPF [CUBIC] [eth0]
带宽管理器功能验证
下面是一个应用 Pod 的部署示例,由于使用了 kubernetes.io/egress-bandwidth
注释,其出口带宽被限制为 50 Mbit/s:
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:name: iperf3labels:app: iperf3
spec:selector:matchLabels:app: iperf3template:metadata:labels:app: iperf3annotations:kubernetes.io/egress-bandwidth: '50M'spec:containers:- name: iperf3image: clearlinux/iperf:3command: ['/bin/sh', '-c', 'sleep 1d']ports:- containerPort: 5201
EOF
结果如下:
$ k3s kubectl get pod -o wide -l app=iperf3
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
iperf3-g54rg 1/1 Running 0 2m9s 10.0.0.127 cilium-62-1 <none> <none>
iperf3-4fwnf 1/1 Running 0 97s 10.0.1.101 cilium-62-2 <none> <none>
iperf3-688m4 1/1 Running 0 65s 10.0.2.247 cilium-62-3 <none> <none>
选择一个 pod 作为 server(cilium-62-2 node 上的为 server), 另一个作为 client(cilium-62-3 node 上的为client).
Server (iperf3-4fwnf) 运行的命令为:
kubectl exec -it iperf3-4fwnf -- iperf3 -s -f M
Client (iperf3-688m4) 运行的命令为:
$ kubectl exec -it iperf3-688m4 -- iperf3 -c 10.0.1.101 -f m
Connecting to host 10.0.1.101, port 5201
[ 5] local 10.0.2.247 port 33300 connected to 10.0.1.101 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 7.51 MBytes 63.0 Mbits/sec 0 385 KBytes
[ 5] 1.00-2.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 2.00-3.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 3.00-4.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 4.00-5.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 5.00-6.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 6.00-7.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 7.00-8.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 8.00-9.00 sec 5.65 MBytes 47.4 Mbits/sec 0 385 KBytes
[ 5] 9.00-10.00 sec 6.46 MBytes 54.2 Mbits/sec 0 385 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 59.2 MBytes 49.7 Mbits/sec 0 sender
[ 5] 0.00-10.02 sec 57.0 MBytes 47.8 Mbits/sec receiveriperf Done.
实测带宽为: 49.7 Mbits/sec 47.8 Mbits/sec, 确实实现了 50 Mb/s 的带宽限制. 👍️👍️👍️
总结
本文继续调优 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, 支持的 NICs: mlx4, mlx5)
- 由于没有支持的网卡, 无法完成验证
- ❌ 修改 MTU 为巨型帧 (jumbo frames) (需要网络条件允许)
- ✔️ 启用带宽管理器 (Bandwidth Manager) (需要 Kernel >= 5.1)
- 启用 Pod 的 BBR 拥塞控制 (需要 Kernel >= 5.18)
- 启用 XDP 加速 (需要 支持本地 XDP 驱动程序)
📚️参考文档
- Bandwidth Manager - Tuning Guide — Cilium 1.13.4 documentation
- Bandwidth Manager - Cilium 1.9: Maglev, Deny Policies, VM Support, OpenShift, Hubble mTLS, Bandwidth Manager, eBPF Node-Local Redirect, Datapath Optimizations, and more
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
相关文章:

Cilium系列-11-启用带宽管理器
系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, 可以进一步提升 Cilium 的网络性能. 具体调优项包括不限于: 启用本地路由(Native Routing)完全替换 KubeProx…...

无人机自动返航的关键技术有哪些
无人机的广泛应用使得无人机自动返航技术变得至关重要。在各种应对意外情况的背景下,无人机自动返航技术的发展对确保无人机的安全,以及提高其应用范围具有重要意义。接下来,便为大家详细介绍无人机自动返航所运用到的关键技术。 一、定位与导…...

Vision Transformer (ViT):图像分块、图像块嵌入、类别标记、QKV矩阵与自注意力机制的解析
作者:CSDN _养乐多_ 本文将介绍Vision Transformers (ViT)中的关键点。包括图像分块(Image Patching)、图像块嵌入(Patch Embedding)、类别标记、(class_token)、QKV矩…...

Mybatis:一对多映射处理
Mybatis:一对多映射处理 前言一、概述二、创建数据模型三、问题四、解决方案1、方案一:collection(嵌套结果)2、方案二:分步查询(嵌套查询) 前言 本博主将用CSDN记录软件开发求学之路上的亲身所…...

HTML+CSS+JavaScript:全选与反选案例
一、需求 1、单击全选按钮,下面三个复选框自动选中,再次单击全选按钮,下面三个复选框自动取消选中 2、当下面三个复选框全都选中时,全选按钮自动选中,下面三个复选框至少有一个未选中,全选按钮自动取消选…...

Python 程序设计入门(001)—— 安装 Python(Windows 操作系统)
Python 程序设计入门(001)—— 安装 Python(Windows 操作系统) 目录 Python 程序设计入门(001)—— 安装 Python(Windows 操作系统)一、下载 Python 安装包二、安装 Python三、测试&…...

【redis】创建集群
这里介绍的是创建redis集群的方式,一种是通过create-cluster配置文件创建部署在一个物理机上的伪集群,一种是先在不同物理机启动单体redis,然后通过命令行使这些redis加入集群的方式。 一,通过配置文件创建伪集群 进入redis源码…...

linux 配置nacos遇见的问题及解决办法
本次的集群是启动一个服务的三个不同端口,配置如下: 一.application.properties 加上下列配置,目的是使用自己的mysql数据库: spring.datasource.platformmysql db.num1 db.url.0jdbc:mysql://127.0.0.1:3306/nacos_config?s…...

小程序开发趋势:探索人工智能在小程序中的应用
第一章:引言 小程序开发近年来取得了快速的发展,成为了移动应用开发的重要一环。随着人工智能技术的飞速发展,越来越多的企业开始探索如何将人工智能应用于小程序开发中,为用户提供更智能、便捷的服务。本文将带您一起探索人工智能…...

基于埋点日志数据的网络流量统计 - PV、UV
水善利万物而不争,处众人之所恶,故几于道💦 文章目录 一、 网站总流量数统计 - PV 1. 需求分析 2. 代码实现 方式一 方式二 方式三:使用process算子实现 方式四:使用process算子实现 二、网站独立访客数统计 - UV 1. …...

cuda入门demo(2)——最基础的二方向sobel
⚠️主要是自己温习用,只保证代码正确性,不保证讲解的详细性。 今天继续总结cuda最基本的入门demo。很多教程会给你说conv怎么写,实际上sobel也是conv,并且conv本身已经用torch实现了。 之前在课题中尝试了sobel的变体࿰…...

软件外包开发的后台开发语言
在软件外包开发中,后台语言的选择通常取决于项目需求、客户偏好、团队技能和开发效率。今天和大家分享一些常用的后台语言及选择它们的原因,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。…...

自动驾驶感知系统-全球卫星定位系统
卫星定位系统 车辆定位是让无人驾驶汽车获取自身确切位置的技术,在自动驾驶技术中定位担负着相当重要的职责。车辆自身定位信息获取的方式多样,涉及多种传感器类型与相关技术。自动驾驶汽车能够持续安全可靠运行的一个关键前提是车辆的定位系统必须实时…...

数据结构 | 基本数据结构——队列
目录 一、何谓队列 二、队列抽象数据类型 三、用Python实现队列 四、模拟:传土豆 五、模拟:打印任务 5.1 主要模拟步骤 5.2 Python实现 一、何谓队列 队列是有序集合,添加操作发生在“尾部”,移除操作则发生在“头部”。新…...

QT在label上透明绘图(二)
前面步骤参考前一篇文章 QT在label上透明绘图 一、给TransparentLabel类添加double transparency;变量, 二、ui添加doublespinbox,调整透明参数 void MainWindow::on_doubleSpinBox_valueChanged(double arg1) {transparentLabel->transparencyarg1;…...

微信小程序使用editor富文本编辑器 以及回显 全屏弹窗的模式
<!--富文本接收的位置--><view class"white-box"><view class"title"><view class"yellow-fence"></view><view class"v1">教研记录</view></view><view class"add-btn"…...

在CSDN学Golang场景化解决方案(基于gin框架的web开发脚手架)
一,中间件统一实现Oauth2身份验证 在Golang基于Gin框架开发Web应用程序时,可以使用gin-oauth2来实现Oauth2身份验证。下面是简单的步骤: 安装gin-oauth2包:go get github.com/appleboy/gin-oauth2导入依赖:import &q…...

关于Express 5
目录 1、概述 2、Express 5的变化 2.1 弃用或删除内容的列表: app.param(name,fn)名称中的前导冒号(:) app.del() app.param(fn) 复数方法名 res.json࿰…...

ftrace 原理详细分析
》内核新视界文章汇总《 文章目录 ftrace 原理分析1 简介2 ftrace 的编译器支持2.1 HAVE_FUNCTION_TRACER 选项对 ftrace 的支持2.2 HAVE_DYNAMIC_FTRACE 选项对动态 ftrace 的支持 3 ftrace 的初始化4 function trace 流程5 总结 ftrace 原理分析 1 简介 ftrace 是一个内核…...

UWB定位技术和蓝牙AOA有哪些不同?-高精度室内定位技术对比
UWB超宽带定位 UWB(Ultra Wide Band )即超宽带技术,它是一种无载波通信技术,利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。传统的定位技术是根据信号强弱来判别物体位置,信号强弱受外界…...

【RabbitMQ】golang客户端教程2——工作队列
任务队列/工作队列 在上一个教程中,我们编写程序从命名的队列发送和接收消息。在这一节中,我们将创建一个工作队列,该队列将用于在多个工人之间分配耗时的任务。 工作队列(又称任务队列)的主要思想是避免立即执行某些…...
芯旺微冲刺IPO,车规级MCU竞争白热化下的“隐忧”凸显
在汽车智能化和电动化发展带来的巨大蓝海市场下,产业链企业迎来了一波IPO小高潮。 日前,上海芯旺微电子技术股份有限公司(以下简称“芯旺微”)在科创板的上市申请已经被上交所受理,拟募资17亿元,用于投建车…...

HTML <s> 标签
例子 可以像这样标记删除线文本: 在 HTML 5 中,<s>仍然支持</s>已经不支持这个标签了。 浏览器支持 元素ChromeIEFirefoxSafariOpera<s>YesYesYesYesYes 所有浏览器都支持 <s> 标签。 定义和用法 <s> 标签可定义加…...

微信小程序 - scroll-view组件之上拉加载下拉刷新(解决上拉加载不触发)
前言 最近在做微信小程序项目中,有一个功能就是做一个商品列表分页限流然后实现上拉加载下拉刷新功能,遇到了一个使用scroll-viwe组件下拉刷新事件始终不触发问题,网上很多说给scroll-view设置一个高度啥的就可以解决,有些人设置了…...

rust usize与i64怎么比较大小?
在Rust中, usize 和 i64 是不同的整数类型,它们的位数和表示范围可能不同。因此,直接比较 usize 和 i64 是不允许的。如果需要比较它们的大小,可以将它们转换为相同的类型,然后进行比较。 要将 usize 转换为 i64 &…...

电脑更新win10黑屏解决方法
电脑更新win10黑屏解决方法 电脑黑屏出现原因解决步骤 彻底解决 电脑黑屏 出现原因 系统未更新成功就关机,导致系统出故障无法关机 解决步骤 首先长安电源键10s关机 按电源键开机,出现logo时按F8进入安全模式。 进入自动修复环境后,单击…...

STM32入门——外部中断
中断系统概述 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行中断优先级ÿ…...

【计算机网络】NAT及Bridge介绍
OSI七层模型 七层模型介绍及举例 为通过网络将人类可读信息通过网络从一台设备传输到另一台设备,必须在发送设备沿 OSI 模型的七层结构向下传输数据,然后在接收端沿七层结构向上传输数据。 数据在 OSI 模型中如何流动 库珀先生想给帕尔梅女士发一封电…...

封装动态SQL的插件
最近根据公司的业务需要封装了一个简单的动态SQL的插件,要求是允许用户在页面添加SQL的where条件,然后开发者只需要给某个接口写查询对应的表,参数全部由插件进行拼接完成。下面是最终实现: 开发人员只需要在接口写上下面的查询SQ…...

C# Microsoft消息队列服务器的使用 MSMQ
先安装消息队列服务器 private static readonly string path ".\\Private$\\myQueue";private void Create(){if (!MessageQueue.Exists(path)){MessageQueue.Create(path);}}private void Send(){Stopwatch stopwatch new Stopwatch();stopwatch.Start();Message…...