将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能。但是通过对 Cilium 不同模式的切换/功能的启用,可以进一步提升 Cilium 的网络性能。具体调优项包括不限于:
CONFIG_PREEMPT_NONE=y
tuned-adm profile network-latency
或 network-throughput
irqbalance
,将网卡中断引脚指向特定 CPU在网络/网卡设备/OS 等条件满足的情况下,我们尽可能多地启用这些调优选项,相关优化项会在后续文章逐一更新。敬请期待。
今天我们来将 Cilium 的 NodePort 实现从 SNAT 改为 DSR 以提升网络性能。
默认情况下,Cilium 的 eBPF NodePort 实现以 SNAT 模式运行。也就是说,当节点外部流量到达时,如果节点确定负载平衡器、NodePort 或具有外部 IP 的服务的后端位于远程节点,那么节点就会通过执行 SNAT 将请求重定向到代表自己的远程后端。这不需要额外更改 MTU。代价是,来自后端的回复需要额外跳回节点,在那里执行反向 SNAT 转换,然后再将数据包直接返回给外部客户端。
示例如下,Cilium 的 eBPF NodePort 实现以 SNAT 模式运行:
$ kubectl -n kube-system exec ds/cilium -- cilium status --verbose
...
KubeProxyReplacement Details:
Status: Strict
Socket LB: Enabled
Socket LB Tracing: Enabled
Socket LB Coverage: Full
Devices: eth0 192.168.2.3 (Direct Routing)
Mode: SNAT
SNAT 模式下,NodePort 后端 pod 在其他节点入向流量:
出向流量:
该设置可通过 loadBalancer.mode
Helm 选项更改为 dsr
,以便让 Cilium 的 eBPF NodePort 实现在 DSR 模式下运行。在这种模式下,后端直接回复外部客户端,而不需要额外的跳转,也就是说,后端通过使用服务 IP/port 作为源来回复。DSR 目前要求 Cilium 以本地路由模式部署,也就是说,它不能在任何一种隧道模式下工作。
DSR 模式流量如下:
DSR 模式的另一个优点是保留了客户端的源 IP,因此可以在后端节点对其进行策略匹配。而在 SNAT 模式下则无法做到这一点。鉴于一个特定的后端可被多个服务使用,后端需要知道它们需要回复的服务 IP/端口。
请注意,由于 Cilium 特定的 IP 选项可能会被底层网络结构丢弃,因此 DSR 模式在某些公共云提供商环境中可能无法使用。如果后端位于与处理给定 NodePort 请求的节点相距较远的节点上,在出现服务连接问题时,首先要检查 NodePort 请求是否实际到达了包含后端的节点。如果不是,则建议切换回默认 SNAT 模式作为一种解决方法。
此外,在某些实施源/目标 IP 地址检查的公共云提供商环境中(如 AWS),必须禁用检查才能使用 DSR 模式。
在启用仅 DSR 模式的无 kube proxy 环境中,上述 Helm 示例配置如下:
helm upgrade cilium cilium/cilium --version 1.13.4 \
--namespace kube-system \
--reuse-values \
--set loadBalancer.mode=dsr
Warning
前提是:
- 启用本地路由
- Cilium 完全替换 KubeProxy
$ kubectl -n kube-system exec ds/cilium -- cilium status --verbose|grep DSR
Mode: DSR
性能提升可以查看官方的 benchmark:
️️️
本文我们将 Cilium 的 NodePort 实现从 SNAT 模式切换为 DSR 的模式。相比 SNAT 模式,DSR 在"NodePort 后端 pod 在其他节点"时优势明显:
但是在公有云环境上需要注意启用的条件。
至此,性能调优已完成:
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.