CCE集群IPVS转发模式下conn_reuse_mode问题说明
问题说明
对于节点内核版本小于5.9的场景,CCE集群在IPVS模式下,通过Service方式访问集群内部服务,偶现1秒延时或者后端业务升级后访问Service失败的情况,引起该问题的主要原因为社区IPVS连接复用Bug。
IPVS连接复用参数说明
IPVS对端口的复用策略主要由内核参数net.ipv4.vs.conn_reuse_mode决定。
- 当net.ipv4.vs.conn_reuse_mode=0时,IPVS不会对新连接进行重新负载,而是复用之前的负载结果,将新连接转发到原来的RS(IPVS的后端)上。
- 当net.ipv4.vs.conn_reuse_mode=1时,IPVS则会对新连接进行重新负载。
IPVS连接复用参数带来的问题
- 问题1
当net.ipv4.vs.conn_reuse_mode=0时,对于端口复用的连接,IPVS不会主动进行新的调度,也并不会触发结束连接或DROP操作,新连接的数据包会被直接转发到之前使用的后端pod。如果此时后端pod已经被删除或重建就会出现异常,根据当前的实现逻辑,高并发访问Service场景下,不断有端口复用的连接请求发来,旧的转发连接不会被kube-proxy删除,导致访问Service失败。
- 问题2
当net.ipv4.vs.conn_reuse_mode=1时,高并发场景下发生源端口与之前链接重复的情况,不会复用链接,而是会重新进行调度。根据ip_vs_in()的处理逻辑,当开启了net.ipv4.vs.conntrack时,这种情况会先DROP掉第一个SYN包,导致SYN的重传,有1秒延迟。导致性能下降。
社区当前行为及在CCE集群中影响
节点上net.ipv4.vs.conn_reuse_mode的初始默认值为1,但社区kube-proxy会对该参数进行重新设置:
集群版本 |
kube-proxy行为 |
对CCE集群的影响 |
---|---|---|
1.17及以下 |
kube-proxy默认将net.ipv4.vs.conn_reuse_mode设置为0,详情请参见fix IPVS low throughput issue。 |
如果CCE 1.17及以下版本的集群使用IPVS作为服务转发模式,所有节点net.ipv4.vs.conn_reuse_mode参数都会被kube-proxy默认设置为0,因此将存在•问题1,即端口复用下的RS无法移除问题。 |
1.19及以上 |
kube-proxy会根据内核的版本进行选择,详情请参见ipvs: only attempt setting of sysctlconnreuse on supported kernels。
说明:
由于Linux 5.9内核已修复该问题,从Kubernetes 1.22版本开始,对于5.9及以上的内核,kube-proxy不再修改net.ipv4.vs.conn_reuse_mode参数,详情请参见Don't set sysctl net.ipv4.vs.conn_reuse_mode for kernels >=5.9。 |
在CCE 1.19.16-r0及以上版本集群中,使用IPVS作为服务转发模式的情况下,由于节点内核版本不同,不同操作系统情况如下:
|
建议
请您对该问题的影响进行评估,如果上述问题会对您的业务产生影响建议您采取以下措施:
- 使用不涉及该问题的操作系统,如Huawei Cloud EulerOS 2.0、Ubuntu 22.04。对于EulerOS 2.9的节点,新建节点不涉及该问题,存量低版内核的节点需要升级至已修复版本,详情请参见修复计划。
- 使用服务转发模式为iptables的集群。
修复计划
如果您使用EulerOS 2.9的节点,请确认节点内核核版本是否满足以下要求。如节点内核版本过低,可以选择重置节点或者重新创建节点解决该问题。
- x86:4.18.0-147.5.1.6.h686.eulerosv2r9.x86_64
- ARM: 4.19.90-vhulk2103.1.0.h584.eulerosv2r9.aarch64
K8s社区issue:https://github.com/kubernetes/kubernetes/issues/81775