Cilium系列-6-从地址伪装从IPtables切换为eBPF
系列文章
前言
将 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 eBPF IP 地址伪装(Masquerading)模式以提升网络效率.
测试环境
- Cilium 1.13.4
- K3s v1.26.6+k3s1
- OS
- 3台 Ubuntu 23.04 VM, Kernel 6.2, x86
IP 地址伪装(Masquerading)
Pod 使用的 IPv4 地址通常是从 RFC1918 专用地址块中分配的,因此不可公开路由。Cilium 会自动将离开群集的所有流量的源 IP 地址伪装成 node 的 IPv4 地址,因为 node 的 IP 地址已经可以在网络上路由。如下图:

对于 IPv6 地址,只有在使用 iptables 执行模式时才会进行伪装。
如果要禁用该选项:
- 对于离开主机的 IPv4 流量,可使用选项
enable-ipv4-masquerade:false, - 对于 IPv6 流量,可使用选项
enable-ipv6-masquerade:false。
配置
设置可路由 CIDR
默认行为是排除本地节点 IP 分配 CIDR 范围内的任何目的地。如果 pod IP 可通过更广泛的网络进行路由,则可使用选项:ipv4-native-routing-cidr: 10.0.0.0/8(或 IPv6 地址的 ipv6-native-routing-cidr: fd00::/100)指定该网络,在这种情况下,该 CIDR 范围内的所有目的地都不会被伪装。
设置伪装接口
请参阅下文配置伪装接口。
基于 eBPF 的 IP 地址伪装模式
如果没有明确指定, 默认使用基于 IPTables 的 IP 地址伪装模式. 这是传统的实现方式,可以在所有内核版本上运行。默认配置检查如下:
$ kubectl -n kube-system exec ds/cilium -- cilium status | grep Masquerading
Masquerading: IPTables [IPv4: Enabled, IPv6: Disabled]
而基于 eBPF 的实现是最有效的实现。它需要 Linux 内核 4.19,并可通过 bpf.masquerade=true helm 选项启用。
当前的实现依赖于 BPF NodePort 功能。未来将移除该依赖关系(GitHub 问题 13732)。
具体命令为:
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--reuse-values \
--set bpf.masquerade=true
伪装只能在运行 eBPF 伪装程序的网卡设备上进行。这意味着,如果输出网卡设备运行了该程序,从 pod 发送到外部地址的数据包将被伪装(伪装到输出网卡设备的 IPv4 地址)。如果未指定,程序将自动连接到 BPF NodePort 网卡设备检测机制选择的网卡设备上。要手动更改,请使用devices helm 选项。使用 cilium status 来确定程序运行在哪些网卡设备上:
$ kubectl -n kube-system exec ds/cilium -- cilium status | grep Masquerading
Masquerading: BPF [eth0] 10.0.0.0/22 [IPv4: Enabled, IPv6: Disabled]
如上输出, IPv6: Disabled, 这是因为基于 eBPF 的伪装目前不支持 IPv6 流量。
从上面的输出来看,程序正在 eth0 网卡设备上运行。
基于 eBPF 的伪装可伪装以下 IPv4 L4 协议的数据包:
- TCP
- UDP
- ICMP(仅 Echo request 和 Echo reply)
默认情况下,除了发往其他集群节点的数据包外,所有从 pod 发往 ipv4-native-routing-cidr 范围之外 IP 地址的数据包都会被伪装。排除的 CIDR 显示在上述 cilium status(10.0.0.0/22)输出中。
为实现更精细的控制,Cilium 在 eBPF 中实现了 ip-masq-agent,可通过 ipMasqAgent.enabled=true helm 选项启用。
基于 eBPF 的 ip-masq-agent 支持在配置文件中设置 nonMasqueradeCIDRs 和 masqLinkLocal 选项。从 pod 发送到属于 nonMasqueradeCIDRs 中任何 CIDR 的目的地的数据包都不会被伪装。如果配置文件为空,agent 将提供以下非伪装 CIDR:
10.0.0.0/8172.16.0.0/12192.168.0.0/16100.64.0.0/10192.0.0.0/24192.0.2.0/24192.88.99.0/24198.18.0.0/15198.51.100.0/24203.0.113.0/24240.0.0.0/4
Note
关于使用
ip-masq-agent的配置, 本次暂不进行演示, 感兴趣的小伙伴可以自行尝试.
此外,如果 masqLinkLocal 未设置或设置为 false,则 169.254.0.0/16 会被附加到非屏蔽 CIDR 列表中。
Agent 使用 Fsnotify 跟踪配置文件的更新
下面的示例展示了如何通过 ConfigMap 配置 agent 并进行验证:
apiVersion: v1
kind: ConfigMap
metadata:
name: ip-masq-agent
data:
config: |
nonMasqueradeCIDRs:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
masqLinkLocal: true
$ kubectl create -n kube-system -f https://raw.githubusercontent.com/cilium/cilium/1.13.4/examples/kubernetes-ip-masq-agent/rfc1918.yaml
$ # Wait ~60s until the ConfigMap is propagated into the configuration file
$ kubectl -n kube-system exec ds/cilium -- cilium bpf ipmasq list
IP PREFIX/ADDRESS
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
或者,在通过 Helm 安装 Cilium 时,可以通过 --set ipMasqAgent.config.nonMasqueradeCIDRs='{10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}' 和 --set ipMasqAgent.config.masqLinkLocal=false 来配置上述 ip-masq-agent。
总结
本文我们将地址伪装从 IPTables 切换为基于 eBPF 的模式. 相比 IPTables 模式, 基于 eBPF 的实现是最有效的实现。
至此, 性能调优已完成:
- ️ 启用本地路由(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 驱动程序)
️参考文档
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
Cilium系列-6-从地址伪装从IPtables切换为eBPF的更多相关文章
- Adobe系列软件下载地址
在前些上传的文章中已经讲了如何激活Adobe系列软件,在这放上Adobe系列软件下载地址: 1.Adobe After Effects 2017-14.0 32位下载地址: 链接:http://pan ...
- RHEL7配置端口转发和地址伪装
说明:这里是Linux服务综合搭建文章的一部分,本文可以作为Linux上使用firewalld做端口转发和地址伪装以及外网访问内网的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭 ...
- C# 视频监控系列:学习地址汇总
原文地址:http://www.cnblogs.com/over140/archive/2009/04/07/1429308.html 前言 对于视频监控系统大家应该是不陌生的,实施的路况信息.地铁. ...
- 获取IP地址 & 伪装IP地址发送请求
//获取请求客户端IP地址 public final static String getIpAddress(HttpServletRequest request) throws IOExcepti ...
- 分分钟学会系列:mac地址泛洪攻击实验
一.实验目的: 通过实战深入理解mac地址泛洪攻击的原理. 二.实验原理: 交换机中有一张非常重要的表,叫做mac表,这个表是一个硬件组成的表,主要是完成快速转发.mac表有大小限制,不同的交换机的m ...
- Windows Mac地址伪装步骤
本文介绍Windows上Mac地址修改方法,适用于网络环境绑定了Mac地址需要修改上网的情况. 工具/原料 PC电脑一台 Windows系统 方法/步骤 点击右下角图标. 点击打开网络和共享中心. 点 ...
- iOS7入门开发全系列教程新地址
包括了系列1所有.系列2所有,系列3部分(进行中) 由于大家都知道的原因,换了github保存: https://github.com/eseedo/kidscoding 假设下载有问题能够留言,请在 ...
- linux学习系列博客地址汇总
2018-09-28 16:03:43 CentOS7 yum命令:这是一个用来管理rpm包进行自动化安装的C/S模式的一个程序. CentOS7(无图形界面)支持中文显示的办法:系统安装好之后,有可 ...
- iOS开发系列-打印内存地址
打印内存地址 基本数据类型 定义一个基本数据类型,会根据变量类型分配对应的内存空间.比如定义一个int类型的变量a. int a = 10; 内存如下 输入变量a在内存中内存地址 NSLog(@&qu ...
- .net core系列源码地址介绍
很早就想写.net core相关教程内容了,但是一方面感觉东西太多了,一方面是太懒了,最近才下定决心,一定要写点东西出来,希望能支持一下国内.net 的尴尬处境 好了,先从.net core开源开始吧 ...
随机推荐
- C# 禁用窗口激活
如果界面点击时,不想让窗口激活,可以按如下操作: 1 public MainWindow() 2 { 3 InitializeComponent(); 4 SourceInitialized += O ...
- Pytorch数据操作
1.Pytorch中tensor的生成与访问 可以使用arange()创建一个张量:如,torch.arange(12)创建0开始的前12个整数: 除非特殊指定,否则新的张量将存放在内存中,并采用CP ...
- SaaS化开源项目之HouseKeeper云上部署实践
摘要:华为云DTSE技术专家从源码构建.应用部署到系统调测,详细解读云原生SaaS应用构建的全过程. 本文分享自华为云社区<HouseKeeper云上部署实践>,作者:华为云DTSE. H ...
- 2022-05-19:给定一个数组arr,给定一个正数M, 如果arr[i] + arr[j]可以被M整除,并且i < j,那么(i,j)叫做一个M整除对。 返回arr中M整除对的总数量。 来自微软。
2022-05-19:给定一个数组arr,给定一个正数M, 如果arr[i] + arr[j]可以被M整除,并且i < j,那么(i,j)叫做一个M整除对. 返回arr中M整除对的总数量. 来自 ...
- 2022-02-13:k8s安装gitlab,yaml如何写?
2022-02-13:k8s安装gitlab,yaml如何写? 答案2022-02-13: yaml如下: apiVersion: apps/v1 kind: Deployment metadata: ...
- C++中的字符串编码处理
今天由于在项目中用到一些与C++混合开发的东西 ,需要通过socket与C++那边交换数据,没啥特别的,字节码而已,两边确定一种编码规则就行了.我们确定的UTF-8.关于C++的 这种又是宽字节 又是 ...
- ESlint配置详解
开发中出现eslint提示代码格式错误,有时候不明白其配置规范,是件很头疼的事情到处找api又是半天:so记录一份配置详情便于开发中翻阅 { // 环境定义了预定义的全局变量. "env&q ...
- LINIUX 查询命令的 区别 chich whereis locate fing
我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索: which 查看可执行文件的位置. whereis 查看文件的位置. locate 配合数据库查看文件位置 ...
- Python time strftime() 方法的使用
1.描述 strftime() 用于格式化时间,返回以可读字符串表示的时间,格式自定义. 2.说明 python中日期和时间的格式化符号有很多,下面列举常用的符号: %y 两位数的年份表示(00-9 ...
- CANoe _ Panel面板的创建过程
在Canoe中创建Panel面板,用于显示和操作CAN网络的数据和信号,遵循以下步骤: 1.打开Canoe 启动Canoe软件. 2.打开项目 在Canoe的菜单栏中,选择"File&quo ...