您现在的位置是:首页 >技术交流 >解开 Kubernetes 中 Pod 健康检查失败之谜网站首页技术交流

解开 Kubernetes 中 Pod 健康检查失败之谜

沃趣数据库管理平台 2024-06-14 17:18:27
简介解开 Kubernetes 中 Pod 健康检查失败之谜

Pipedrive Infra 在不同的云中(主要是 AWS 和本地 OpenStack)运营自管理的 Kubernetes 集群。

截至撰写本文时,我们管理着 20 多个不同的集群,规模大小不一,有些非常具体,有些则较小。

Pod 健康检查失败的历史

我们很久以前就注意到,有时 Pod 健康检查会无缘无故地失败,然后几乎立即恢复。但是,由于这种情况很少发生且不会影响任何事情,所以没有人认为这是一个问题。

但是,随后它变得更加频繁,这意味着开发人员开始更频繁地收到有关其部署健康状况的警报。当这种情况发生时,通常会首先询问基础设施团队,但没有任何报告:一切看起来都很健康。

我们决定找出这个问题的根本原因。起初,这种情况非常罕见,很难捕捉到事件。


步骤1:日志

  • Kubernetes 工作节点的 syslog — 没有任何信息。

  • Kubelet 日志 — 没有任何信息。

  • Containerd 日志 — 没有任何信息。

  • CNI 日志 — 没有任何信息。

  • 最近失败检查的 Pod 中的日志 — 没有任何信息:它们似乎很正常。

  • 失败的 Pod “朋友”的日志 — 没有任何信息:它们似乎没有检测到任何友好服务的停机时间。

但是健康检查仍然失败,而且发生得更加频繁,出现在更多的地方!

需要注意的是:

  • 它与云没有关系:我们在 AWS ec2 和本地虚拟机中都经历了相同的失败节奏。

  • 与 CNI 无关:不同的云使用不同的 CNI。我们在本地使用 calico,在 AWS 中使用 AWS CNI。

  • 与 Containerd 或 Kubernetes 版本无关:它在任何地方都失败了。

  • 不依赖于集群负载:它发生在测试环境中,在高峰期和夜间。

由于看起来是一个“网络问题”,所以这个问题被分配给了网络团队,他们想要查看实际的流量,并使用 tcpdump 进行了调查。


步骤2:tcpdump

在流量捕获中,我们注意到当 Kubelet 向 Pod 发送 TCP SYN 时,Pod 会回复 TCP SYN-ACK,但是 Kubelet 没有跟随 TCP ACK。经过一些重试后,Kubelet 建立了一个没有问题的 TCP 会话 — 这是一个完全随机的故障。

为了确保,我们检查了失败的 TCP 流中的 seq 和 ack 数字,一切都非常正常。

我们开始怀疑工作节点上的源进程:如果 Kubelet 发生了什么事情,它不想继续怎么办?


步骤3:ss

我们每秒钟检查一次“ss -natp”的输出。这应该显示一些东西 — 至少每个进程的连接数。

我们很快发现,失败的连接被卡在 SYN-SENT 中。这与我们在 tcpdump 中看到的不符,应该是 SYN-RECV。


步骤4:conntrack

在 Conntrack 中,损坏的连接被卡在 SYN-RECV 中,这至少是可以预期的。

在通过防火墙后将返回流量返回给 Kubelet 时可能会发生什么?什么可以防止 TCP SYN-ACK 到达 Kubelet 打开的套接字?

此时,我们已经没有更多的想法了,但我们注意到卡在 SYN-SENT 或 SYN-RECV 中的连接并不完全是随机的,因为所有源端口似乎都相似。

我们允许使用广泛的端口作为源:

net.ipv4.ip_local_port_range=12000 65001

有问题的端口看起来像是 30XXX 或 31XXX,这个范围看起来非常熟悉。


步骤5:ipvs

我们使用 ipvsadm 检查了我们的 ipvs 配置,并发现所有卡在连接中的端口都被 Kubernetes nodeport 保留了。

发现根本原因是这样的:Kubelet使用一个随机源端口(例如31055)向pod发起TCP会话。TCP SYN到达pod,pod回复TCP SYN-ACK到端口31055。回复命中IPVS,我们在Kubernetes服务上使用nodeport 31055的负载均衡器。TCP SYN-ACK被重定向到服务端点(其他pod)。结果是可预测的:没有人回答。

解决健康检查失败的方法是禁止使用nodeport范围作为TCP会话的源端口。

幸运的是,只需要一行代码:

net.ipv4.ip_local_reserved_ports=”30000–32768"

在所有节点上实施后,问题立即得到解决。具有讽刺意味的是,几个小时的故障排除只产生了一行代码。

作者:Roman Kuchin

更多技术干货请关注公号“云原生数据库

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。