Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >kubernetes 中 ipvs 连接复用引发的系列问题

kubernetes 中 ipvs 连接复用引发的系列问题

原创
作者头像
imroc
修改于 2023-12-14 06:59:45
修改于 2023-12-14 06:59:45
4.2K0
举报

本文摘自 kubernetes 学习笔记

背景

Kubernetes 社区里面有一个讨论已久的 bug (#81775),这个问题是当 client 对 service 发起大量新建 TCP 连接时,新的连接被转发到 Terminating 或已完全销毁的旧 Pod 上,导致持续丢包 (报错 no route to host),其根因是内核 ipvs 连接复用引发,本文来详细掰扯下。

conn_reuse_mode 简介

在介绍原因之前,我们先介绍下 conn_reuse_mode 这个内核参数,它是以下两个 patch 引入的:

  1. year 2015 d752c364571743d696c2a54a449ce77550c35ac5
  2. year 2016 f719e3754ee2f7275437e61a6afd520181fdd43b

其目的是:

  1. client ip:client port 复用发生时,对于 TIME_WAIT 状态下的 ip_vs_conn,进行重新调度,使得 connection 在 rs 上的分布更均衡,以提高性能。
  2. 如果该 mode 是 0,则会复用旧 ip_vs_conn 里的 rs,使得连接更不均衡。

所以当 conn_reuse_mode 为 0 表示启用 ipvs 连接复用,为 1 表示不复用,是不是有点反直觉?这个确实也比较有争议。

conn_reuse_mode=1 的 bug

开启这个内核参数 (conn_reuse_mode=1) 本意是为了提高新建的性能,实际结果是大幅度降低了性能,实际测试中发现 cps 从 3w 降低到了 1.5K,这也表明内核社区的一些 patch 没有经过严格的性能测试

开启这个内核参数实际就表示 ipvs 转发时不做连接复用,每次新建的连接都会重新调度 rs 并新建 ip_vs_conn,但它的实现有个问题: 在新建连接时 (SYN 包),如果 client ip:client port 匹配到了 ipvs 旧连接 (TIME_WIAT 状态),且使用了 conntrack,就会丢掉第一个 SYN 包,等待重传后 (1s) 才能成功建连,从而导致建连性能急剧下降。

Kubernetes 社区也发现了这个 bug,所以当 kube-proxy 使用 ipvs 转发模式时,默认将 conn_reuse_mode 置为 0 来规避这个问题,详见 PR #71114 与 issue #70747

conn_reuse_mode=0 引发的问题

由于 Kubernetes 为了规避 conn_reuse_mode=1 带来的性能问题,在 ipvs 模式下,让 kube-proxy 在启动时将 conn_reuse_mode 置为了 0 ,即使用 ipvs 连接复用的能力,但 ipvs 连接复用有两个问题:

  1. 只要有 client ip:client port 匹配上 ip_vs_conn (发生复用),就直接转发给对应的 rs,不管 rs 当前是什么状态,即便 rs 的 weight 为 0 (通常是 TIME_WAIT 状态) 也会转发,TIME_WAIT 的 rs 通常是 Terminating 状态已销毁的 Pod,转发过去的话连接就必然异常。
  2. 高并发下大量复用,没有为新连接没有调度 rs,直接转发到所复用连接对应的 rs 上,导致很多新连接被 "固化" 到部分 rs 上。

业务中实际遇到的现象可能有很多种:

  1. 滚动更新连接异常。 被访问的服务滚动更新时,Pod 有新建有销毁,ipvs 发生连接复用时转发到了已销毁的 Pod 导致连接异常 (no route to host)。
  2. 滚动更新负载不均。 由于复用时不会重新调度连接,导致新连接也被 "固化" 在某些 Pod 上了。
  3. 新扩容的 Pod 接收流量少。 同样也是由于复用时不会重新调度连接,导致很多新连接被 "固化" 在扩容之前的这些 Pod 上了。

规避方案

我们知道了问题原因,那么在 ipvs 转发模式下该如何规避呢?我们从南北向和东西向分别考虑下。

南北向流量

  1. 使用 LB 直通 Pod。对于南北向流量,通常依赖 NodePort 来暴露,前面的负载均衡器将流量先转到 NodePort 上,然后再通过 ipvs 转发到后端 Pod。现在很多云厂商都支持 LB 直通 Pod,这种模式下负载均衡器直接将请求转发到 Pod,不经过 NodePort,也就没有 ipvs 转发,从而在流量接入层规避这个问题。
  2. 使用 ingress 转发。在集群中部署 ingress controller (比如 nginx ingress),流量到达 ingress 再向后转时 (转发到集群内的 Pod),不会经过 service 转发,而是直接转发到 service 对应的 Pod IP:Port,也就绕过了 ipvs。Ingress controller 本身结合使用前面所说的 LB 直通 Pod 方式部署,效果更佳。

东西向流量

集群内的服务间调用 (东西向流量),默认还是会走 ipvs 转发。对于有这种高并发场景的业务,我们可以考虑使用 Serivce Mesh (如 istio) 来治理流量,服务间转发由 sidecar 代理,并且不会经过 ipvs。

终极方案: 内核修复

conn_reuse_mode=1 引发性能急需下降的 bug,目前在腾讯云提供的 TencentOS-kernel 开源内核已修复,对应 PR #17TKE 上的解决方案就是使用这个内核 patch,依赖禁用 ipvs 连接复用 (conn_reuse_mode=1),这样同时也就解决了 ipvs 连接复用引发的系列问题,且经过了大规模生产验证。

不过以上修复并未直接合并到 linux 社区,当前已有两个相关 patch 合并到了 linux 内核主干 (自 v5.9),分别解决 conn_reuse_mode 为 0 和 1 时的上述 bug,其中一个也是借鉴了腾讯云修复的思路,详见 k8s issue #93297

如果你使用了 v5.9 以上的内核,理论上就没有本文所述的问题了。既然 v5.9 以上的内核已修复上述 bug,那么 kube-proxy 就无需显式去设置 conn_reuse_mode 这个内核参数了,这也是 PR #102122 所做的事。不过值得注意的是,社区 patch 目前并未看到有大规模的生产验证,试用有风险。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入kube-proxy ipvs模式的conn_reuse_mode问题
在高并发、短连接的场景下,kube-proxy ipvs 存在 rs 删除失败或是延迟高的问题,社区也有不少 Issue 反馈,比如kube-proxy ipvs conn_reuse_mode setting causes errors with high load from single client[1]。文本对这些问题进行了梳理,试图介绍产生这些问题的内部原因。由于能力有限,其中涉及内核部分,只能浅尝辄止。
米开朗基杨
2021/06/09
3.3K0
深入kube-proxy ipvs模式的conn_reuse_mode问题
云计算网络技术内幕 (24) 向云原生进军 (下)
我们知道,Kubernetes是为微服务化的应用提供的运行平台,也就是说,Kubernetes内部会有大量的微服务,应用之间各个模块的调用都需要通过service名称来进行。因此,使用传统的负载均衡器,或在1-2台服务器上部署单机/主备方式工作的软件负载均衡,会遇到性能扩展的瓶颈。
用户8289326
2023/09/06
2600
云计算网络技术内幕 (24) 向云原生进军 (下)
TKE集群CLB 回环问题总结
使用 TKE 的内部和外部客户,经常会遇到因 CLB 回环问题导致服务访问不通或访问 Ingress 几秒延时的现象,本文就此问题介绍下相关背景、原因以及一些思考与建议。
聂伟星
2021/02/05
4.8K1
绕过conntrack,使用eBPF增强 IPVS优化K8s网络性能
作者范建明、洪志国、张浩,均为腾讯云容器产品中心高级工程师,负责容器网络和Service Mesh,容器Runtime,调度等相关研发工作。
腾讯云原生
2020/08/27
7.5K1
Kubernetes 疑难杂症排查分享: 诡异的 No route to host
大家好,我是 roc,来自腾讯云容器服务(TKE)团队,之前发过一篇干货满满的爆火文章 Kubernetes 网络疑难杂症排查分享,包含多个疑难杂症的排查案例分享,信息量巨大。这次我又带来了续集,只讲
imroc
2019/12/16
4.1K0
Kubernetes 疑难杂症排查分享: 诡异的 No route to host
vivo AI计算平台 Kubernetes集群Ingress网关实践
vivo 人工智能计算平台小组从 2018 年底开始建设 AI 计算平台至今,已经在 kubernetes 集群、以及离线的深度学习模型训练等方面,积累了众多宝贵的开发、运维经验,并逐步打造出稳定的基础容器平台 - AI 容器平台(VContainer)。为了支撑公司 AI 在线业务的发展,满足公司对算力资源的高效调度管控需求,需要将在线业务,主要包括 C 端、推理等业务,由原来的虚拟机或物理机迁移至 AI 容器平台。于是小组从 2020 年初开始,基于在线业务的需求对 AI 容器平台进行进一步建设,并将平台与公司的 CMDB、CICD 等基础模块进行打通,使在线业务能够顺利从虚拟机、物理机迁移至 AI 容器平台。
深度学习与Python
2020/12/18
7660
大规模微服务利器:eBPF + Kubernetes 介绍
问卷链接(https://www.wjx.cn/jq/97146486.aspx) ---- 本文翻译自 2020 年 Daniel Borkmann 在 KubeCon 的一篇分享: eBPF and Kubernetes: Little Helper Minions for Scaling Microservices(https://kccnceu20.sched.com/event/ZemQ/ebpf-and-kubernetes-little-helper-minions-for-scaling-m
CNCF
2021/01/26
2.2K0
性能提升40%: 腾讯 TKE 用 eBPF绕过 conntrack 优化K8s Service
作者范建明、洪志国、张浩,均为腾讯云容器产品中心高级工程师,负责容器网络和Service Mesh,容器Runtime,调度等相关研发工作。 Kubernetes Service[1] 用于实现集群中业务之间的互相调用和负载均衡,目前社区的实现主要有userspace,iptables和IPVS三种模式。IPVS模式的性能最好,但依然有优化的空间。该模式利用IPVS内核模块实现DNAT,利用nf_conntrack/iptables实现SNAT。nf_conntrack是为通用目的设计的,其内部的状态和流程
腾讯云原生
2022/04/14
2.2K0
性能提升40%: 腾讯 TKE 用 eBPF绕过 conntrack 优化K8s Service
深入浅出Kubernetes架构!!建议收藏
Kubernetes 已经成为容器编排领域的王者,它是基于容器的集群编排引擎,具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。
架构师修行之路
2020/07/17
1.2K0
[译] 利用 eBPF 支撑大规模 K8s Service
K8S 当前重度依赖 iptables 来实现 Service 的抽象,对于每个 Service 及其 backend pods,在 K8s 里会生成很多 iptables 规则。例如 5K 个 Service 时,iptables 规则将达到 25K 条,导致的后果:
CNCF
2021/01/27
9770
[译] 利用 eBPF 支撑大规模 K8s Service
快速了解 Kubernetes 的架构及特性
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/08/29
4070
快速了解 Kubernetes 的架构及特性
kubernetes service 原理解析
在 kubernetes 中,当创建带有多个副本的 deployment 时,kubernetes 会创建出多个 pod,此时即一个服务后端有多个容器,那么在 kubernetes 中负载均衡怎么做,容器漂移后 ip 也会发生变化,如何做服务发现以及会话保持?这就是 service 的作用,service 是一组具有相同 label pod 集合的抽象,集群内外的各个服务可以通过 service 进行互相通信,当创建一个 service 对象时也会对应创建一个 endpoint 对象,endpoint 是用来做容器发现的,service 只是将多个 pod 进行关联,实际的路由转发都是由 kubernetes 中的 kube-proxy 组件来实现,因此,service 必须结合 kube-proxy 使用,kube-proxy 组件可以运行在 kubernetes 集群中的每一个节点上也可以只运行在单独的几个节点上,其会根据 service 和 endpoints 的变动来改变节点上 iptables 或者 ipvs 中保存的路由规则。
田飞雨
2019/12/15
1.6K0
kubernetes service 原理解析
kubernetes service 原理解析
在 kubernetes 中,当创建带有多个副本的 deployment 时,kubernetes 会创建出多个 pod,此时即一个服务后端有多个容器,那么在 kubernetes 中负载均衡怎么做,容器漂移后 ip 也会发生变化,如何做服务发现以及会话保持?这就是 service 的作用,service 是一组具有相同 label pod 集合的抽象,集群内外的各个服务可以通过 service 进行互相通信,当创建一个 service 对象时也会对应创建一个 endpoint 对象,endpoint 是用来做容器发现的,service 只是将多个 pod 进行关联,实际的路由转发都是由 kubernetes 中的 kube-proxy 组件来实现,因此,service 必须结合 kube-proxy 使用,kube-proxy 组件可以运行在 kubernetes 集群中的每一个节点上也可以只运行在单独的几个节点上,其会根据 service 和 endpoints 的变动来改变节点上 iptables 或者 ipvs 中保存的路由规则。
田飞雨
2019/12/19
5640
Kubernetes系列之Service
通过小堂的上篇文章,我们已经能够通过Deployment来创建一组Pod来提供高可用性服务。虽然每 个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:
编程识堂
2023/05/24
4370
Kubernetes系列之Service
Kubernetes vs Openshift, 谁的网络更安全?
前言 本文仅代表作者魏新宇的个人观点;在书写过程中,笔者与同事郭跃军进行了技术讨论,大有裨益,在此表示感谢! 一、K8S vs OCP, 网络端口访问方式 我在上一篇文章《深度理解:Openshif
魏新宇
2018/04/18
2.8K0
Kubernetes vs Openshift, 谁的网络更安全?
Kubernetes | Service - Ingress
Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略——通常称为微服务。这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector。
Zkeq
2023/05/11
6360
Kubernetes | Service - Ingress
Kubernetes IPVS 工作模式原理剖析
在 iptables 工作模式下,iptables 中 KUBE-SEP-XXX 链上规则和 Pod 数量成正比,当集群规模增大(10000 个 Pod 以上)时每个 k8s 节点上 iptables 规则会快速上升,从而影响集群 Service 的连接速度以及 CPU 资源消耗。
用户1107783
2023/12/12
2.3K0
Kubernetes IPVS 工作模式原理剖析
kubernetes 组件之 kube-proxy
我们知道容器的特点是快速创建、快速销毁,Kubernetes Pod和容器一样只具有临时的生命周期,一个Pod随时有可能被终止或者漂移,随着集群的状态变化而变化,一旦Pod变化,则该Pod提供的服务也就无法访问,如果直接访问Pod则无法实现服务的连续性和高可用性,因此显然不能使用Pod地址作为服务暴露端口。
看、未来
2022/06/05
6390
kubernetes 组件之 kube-proxy
《Kubernetes》,你需要掌握的 Service 和 Ingress
k8s 我们已经从 NameSpace、Pod、PodController到Volumn都介绍过了,相信看完的小伙伴们也会很有收获的~那么今天我们继续来到k8s的课堂,这节我们将要来说下 k8S 搭建完服务后如何访问!
潜行前行
2021/06/25
1.3K0
《Kubernetes》,你需要掌握的 Service 和 Ingress
kubernetes | service & ingress
基于centos7.9,docker-ce-20.10.18,kubelet-1.22.3-0
Amadeus
2022/10/25
5510
kubernetes | service & ingress
相关推荐
深入kube-proxy ipvs模式的conn_reuse_mode问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档