更新时间:2024-12-04 GMT+08:00

CCE集群IPVS转发模式下conn_reuse_mode问题说明

问题说明

对于节点内核版本小于5.9的场景,CCE集群在IPVS模式下,通过Service方式访问集群内部服务,偶现1秒延时或者后端业务升级后访问Service失败的情况,引起该问题的主要原因为社区IPVS连接复用Bug。

IPVS连接复用参数说明

IPVS对端口的复用策略主要由内核参数net.ipv4.vs.conn_reuse_mode决定。

  1. 当net.ipv4.vs.conn_reuse_mode=0时,IPVS不会对新连接进行重新负载,而是复用之前的负载结果,将新连接转发到原来的RS(IPVS的后端)上。
  2. 当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

  • 内核版本大于4.1:将net.ipv4.vs.conn_reuse_mode设置为0。
  • 其他情况:保持系统原有的默认值(即net.ipv4.vs.conn_reuse_mode=1)。
说明:

由于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作为服务转发模式的情况下,由于节点内核版本不同,不同操作系统情况如下:
  • 当节点的OS版本为EulerOS 2.5时,内核版本低于4.1,因此kube-proxy会保持系统原有的默认值net.ipv4.vs.conn_reuse_mode=1,将存在•问题2,即高并发场景存在1秒延时。
  • 当节点的OS版本为EulerOS 2.9时,低版本内核情况下kube-proxy设置net.ipv4.vs.conn_reuse_mode=0会引发•问题1,将内核版本升级至指定版本即可修复该问题,参见修复计划
  • 当节点的OS版本为Huawei Cloud EulerOS 2.0、Ubuntu 22.04时,内核版本大于5.9,操作系统已修复该问题。

建议

请您对该问题的影响进行评估,如果上述问题会对您的业务产生影响建议您采取以下措施:

  1. 使用不涉及该问题的操作系统,如Huawei Cloud EulerOS 2.0、Ubuntu 22.04。对于EulerOS 2.9的节点,新建节点不涉及该问题,存量低版内核的节点需要升级至已修复版本,详情请参见修复计划
  2. 使用服务转发模式为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