惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
C
Check Point Blog
M
MIT News - Artificial intelligence
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
大猫的无限游戏
大猫的无限游戏
D
Docker
Last Week in AI
Last Week in AI
IT之家
IT之家
F
Fortinet All Blogs
A
About on SuperTechFans
P
Proofpoint News Feed
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog RSS Feed
博客园_首页
月光博客
月光博客
博客园 - 司徒正美
Y
Y Combinator Blog

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述
Kubernetes - kube-proxy 代理模式工程优化
2023-10-23 · via 蛮荆

2023-10-23 Cloud Native Kubernetes

概述

kube-proxy 是集群中运行在每个工作节点 (Node) 上面的网络代理,通过维护网络转发规则 (iptables, ipvs),将流量分发到对应的 Pod 中, 是实现 Service 功能 ClusterIP (虚拟 IP) 的重要组件。

kube-proxy 会通过 API Server 的通知消息来检测 Service 和 EndPoint 的变化,然后改变节点上的网络转发规则 (iptables, ipvs), kube-proxy 可以根据 EndPoint 的数据作为流量转发规则的指定依据。也就是说,kube-proxy 并不会直接就接收进入 Node 的流量, 而是会创建相应的 iptables 规则,将流量转发到 Service 对应的 Pod 中。

代理模式

下面着重介绍下 kube-proxy 内部实现的工程优化历史过程。

userspace

userspace 是 Kubernetes 早期的默认代理模式,这里简单提一下。

在这种模式中,对于每个 Service, kube-proxy 会在节点上随机选择一个端口作为 “代理端口”,然后新建 iptables 规则,将 Service 对应的 ClusterIP (虚拟 IP) + Port 重定向到 “代理端口”, 这样一来,任何发送到 Service 的请求都会被转发到 “代理端口”,最后转发到 Service 对应的 Pod 中。

图片来源: https://rtfm.co.ua/en/kubernetes-service-load-balancing-kube-proxy-and-iptables/

userspace 模式已经不再推荐使用,因为其存在显而易见的 性能问题: userspace 模式通过在用户空间中处理网络数据包来实现负载均衡和流量转发,这会引发用户态到内核态的上下文切换和数据拷贝。

iptables

创建一个 Service 时会得到一个对应的 ClusterIP (虚拟 IP),然后 API Server 通过所有工作节点 (Node) 上运行的 kube-proxy 组件, 为新创建的 Service 建立对应的 iptables 规则,确保任何发送到 Service 的请求被正确解析并转发到对应的 Pod 中。

在这种模式中,对于每个 Service, kube-proxy 会新建 iptables 规则,将 Service 对应的 ClusterIP (虚拟 IP) + Port 重定向到 Service 对应的 Pod, 这样一下,任何发送到 Service 的请求都会被转发到 Service 对应的 Pod 中。

图片来源: https://rtfm.co.ua/en/kubernetes-service-load-balancing-kube-proxy-and-iptables/

优化参数

字段 描述
syncPeriod iptables 规则的刷新周期 (例如,‘5s’、‘1m’、‘2h22m’)
minSyncPeriod iptables 规则被刷新的最小周期 (例如,‘5s’、‘1m’、‘2h22m’)

Kubernetes v1.28 版本开始,kube-proxy 的 iptables 模式采用了更精确的方法,只有在 Service 或 EndpointSlice 的值真正发生变化时才会进行更新。

相比于 userspace 模式,iptables 模式运行在内核态,所以性能要高出一个数量级,但是当集群中的节点数量较大时,iptables 也会遇到性能瓶颈, 因此这种模式只适用于小规模集群。

ipvs

在这种模式中,转发规则的维护过程、流量转发的过程和 iptables 模式类似,ipvs 虽然也是基于 netfilter 钩子函数实现并且工作在内核态,但是它使用哈希表作为底层数据结构, 所以性能要优于 iptables。

此外,ipvs 提供了更多的负载均衡算法选项:

rr  轮询调度
lc  最小连接数
dh  目标哈希
sh  源哈希
sed 最短期望延迟
nq  不排队调度

注意: ipvs 模式假定节点上已经安装了 ipvs 内核模块,当 kube-proxy 以 ipvs 代理模式启动时,如果节点未安装 ipvs 内核模块,则回退到 iptables 模式。

图片来源: https://rtfm.co.ua/en/kubernetes-service-load-balancing-kube-proxy-and-iptables/


ipvs 为什么优于 iptables

iptables 是一项 Linux 内核功能,目标是成为一个高效的防火墙,具有足够的灵活性来处理各种常见的数据包操作和过滤需求,但是其底层的链表数据结构的实现决定了, 每次添加或更新规则时需要遍历所有规则,最终控制平面时间复杂度为 O(N²), 数据平面时间复杂度为 O(N)。 根据社区统计,当集群中的 Service 数量超过 5000 个时,每增加一条 iptables 规则耗时将超过 10 分钟。

ipvs 是专门为负载平衡而设计的 Linux 内核功能,其底层数据结构为哈希表,时间复杂度为 O(1), 也就是说,大多数情况下其性能和集群规模无关 (回忆一下哈希表数据结构的最好情况和最坏情况)。

图片来源: https://www.tigera.io/blog/comparing-kube-proxy-modes-iptables-or-ipvs/

上图是针对 iptables 和 ipvs 模式进行的性能测试,从输出的图表结果来看,在 Service 数量不超过 1000 个时,两者之间的性能差异很小。

美中不足

虽然 ipvs 的性能要优于 iptables, 但是 ipvs 只负责负载均衡和流量转发功能,而一个完整的 Service 功能还包括数据包过滤、SNAT 等操作,这部分功能依然需要配合 iptables 来实现。 如果希望获得更强悍的性能,就需要从这个角度入手了,例如 扩展阅读第二篇文章 中提到的优化方法。

Reference

扩展阅读